From: Mauro Carvalho Chehab Date: Sun, 10 May 2020 14:06:53 +0000 (+0200) Subject: media: atomisp: reduce the risk of a race condition X-Git-Tag: Ubuntu-5.13.0-19.19~5895^2~39 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=09d87466655d00526cf818b3f3b267884c591702;p=mirror_ubuntu-jammy-kernel.git media: atomisp: reduce the risk of a race condition This driver is really on bad shape. One of the problems is that, as soon as the I2C transfers start to happen, it timeouts detecting a camera: ov2680 i2c-OVTI2680:00: ov2680_probe: ACPI detected it on bus ID=CAM1, HID=OVTI2680 atomisp-isp2 0000:00:03.0: no camera attached or fail to detect ov2680 i2c-OVTI2680:00: gmin: initializing atomisp module subdev data using PMIC regulator ... The right fix here would be to use defer probe, but driver is still on too bad shape. Signed-off-by: Mauro Carvalho Chehab --- diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c index ae1585d99e74..c4bf2ac706d9 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@ -46,6 +46,10 @@ #include "device_access.h" +/* Timeouts to wait for all subdevs to be registered */ +#define SUBDEV_WAIT_TIMEOUT 50 /* ms */ +#define SUBDEV_WAIT_TIMEOUT_MAX_COUNT 40 /* up to 2 seconds */ + /* G-Min addition: pull this in from intel_mid_pm.h */ #define CSTATE_EXIT_LATENCY_C1 1 @@ -1082,7 +1086,7 @@ static int atomisp_subdev_probe(struct atomisp_device *isp) { const struct atomisp_platform_data *pdata; struct intel_v4l2_subdev_table *subdevs; - int ret, raw_index = -1; + int ret, raw_index = -1, count; pdata = atomisp_get_platform_data(); if (!pdata) { @@ -1090,6 +1094,8 @@ static int atomisp_subdev_probe(struct atomisp_device *isp) return 0; } + /* FIXME: should, instead, use I2C probe */ + for (subdevs = pdata->subdevs; subdevs->type; ++subdevs) { struct v4l2_subdev *subdev; struct i2c_board_info *board_info = @@ -1098,6 +1104,8 @@ static int atomisp_subdev_probe(struct atomisp_device *isp) i2c_get_adapter(subdevs->v4l2_subdev.i2c_adapter_id); int sensor_num, i; + dev_info(isp->dev, "Probing Subdev %s\n", board_info->type); + if (!adapter) { dev_err(isp->dev, "Failed to find i2c adapter for subdev %s\n", @@ -1177,6 +1185,16 @@ static int atomisp_subdev_probe(struct atomisp_device *isp) } } + /* FIXME: should return -EPROBE_DEFER if not all subdevs were probed */ + for (count = 0; count < SUBDEV_WAIT_TIMEOUT_MAX_COUNT; count++) { + if (isp->input_cnt) + break; + msleep(SUBDEV_WAIT_TIMEOUT); + count++; + } + /* Wait more time to give more time for subdev init code */ + msleep(5 * SUBDEV_WAIT_TIMEOUT); + /* * HACK: Currently VCM belongs to primary sensor only, but correct * approach must be to acquire from platform code which sensor @@ -1186,8 +1204,11 @@ static int atomisp_subdev_probe(struct atomisp_device *isp) isp->inputs[raw_index].motor = isp->motor; /* Proceed even if no modules detected. For COS mode and no modules. */ - if (!isp->inputs[0].camera) + if (!isp->input_cnt) dev_warn(isp->dev, "no camera attached or fail to detect\n"); + else + dev_info(isp->dev, "detected %d camera sensors\n", + isp->input_cnt); return atomisp_csi_lane_config(isp); }