Re: [PATCH 1/4] media: i2c: st-vgxy61: Use sub-device active state

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

 



Hi Julien,

Thank you for your patch.


First, sorry for the delay. I have a lot of stuff ongoing. I'll be more
available now.

Second, I don't currently have a setup that can handle the multi stream
serie. Therefore I'm not able to test your serie. Following your
patchset acquiring such a platform went up in my todo list.


On 3/15/24 09:51, Julien Massot wrote:
> Use sub-device active state. Rely on control handler lock to serialize
> access to the active state.
> 
> Signed-off-by: Julien Massot <julien.massot@xxxxxxxxxxxxx>

I have yet to dive deep into active states.
I find curious that the 'current_mode' field in vgxy61_dev is still
here. From my understanding it should be replaced by
'v4l2_subdev_state_get_format', and all the 'current_mode->crop'
replaced by 'v4l2_subdev_state_get_crop'.
Someone tell me if this is incorrect.

> ---
>  drivers/media/i2c/st-vgxy61.c | 109 ++++++++++++----------------------
>  1 file changed, 39 insertions(+), 70 deletions(-)
> 
> diff --git a/drivers/media/i2c/st-vgxy61.c b/drivers/media/i2c/st-vgxy61.c
> index b9e7c57027b1..733713f909cf 100644
> --- a/drivers/media/i2c/st-vgxy61.c
> +++ b/drivers/media/i2c/st-vgxy61.c
> @@ -397,8 +397,6 @@ struct vgxy61_dev {
>  	u16 line_length;
>  	u16 rot_term;
>  	bool gpios_polarity;
> -	/* Lock to protect all members below */
> -	struct mutex lock;
>  	struct v4l2_ctrl_handler ctrl_handler;
>  	struct v4l2_ctrl *pixel_rate_ctrl;
>  	struct v4l2_ctrl *expo_ctrl;
> @@ -686,27 +684,6 @@ static int vgxy61_enum_mbus_code(struct v4l2_subdev *sd,
>  	return 0;
>  }
>  
> -static int vgxy61_get_fmt(struct v4l2_subdev *sd,
> -			  struct v4l2_subdev_state *sd_state,
> -			  struct v4l2_subdev_format *format)
> -{
> -	struct vgxy61_dev *sensor = to_vgxy61_dev(sd);
> -	struct v4l2_mbus_framefmt *fmt;
> -
> -	mutex_lock(&sensor->lock);
> -
> -	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
> -		fmt = v4l2_subdev_state_get_format(sd_state, format->pad);
> -	else
> -		fmt = &sensor->fmt;
> -
> -	format->format = *fmt;
> -
> -	mutex_unlock(&sensor->lock);
> -
> -	return 0;
> -}
> -
>  static u16 vgxy61_get_vblank_min(struct vgxy61_dev *sensor,
>  				 enum vgxy61_hdr_mode hdr)
>  {
> @@ -1167,16 +1144,17 @@ static int vgxy61_stream_disable(struct vgxy61_dev *sensor)
>  static int vgxy61_s_stream(struct v4l2_subdev *sd, int enable)
>  {
>  	struct vgxy61_dev *sensor = to_vgxy61_dev(sd);
> +	struct v4l2_subdev_state *sd_state;
>  	int ret = 0;
>  
> -	mutex_lock(&sensor->lock);
> +	sd_state = v4l2_subdev_lock_and_get_active_state(&sensor->sd);
>  
>  	ret = enable ? vgxy61_stream_enable(sensor) :
>  	      vgxy61_stream_disable(sensor);
>  	if (!ret)
>  		sensor->streaming = enable;
>  
> -	mutex_unlock(&sensor->lock);
> +	v4l2_subdev_unlock_state(sd_state);
>  
>  	return ret;
>  }
> @@ -1187,51 +1165,39 @@ static int vgxy61_set_fmt(struct v4l2_subdev *sd,
>  {
>  	struct vgxy61_dev *sensor = to_vgxy61_dev(sd);
>  	const struct vgxy61_mode_info *new_mode;
> -	struct v4l2_mbus_framefmt *fmt;
>  	int ret;
>  
> -	mutex_lock(&sensor->lock);
> -
> -	if (sensor->streaming) {
> -		ret = -EBUSY;
> -		goto out;
> -	}
> +	if (sensor->streaming)
> +		return -EBUSY;
>  
>  	ret = vgxy61_try_fmt_internal(sd, &format->format, &new_mode);
>  	if (ret)
> -		goto out;
> -
> -	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
> -		fmt = v4l2_subdev_state_get_format(sd_state, 0);
> -		*fmt = format->format;
> -	} else if (sensor->current_mode != new_mode ||
> -		   sensor->fmt.code != format->format.code) {
> -		fmt = &sensor->fmt;
> -		*fmt = format->format;
> -
> -		sensor->current_mode = new_mode;
> -
> -		/* Reset vblank and framelength to default */
> -		ret = vgxy61_update_vblank(sensor,
> -					   VGXY61_FRAME_LENGTH_DEF -
> -					   new_mode->crop.height,
> -					   sensor->hdr);
> -
> -		/* Update controls to reflect new mode */
> -		__v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_ctrl,
> -					 get_pixel_rate(sensor));
> -		__v4l2_ctrl_modify_range(sensor->vblank_ctrl,
> -					 sensor->vblank_min,
> -					 0xffff - new_mode->crop.height,
> -					 1, sensor->vblank);
> -		__v4l2_ctrl_s_ctrl(sensor->vblank_ctrl, sensor->vblank);
> -		__v4l2_ctrl_modify_range(sensor->expo_ctrl, sensor->expo_min,
> -					 sensor->expo_max, 1,
> -					 sensor->expo_long);
> -	}
> +		return ret;
> +
> +	*v4l2_subdev_state_get_format(sd_state, format->pad) = format->format;
>  
> -out:
> -	mutex_unlock(&sensor->lock);
> +	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
> +		return 0;
> +
> +	sensor->current_mode = new_mode;
> +
> +	/* Reset vblank and framelength to default */
> +	ret = vgxy61_update_vblank(sensor,
> +				   VGXY61_FRAME_LENGTH_DEF -
> +				   new_mode->crop.height,
> +				   sensor->hdr);
> +
> +	/* Update controls to reflect new mode */
> +	__v4l2_ctrl_s_ctrl_int64(sensor->pixel_rate_ctrl,
> +				 get_pixel_rate(sensor));
> +	__v4l2_ctrl_modify_range(sensor->vblank_ctrl,
> +				 sensor->vblank_min,
> +				 0xffff - new_mode->crop.height,
> +				 1, sensor->vblank);
> +	__v4l2_ctrl_s_ctrl(sensor->vblank_ctrl, sensor->vblank);
> +	__v4l2_ctrl_modify_range(sensor->expo_ctrl, sensor->expo_min,
> +				 sensor->expo_max, 1,
> +				 sensor->expo_long);
>  
>  	return ret;
>  }
> @@ -1321,8 +1287,6 @@ static int vgxy61_init_controls(struct vgxy61_dev *sensor)
>  	int ret;
>  
>  	v4l2_ctrl_handler_init(hdl, 16);
> -	/* We can use our own mutex for the ctrl lock */
> -	hdl->lock = &sensor->lock;
>  	v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN, 0, 0x1c, 1,
>  			  sensor->analog_gain);
>  	v4l2_ctrl_new_std(hdl, ops, V4L2_CID_DIGITAL_GAIN, 0, 0xfff, 1,
> @@ -1398,7 +1362,7 @@ static const struct v4l2_subdev_video_ops vgxy61_video_ops = {
>  
>  static const struct v4l2_subdev_pad_ops vgxy61_pad_ops = {
>  	.enum_mbus_code = vgxy61_enum_mbus_code,
> -	.get_fmt = vgxy61_get_fmt,
> +	.get_fmt = v4l2_subdev_get_fmt,
>  	.set_fmt = vgxy61_set_fmt,
>  	.get_selection = vgxy61_get_selection,
>  	.enum_frame_size = vgxy61_enum_frame_size,
> @@ -1801,7 +1765,7 @@ static int vgxy61_probe(struct i2c_client *client)
>  	vgxy61_fill_framefmt(sensor, sensor->current_mode, &sensor->fmt,
>  			     VGXY61_MEDIA_BUS_FMT_DEF);
>  
> -	mutex_init(&sensor->lock);
> +	sensor->sd.state_lock = sensor->ctrl_handler.lock;
>  
>  	ret = vgxy61_update_hdr(sensor, sensor->hdr);
>  	if (ret)
> @@ -1820,6 +1784,10 @@ static int vgxy61_probe(struct i2c_client *client)
>  		goto error_handler_free;
>  	}
>  
> +	ret = v4l2_subdev_init_finalize(&sensor->sd);
> +	if (ret)
> +		goto error_media_entity_cleanup;
> +
>  	/* Enable runtime PM and turn off the device */
>  	pm_runtime_set_active(dev);
>  	pm_runtime_enable(dev);
> @@ -1841,11 +1809,12 @@ static int vgxy61_probe(struct i2c_client *client)
>  error_pm_runtime:
>  	pm_runtime_disable(&client->dev);
>  	pm_runtime_set_suspended(&client->dev);
> +	v4l2_subdev_cleanup(&sensor->sd);
> +error_media_entity_cleanup:
>  	media_entity_cleanup(&sensor->sd.entity);
>  error_handler_free:
>  	v4l2_ctrl_handler_free(sensor->sd.ctrl_handler);
>  error_power_off:
> -	mutex_destroy(&sensor->lock);
>  	vgxy61_power_off(dev);
>  
>  	return ret;
> @@ -1857,7 +1826,7 @@ static void vgxy61_remove(struct i2c_client *client)
>  	struct vgxy61_dev *sensor = to_vgxy61_dev(sd);
>  
>  	v4l2_async_unregister_subdev(&sensor->sd);
> -	mutex_destroy(&sensor->lock);
> +	v4l2_subdev_cleanup(&sensor->sd);
>  	media_entity_cleanup(&sensor->sd.entity);
>  
>  	pm_runtime_disable(&client->dev);

-- 
Regards,

Benjamin




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux