]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
media: atomisp: reduce the risk of a race condition
authorMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Sun, 10 May 2020 14:06:53 +0000 (16:06 +0200)
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Wed, 20 May 2020 12:51:28 +0000 (14:51 +0200)
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 <mchehab+huawei@kernel.org>
drivers/staging/media/atomisp/pci/atomisp_v4l2.c

index ae1585d99e74e7f02c2ec1c3027b5212693f9e4b..c4bf2ac706d96896bbe559511c6bbed4e6488c8c 100644 (file)
 
 #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);
 }