Re: FAILED: patch "[PATCH] media: smiapp: Avoid maintaining power state information" failed to apply to 5.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Greg,

On Thu, Jul 15, 2021 at 04:16:52PM +0200, gregkh@xxxxxxxxxxxxxxxxxxx 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@xxxxxxxxxxxxxxx>.
> 
> 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@xxxxxxxxxxxxxxx>
> 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@xxxxxxxxxxxxxxx>
> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@xxxxxxxxxx>
> 
> 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



[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux