All of lore.kernel.org
 help / color / mirror / Atom feed
* FAILED: patch "[PATCH] media: smiapp: Avoid maintaining power state information" failed to apply to 5.10-stable tree
@ 2021-07-15 14:16 gregkh
  2021-07-19 11:28 ` Sakari Ailus
  0 siblings, 1 reply; 2+ messages in thread
From: gregkh @ 2021-07-15 14:16 UTC (permalink / raw)
  To: sakari.ailus, mchehab+huawei; +Cc: stable


The patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From 96e3a6b92f23a97ca9bf3359ada1b5c773b32b7e Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@linux.intel.com>
Date: Mon, 30 Sep 2019 10:18:45 +0200
Subject: [PATCH] media: smiapp: Avoid maintaining power state information

Instead of keeping track of the power state ourselves, let runtime PM
handle it.

This also splits handling controls between side effect management and
writing the new configuration to the sensor's registers.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>

diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index 84f9771b5fed..0dca8db21f65 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -413,21 +413,14 @@ static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl)
 	struct smiapp_sensor *sensor =
 		container_of(ctrl->handler, struct smiapp_subdev, ctrl_handler)
 			->sensor;
+	struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
+	int pm_status;
 	u32 orient = 0;
+	unsigned int i;
 	int exposure;
 	int rval;
 
 	switch (ctrl->id) {
-	case V4L2_CID_ANALOGUE_GAIN:
-		return smiapp_write(
-			sensor,
-			SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GLOBAL, ctrl->val);
-
-	case V4L2_CID_EXPOSURE:
-		return smiapp_write(
-			sensor,
-			SMIAPP_REG_U16_COARSE_INTEGRATION_TIME, ctrl->val);
-
 	case V4L2_CID_HFLIP:
 	case V4L2_CID_VFLIP:
 		if (sensor->streaming)
@@ -440,15 +433,10 @@ static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl)
 			orient |= SMIAPP_IMAGE_ORIENTATION_VFLIP;
 
 		orient ^= sensor->hvflip_inv_mask;
-		rval = smiapp_write(sensor, SMIAPP_REG_U8_IMAGE_ORIENTATION,
-				    orient);
-		if (rval < 0)
-			return rval;
 
 		smiapp_update_mbus_formats(sensor);
 
-		return 0;
-
+		break;
 	case V4L2_CID_VBLANK:
 		exposure = sensor->exposure->val;
 
@@ -461,59 +449,105 @@ static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl)
 				return rval;
 		}
 
-		return smiapp_write(
-			sensor, SMIAPP_REG_U16_FRAME_LENGTH_LINES,
-			sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height
-			+ ctrl->val);
-
-	case V4L2_CID_HBLANK:
-		return smiapp_write(
-			sensor, SMIAPP_REG_U16_LINE_LENGTH_PCK,
-			sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width
-			+ ctrl->val);
-
+		break;
 	case V4L2_CID_LINK_FREQ:
 		if (sensor->streaming)
 			return -EBUSY;
 
-		return smiapp_pll_update(sensor);
-
-	case V4L2_CID_TEST_PATTERN: {
-		unsigned int i;
+		rval = smiapp_pll_update(sensor);
+		if (rval)
+			return rval;
 
+		return 0;
+	case V4L2_CID_TEST_PATTERN:
 		for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++)
 			v4l2_ctrl_activate(
 				sensor->test_data[i],
 				ctrl->val ==
 				V4L2_SMIAPP_TEST_PATTERN_MODE_SOLID_COLOUR);
 
-		return smiapp_write(
-			sensor, SMIAPP_REG_U16_TEST_PATTERN_MODE, ctrl->val);
+		break;
 	}
 
+	pm_runtime_get_noresume(&client->dev);
+	pm_status = pm_runtime_get_if_in_use(&client->dev);
+	pm_runtime_put_noidle(&client->dev);
+	if (!pm_status)
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_ANALOGUE_GAIN:
+		rval = smiapp_write(
+			sensor,
+			SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GLOBAL, ctrl->val);
+
+		break;
+	case V4L2_CID_EXPOSURE:
+		rval = smiapp_write(
+			sensor,
+			SMIAPP_REG_U16_COARSE_INTEGRATION_TIME, ctrl->val);
+
+		break;
+	case V4L2_CID_HFLIP:
+	case V4L2_CID_VFLIP:
+		rval = smiapp_write(sensor, SMIAPP_REG_U8_IMAGE_ORIENTATION,
+				    orient);
+
+		break;
+	case V4L2_CID_VBLANK:
+		rval = smiapp_write(
+			sensor, SMIAPP_REG_U16_FRAME_LENGTH_LINES,
+			sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height
+			+ ctrl->val);
+
+		break;
+	case V4L2_CID_HBLANK:
+		rval = smiapp_write(
+			sensor, SMIAPP_REG_U16_LINE_LENGTH_PCK,
+			sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width
+			+ ctrl->val);
+
+		break;
+	case V4L2_CID_TEST_PATTERN:
+		rval = smiapp_write(
+			sensor, SMIAPP_REG_U16_TEST_PATTERN_MODE, ctrl->val);
+
+		break;
 	case V4L2_CID_TEST_PATTERN_RED:
-		return smiapp_write(
+		rval = smiapp_write(
 			sensor, SMIAPP_REG_U16_TEST_DATA_RED, ctrl->val);
 
+		break;
 	case V4L2_CID_TEST_PATTERN_GREENR:
-		return smiapp_write(
+		rval = smiapp_write(
 			sensor, SMIAPP_REG_U16_TEST_DATA_GREENR, ctrl->val);
 
+		break;
 	case V4L2_CID_TEST_PATTERN_BLUE:
-		return smiapp_write(
+		rval = smiapp_write(
 			sensor, SMIAPP_REG_U16_TEST_DATA_BLUE, ctrl->val);
 
+		break;
 	case V4L2_CID_TEST_PATTERN_GREENB:
-		return smiapp_write(
+		rval = smiapp_write(
 			sensor, SMIAPP_REG_U16_TEST_DATA_GREENB, ctrl->val);
 
+		break;
 	case V4L2_CID_PIXEL_RATE:
 		/* For v4l2_ctrl_s_ctrl_int64() used internally. */
-		return 0;
+		rval = 0;
 
+		break;
 	default:
-		return -EINVAL;
+		rval = -EINVAL;
 	}
+
+	if (pm_status > 0) {
+		pm_runtime_mark_last_busy(&client->dev);
+		pm_runtime_put_autosuspend(&client->dev);
+	}
+
+	return rval;
 }
 
 static const struct v4l2_ctrl_ops smiapp_ctrl_ops = {
@@ -1184,10 +1218,6 @@ static int smiapp_power_on(struct device *dev)
 	sleep = SMIAPP_RESET_DELAY(sensor->hwcfg->ext_clk);
 	usleep_range(sleep, sleep);
 
-	mutex_lock(&sensor->mutex);
-
-	sensor->active = true;
-
 	/*
 	 * Failures to respond to the address change command have been noticed.
 	 * Those failures seem to be caused by the sensor requiring a longer
@@ -1270,24 +1300,9 @@ static int smiapp_power_on(struct device *dev)
 		goto out_cci_addr_fail;
 	}
 
-	/* Are we still initialising...? If not, proceed with control setup. */
-	if (sensor->pixel_array) {
-		rval = __v4l2_ctrl_handler_setup(
-			&sensor->pixel_array->ctrl_handler);
-		if (rval)
-			goto out_cci_addr_fail;
-
-		rval = __v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler);
-		if (rval)
-			goto out_cci_addr_fail;
-	}
-
-	mutex_unlock(&sensor->mutex);
-
 	return 0;
 
 out_cci_addr_fail:
-	mutex_unlock(&sensor->mutex);
 	gpiod_set_value(sensor->xshutdown, 0);
 	clk_disable_unprepare(sensor->ext_clk);
 
@@ -1305,8 +1320,6 @@ static int smiapp_power_off(struct device *dev)
 	struct smiapp_sensor *sensor =
 		container_of(ssd, struct smiapp_sensor, ssds[0]);
 
-	mutex_lock(&sensor->mutex);
-
 	/*
 	 * Currently power/clock to lens are enable/disabled separately
 	 * but they are essentially the same signals. So if the sensor is
@@ -1319,10 +1332,6 @@ static int smiapp_power_off(struct device *dev)
 			     SMIAPP_REG_U8_SOFTWARE_RESET,
 			     SMIAPP_SOFTWARE_RESET);
 
-	sensor->active = false;
-
-	mutex_unlock(&sensor->mutex);
-
 	gpiod_set_value(sensor->xshutdown, 0);
 	clk_disable_unprepare(sensor->ext_clk);
 	usleep_range(5000, 5000);
@@ -1507,6 +1516,30 @@ static int smiapp_stop_streaming(struct smiapp_sensor *sensor)
  * V4L2 subdev video operations
  */
 
+static int smiapp_pm_get_init(struct smiapp_sensor *sensor)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
+	int rval;
+
+	rval = pm_runtime_get_sync(&client->dev);
+	if (rval < 0) {
+		if (rval != -EBUSY && rval != -EAGAIN)
+			pm_runtime_set_active(&client->dev);
+		pm_runtime_put_noidle(&client->dev);
+
+		return rval;
+	} else if (!rval) {
+		rval = v4l2_ctrl_handler_setup(&sensor->pixel_array->
+					       ctrl_handler);
+		if (rval)
+			return rval;
+
+		return v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler);
+	}
+
+	return 0;
+}
+
 static int smiapp_set_stream(struct v4l2_subdev *subdev, int enable)
 {
 	struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
@@ -1516,27 +1549,25 @@ static int smiapp_set_stream(struct v4l2_subdev *subdev, int enable)
 	if (sensor->streaming == enable)
 		return 0;
 
-	if (enable) {
-		rval = pm_runtime_get_sync(&client->dev);
-		if (rval < 0) {
-			if (rval != -EBUSY && rval != -EAGAIN)
-				pm_runtime_set_active(&client->dev);
-			pm_runtime_put(&client->dev);
-			return rval;
-		}
-
-		sensor->streaming = true;
-
-		rval = smiapp_start_streaming(sensor);
-		if (rval < 0)
-			sensor->streaming = false;
-	} else {
-		rval = smiapp_stop_streaming(sensor);
+	if (!enable) {
+		smiapp_stop_streaming(sensor);
 		sensor->streaming = false;
 		pm_runtime_mark_last_busy(&client->dev);
 		pm_runtime_put_autosuspend(&client->dev);
+
+		return 0;
 	}
 
+	rval = smiapp_pm_get_init(sensor);
+	if (rval)
+		return rval;
+
+	sensor->streaming = true;
+
+	rval = smiapp_start_streaming(sensor);
+	if (rval < 0)
+		sensor->streaming = false;
+
 	return rval;
 }
 
@@ -2291,13 +2322,9 @@ smiapp_sysfs_nvm_read(struct device *dev, struct device_attribute *attr,
 	if (!sensor->dev_init_done)
 		return -EBUSY;
 
-	rval = pm_runtime_get_sync(&client->dev);
-	if (rval < 0) {
-		if (rval != -EBUSY && rval != -EAGAIN)
-			pm_runtime_set_active(&client->dev);
-		pm_runtime_put_noidle(&client->dev);
+	rval = smiapp_pm_get_init(sensor);
+	if (rval < 0)
 		return -ENODEV;
-	}
 
 	rval = smiapp_read_nvm(sensor, buf, PAGE_SIZE);
 	if (rval < 0) {
diff --git a/drivers/media/i2c/smiapp/smiapp-regs.c b/drivers/media/i2c/smiapp/smiapp-regs.c
index 0470e47c2f7a..ce8c1d47fbf0 100644
--- a/drivers/media/i2c/smiapp/smiapp-regs.c
+++ b/drivers/media/i2c/smiapp/smiapp-regs.c
@@ -223,9 +223,6 @@ int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val)
 	     len != SMIAPP_REG_32BIT) || flags)
 		return -EINVAL;
 
-	if (!sensor->active)
-		return 0;
-
 	msg.addr = client->addr;
 	msg.flags = 0; /* Write */
 	msg.len = 2 + len;
diff --git a/drivers/media/i2c/smiapp/smiapp.h b/drivers/media/i2c/smiapp/smiapp.h
index 3ab874a5deba..4837d80dc453 100644
--- a/drivers/media/i2c/smiapp/smiapp.h
+++ b/drivers/media/i2c/smiapp/smiapp.h
@@ -198,7 +198,6 @@ struct smiapp_sensor {
 
 	u8 hvflip_inv_mask; /* H/VFLIP inversion due to sensor orientation */
 	u8 frame_skip;
-	bool active; /* is the sensor powered on? */
 	u16 embedded_start; /* embedded data start line */
 	u16 embedded_end;
 	u16 image_start; /* image data start line */


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: FAILED: patch "[PATCH] media: smiapp: Avoid maintaining power state information" failed to apply to 5.10-stable tree
  2021-07-15 14:16 FAILED: patch "[PATCH] media: smiapp: Avoid maintaining power state information" failed to apply to 5.10-stable tree gregkh
@ 2021-07-19 11:28 ` Sakari Ailus
  0 siblings, 0 replies; 2+ messages in thread
From: Sakari Ailus @ 2021-07-19 11:28 UTC (permalink / raw)
  To: gregkh; +Cc: mchehab+huawei, stable

Hi Greg,

On Thu, Jul 15, 2021 at 04:16:52PM +0200, gregkh@linuxfoundation.org wrote:
> 
> The patch below does not apply to the 5.10-stable tree.
> If someone wants it applied there, or to any other stable or longterm
> tree, then please email the backport, including the original git commit
> id to <stable@vger.kernel.org>.
> 
> thanks,
> 
> greg k-h

The patch was already merged in v5.6 so it can be safely dropped from the
5.10-stable tree.

> 
> ------------------ original commit in Linus's tree ------------------
> 
> From 96e3a6b92f23a97ca9bf3359ada1b5c773b32b7e Mon Sep 17 00:00:00 2001
> From: Sakari Ailus <sakari.ailus@linux.intel.com>
> Date: Mon, 30 Sep 2019 10:18:45 +0200
> Subject: [PATCH] media: smiapp: Avoid maintaining power state information
> 
> Instead of keeping track of the power state ourselves, let runtime PM
> handle it.
> 
> This also splits handling controls between side effect management and
> writing the new configuration to the sensor's registers.
> 
> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
> 
> diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
> index 84f9771b5fed..0dca8db21f65 100644
> --- a/drivers/media/i2c/smiapp/smiapp-core.c
> +++ b/drivers/media/i2c/smiapp/smiapp-core.c
> @@ -413,21 +413,14 @@ static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl)
>  	struct smiapp_sensor *sensor =
>  		container_of(ctrl->handler, struct smiapp_subdev, ctrl_handler)
>  			->sensor;
> +	struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
> +	int pm_status;
>  	u32 orient = 0;
> +	unsigned int i;
>  	int exposure;
>  	int rval;
>  
>  	switch (ctrl->id) {
> -	case V4L2_CID_ANALOGUE_GAIN:
> -		return smiapp_write(
> -			sensor,
> -			SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GLOBAL, ctrl->val);
> -
> -	case V4L2_CID_EXPOSURE:
> -		return smiapp_write(
> -			sensor,
> -			SMIAPP_REG_U16_COARSE_INTEGRATION_TIME, ctrl->val);
> -
>  	case V4L2_CID_HFLIP:
>  	case V4L2_CID_VFLIP:
>  		if (sensor->streaming)
> @@ -440,15 +433,10 @@ static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl)
>  			orient |= SMIAPP_IMAGE_ORIENTATION_VFLIP;
>  
>  		orient ^= sensor->hvflip_inv_mask;
> -		rval = smiapp_write(sensor, SMIAPP_REG_U8_IMAGE_ORIENTATION,
> -				    orient);
> -		if (rval < 0)
> -			return rval;
>  
>  		smiapp_update_mbus_formats(sensor);
>  
> -		return 0;
> -
> +		break;
>  	case V4L2_CID_VBLANK:
>  		exposure = sensor->exposure->val;
>  
> @@ -461,59 +449,105 @@ static int smiapp_set_ctrl(struct v4l2_ctrl *ctrl)
>  				return rval;
>  		}
>  
> -		return smiapp_write(
> -			sensor, SMIAPP_REG_U16_FRAME_LENGTH_LINES,
> -			sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height
> -			+ ctrl->val);
> -
> -	case V4L2_CID_HBLANK:
> -		return smiapp_write(
> -			sensor, SMIAPP_REG_U16_LINE_LENGTH_PCK,
> -			sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width
> -			+ ctrl->val);
> -
> +		break;
>  	case V4L2_CID_LINK_FREQ:
>  		if (sensor->streaming)
>  			return -EBUSY;
>  
> -		return smiapp_pll_update(sensor);
> -
> -	case V4L2_CID_TEST_PATTERN: {
> -		unsigned int i;
> +		rval = smiapp_pll_update(sensor);
> +		if (rval)
> +			return rval;
>  
> +		return 0;
> +	case V4L2_CID_TEST_PATTERN:
>  		for (i = 0; i < ARRAY_SIZE(sensor->test_data); i++)
>  			v4l2_ctrl_activate(
>  				sensor->test_data[i],
>  				ctrl->val ==
>  				V4L2_SMIAPP_TEST_PATTERN_MODE_SOLID_COLOUR);
>  
> -		return smiapp_write(
> -			sensor, SMIAPP_REG_U16_TEST_PATTERN_MODE, ctrl->val);
> +		break;
>  	}
>  
> +	pm_runtime_get_noresume(&client->dev);
> +	pm_status = pm_runtime_get_if_in_use(&client->dev);
> +	pm_runtime_put_noidle(&client->dev);
> +	if (!pm_status)
> +		return 0;
> +
> +	switch (ctrl->id) {
> +	case V4L2_CID_ANALOGUE_GAIN:
> +		rval = smiapp_write(
> +			sensor,
> +			SMIAPP_REG_U16_ANALOGUE_GAIN_CODE_GLOBAL, ctrl->val);
> +
> +		break;
> +	case V4L2_CID_EXPOSURE:
> +		rval = smiapp_write(
> +			sensor,
> +			SMIAPP_REG_U16_COARSE_INTEGRATION_TIME, ctrl->val);
> +
> +		break;
> +	case V4L2_CID_HFLIP:
> +	case V4L2_CID_VFLIP:
> +		rval = smiapp_write(sensor, SMIAPP_REG_U8_IMAGE_ORIENTATION,
> +				    orient);
> +
> +		break;
> +	case V4L2_CID_VBLANK:
> +		rval = smiapp_write(
> +			sensor, SMIAPP_REG_U16_FRAME_LENGTH_LINES,
> +			sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].height
> +			+ ctrl->val);
> +
> +		break;
> +	case V4L2_CID_HBLANK:
> +		rval = smiapp_write(
> +			sensor, SMIAPP_REG_U16_LINE_LENGTH_PCK,
> +			sensor->pixel_array->crop[SMIAPP_PA_PAD_SRC].width
> +			+ ctrl->val);
> +
> +		break;
> +	case V4L2_CID_TEST_PATTERN:
> +		rval = smiapp_write(
> +			sensor, SMIAPP_REG_U16_TEST_PATTERN_MODE, ctrl->val);
> +
> +		break;
>  	case V4L2_CID_TEST_PATTERN_RED:
> -		return smiapp_write(
> +		rval = smiapp_write(
>  			sensor, SMIAPP_REG_U16_TEST_DATA_RED, ctrl->val);
>  
> +		break;
>  	case V4L2_CID_TEST_PATTERN_GREENR:
> -		return smiapp_write(
> +		rval = smiapp_write(
>  			sensor, SMIAPP_REG_U16_TEST_DATA_GREENR, ctrl->val);
>  
> +		break;
>  	case V4L2_CID_TEST_PATTERN_BLUE:
> -		return smiapp_write(
> +		rval = smiapp_write(
>  			sensor, SMIAPP_REG_U16_TEST_DATA_BLUE, ctrl->val);
>  
> +		break;
>  	case V4L2_CID_TEST_PATTERN_GREENB:
> -		return smiapp_write(
> +		rval = smiapp_write(
>  			sensor, SMIAPP_REG_U16_TEST_DATA_GREENB, ctrl->val);
>  
> +		break;
>  	case V4L2_CID_PIXEL_RATE:
>  		/* For v4l2_ctrl_s_ctrl_int64() used internally. */
> -		return 0;
> +		rval = 0;
>  
> +		break;
>  	default:
> -		return -EINVAL;
> +		rval = -EINVAL;
>  	}
> +
> +	if (pm_status > 0) {
> +		pm_runtime_mark_last_busy(&client->dev);
> +		pm_runtime_put_autosuspend(&client->dev);
> +	}
> +
> +	return rval;
>  }
>  
>  static const struct v4l2_ctrl_ops smiapp_ctrl_ops = {
> @@ -1184,10 +1218,6 @@ static int smiapp_power_on(struct device *dev)
>  	sleep = SMIAPP_RESET_DELAY(sensor->hwcfg->ext_clk);
>  	usleep_range(sleep, sleep);
>  
> -	mutex_lock(&sensor->mutex);
> -
> -	sensor->active = true;
> -
>  	/*
>  	 * Failures to respond to the address change command have been noticed.
>  	 * Those failures seem to be caused by the sensor requiring a longer
> @@ -1270,24 +1300,9 @@ static int smiapp_power_on(struct device *dev)
>  		goto out_cci_addr_fail;
>  	}
>  
> -	/* Are we still initialising...? If not, proceed with control setup. */
> -	if (sensor->pixel_array) {
> -		rval = __v4l2_ctrl_handler_setup(
> -			&sensor->pixel_array->ctrl_handler);
> -		if (rval)
> -			goto out_cci_addr_fail;
> -
> -		rval = __v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler);
> -		if (rval)
> -			goto out_cci_addr_fail;
> -	}
> -
> -	mutex_unlock(&sensor->mutex);
> -
>  	return 0;
>  
>  out_cci_addr_fail:
> -	mutex_unlock(&sensor->mutex);
>  	gpiod_set_value(sensor->xshutdown, 0);
>  	clk_disable_unprepare(sensor->ext_clk);
>  
> @@ -1305,8 +1320,6 @@ static int smiapp_power_off(struct device *dev)
>  	struct smiapp_sensor *sensor =
>  		container_of(ssd, struct smiapp_sensor, ssds[0]);
>  
> -	mutex_lock(&sensor->mutex);
> -
>  	/*
>  	 * Currently power/clock to lens are enable/disabled separately
>  	 * but they are essentially the same signals. So if the sensor is
> @@ -1319,10 +1332,6 @@ static int smiapp_power_off(struct device *dev)
>  			     SMIAPP_REG_U8_SOFTWARE_RESET,
>  			     SMIAPP_SOFTWARE_RESET);
>  
> -	sensor->active = false;
> -
> -	mutex_unlock(&sensor->mutex);
> -
>  	gpiod_set_value(sensor->xshutdown, 0);
>  	clk_disable_unprepare(sensor->ext_clk);
>  	usleep_range(5000, 5000);
> @@ -1507,6 +1516,30 @@ static int smiapp_stop_streaming(struct smiapp_sensor *sensor)
>   * V4L2 subdev video operations
>   */
>  
> +static int smiapp_pm_get_init(struct smiapp_sensor *sensor)
> +{
> +	struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
> +	int rval;
> +
> +	rval = pm_runtime_get_sync(&client->dev);
> +	if (rval < 0) {
> +		if (rval != -EBUSY && rval != -EAGAIN)
> +			pm_runtime_set_active(&client->dev);
> +		pm_runtime_put_noidle(&client->dev);
> +
> +		return rval;
> +	} else if (!rval) {
> +		rval = v4l2_ctrl_handler_setup(&sensor->pixel_array->
> +					       ctrl_handler);
> +		if (rval)
> +			return rval;
> +
> +		return v4l2_ctrl_handler_setup(&sensor->src->ctrl_handler);
> +	}
> +
> +	return 0;
> +}
> +
>  static int smiapp_set_stream(struct v4l2_subdev *subdev, int enable)
>  {
>  	struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
> @@ -1516,27 +1549,25 @@ static int smiapp_set_stream(struct v4l2_subdev *subdev, int enable)
>  	if (sensor->streaming == enable)
>  		return 0;
>  
> -	if (enable) {
> -		rval = pm_runtime_get_sync(&client->dev);
> -		if (rval < 0) {
> -			if (rval != -EBUSY && rval != -EAGAIN)
> -				pm_runtime_set_active(&client->dev);
> -			pm_runtime_put(&client->dev);
> -			return rval;
> -		}
> -
> -		sensor->streaming = true;
> -
> -		rval = smiapp_start_streaming(sensor);
> -		if (rval < 0)
> -			sensor->streaming = false;
> -	} else {
> -		rval = smiapp_stop_streaming(sensor);
> +	if (!enable) {
> +		smiapp_stop_streaming(sensor);
>  		sensor->streaming = false;
>  		pm_runtime_mark_last_busy(&client->dev);
>  		pm_runtime_put_autosuspend(&client->dev);
> +
> +		return 0;
>  	}
>  
> +	rval = smiapp_pm_get_init(sensor);
> +	if (rval)
> +		return rval;
> +
> +	sensor->streaming = true;
> +
> +	rval = smiapp_start_streaming(sensor);
> +	if (rval < 0)
> +		sensor->streaming = false;
> +
>  	return rval;
>  }
>  
> @@ -2291,13 +2322,9 @@ smiapp_sysfs_nvm_read(struct device *dev, struct device_attribute *attr,
>  	if (!sensor->dev_init_done)
>  		return -EBUSY;
>  
> -	rval = pm_runtime_get_sync(&client->dev);
> -	if (rval < 0) {
> -		if (rval != -EBUSY && rval != -EAGAIN)
> -			pm_runtime_set_active(&client->dev);
> -		pm_runtime_put_noidle(&client->dev);
> +	rval = smiapp_pm_get_init(sensor);
> +	if (rval < 0)
>  		return -ENODEV;
> -	}
>  
>  	rval = smiapp_read_nvm(sensor, buf, PAGE_SIZE);
>  	if (rval < 0) {
> diff --git a/drivers/media/i2c/smiapp/smiapp-regs.c b/drivers/media/i2c/smiapp/smiapp-regs.c
> index 0470e47c2f7a..ce8c1d47fbf0 100644
> --- a/drivers/media/i2c/smiapp/smiapp-regs.c
> +++ b/drivers/media/i2c/smiapp/smiapp-regs.c
> @@ -223,9 +223,6 @@ int smiapp_write_no_quirk(struct smiapp_sensor *sensor, u32 reg, u32 val)
>  	     len != SMIAPP_REG_32BIT) || flags)
>  		return -EINVAL;
>  
> -	if (!sensor->active)
> -		return 0;
> -
>  	msg.addr = client->addr;
>  	msg.flags = 0; /* Write */
>  	msg.len = 2 + len;
> diff --git a/drivers/media/i2c/smiapp/smiapp.h b/drivers/media/i2c/smiapp/smiapp.h
> index 3ab874a5deba..4837d80dc453 100644
> --- a/drivers/media/i2c/smiapp/smiapp.h
> +++ b/drivers/media/i2c/smiapp/smiapp.h
> @@ -198,7 +198,6 @@ struct smiapp_sensor {
>  
>  	u8 hvflip_inv_mask; /* H/VFLIP inversion due to sensor orientation */
>  	u8 frame_skip;
> -	bool active; /* is the sensor powered on? */
>  	u16 embedded_start; /* embedded data start line */
>  	u16 embedded_end;
>  	u16 image_start; /* image data start line */
> 

-- 
Sakari Ailus

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-07-19 11:28 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-15 14:16 FAILED: patch "[PATCH] media: smiapp: Avoid maintaining power state information" failed to apply to 5.10-stable tree gregkh
2021-07-19 11:28 ` Sakari Ailus

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.