Commit 09d87466 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab
Browse files

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: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent d03f2e24
Loading
Loading
Loading
Loading
+23 −2
Original line number Diff line number Diff line
@@ -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);
}