Re: [PATCH 47/57] media: atomisp: ov2680: Add runtime-pm support

Andy Shevchenko
2023-01-24T10:53:25Z

On Mon, Jan 23, 2023 at 01:51:55PM +0100, Hans de Goede wrote:
> Add runtime-pm support. This is a preparation patch for letting
> ACPI deal with the regulators and clocks instead of the DIY code
> in atomisp_gmin_platform.c.

Good one!
Reviewed-by: Andy Shevchenko <andy@kernel.org>

> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
> .../media/atomisp/i2c/atomisp-ov2680.c | 57 ++++++++++++-------
> drivers/staging/media/atomisp/i2c/ov2680.h | 1 -
> 2 files changed, 36 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index 2a8c4508cc66..881340d7466f 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -19,6 +19,7 @@
> #include <linux/device.h>
> #include <linux/i2c.h>
> #include <linux/module.h>
> +#include <linux/pm_runtime.h>
> #include <linux/types.h>
> #include <media/ovxxxx_16bit_addr_reg_helpers.h>
> #include <media/v4l2-device.h>
> @@ -138,7 +139,8 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
> struct ov2680_device *sensor = to_ov2680_sensor(sd);
> int ret;
>
> - if (!sensor->power_on) {
> + /* Only apply changes to the controls if the device is powered up */
> + if (!pm_runtime_get_if_in_use(sensor->sd.dev)) {
> ov2680_set_bayer_order(sensor, &sensor->mode.fmt);
> return 0;
> }
> @@ -162,6 +164,8 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
> default:
> ret = -EINVAL;
> }
> +
> + pm_runtime_put(sensor->sd.dev);
> return ret;
> }
>
> @@ -244,9 +248,6 @@ static int power_up(struct v4l2_subdev *sd)
> return -ENODEV;
> }
>
> - if (dev->power_on)
> - return 0; /* Already on */
> -
> /* power control */
> ret = power_ctrl(sd, 1);
> if (ret)
> @@ -275,7 +276,6 @@ static int power_up(struct v4l2_subdev *sd)
> if (ret)
> goto fail_init_registers;
>
> - dev->power_on = true;
> return 0;
>
> fail_init_registers:
> @@ -301,9 +301,6 @@ static int power_down(struct v4l2_subdev *sd)
> return -ENODEV;
> }
>
> - if (!dev->power_on)
> - return 0; /* Already off */
> -
> ret = dev->platform_data->flisclk_ctrl(sd, 0);
> if (ret)
> dev_err(&client->dev, "flisclk failed\n");
> @@ -323,7 +320,6 @@ static int power_down(struct v4l2_subdev *sd)
> return ret;
> }
>
> - dev->power_on = false;
> return 0;
> }
>
> @@ -562,8 +558,8 @@ static int ov2680_s_stream(struct v4l2_subdev *sd, int enable)
> }
>
> if (enable) {
> - ret = power_up(sd);
> - if (ret)
> + ret = pm_runtime_get_sync(sensor->sd.dev);
> + if (ret < 0)
> goto error_unlock;
>
> ret = ov2680_set_mode(sensor);
> @@ -580,7 +576,7 @@ static int ov2680_s_stream(struct v4l2_subdev *sd, int enable)
> goto error_power_down;
> } else {
> ovxxxx_write_reg8(client, OV2680_SW_STREAM, OV2680_STOP_STREAMING);
> - power_down(sd);
> + pm_runtime_put(sensor->sd.dev);
> }
>
> sensor->is_streaming = enable;
> @@ -591,7 +587,7 @@ static int ov2680_s_stream(struct v4l2_subdev *sd, int enable)
> return 0;
>
> error_power_down:
> - power_down(sd);
> + pm_runtime_put(sensor->sd.dev);
> error_unlock:
> mutex_unlock(&sensor->input_lock);
> return ret;
> @@ -612,8 +608,8 @@ static int ov2680_s_config(struct v4l2_subdev *sd,
>
> mutex_lock(&dev->input_lock);
>
> - ret = power_up(sd);
> - if (ret) {
> + ret = pm_runtime_get_sync(&client->dev);
> + if (ret < 0) {
> dev_err(&client->dev, "ov2680 power-up err.\n");
> goto fail_power_on;
> }
> @@ -630,11 +626,7 @@ static int ov2680_s_config(struct v4l2_subdev *sd,
> }
>
> /* turn off sensor, after probed */
> - ret = power_down(sd);
> - if (ret) {
> - dev_err(&client->dev, "ov2680 power-off err.\n");
> - goto fail_csi_cfg;
> - }
> + pm_runtime_put(&client->dev);
> mutex_unlock(&dev->input_lock);
>
> return 0;
> @@ -642,7 +634,7 @@ static int ov2680_s_config(struct v4l2_subdev *sd,
> fail_csi_cfg:
> dev->platform_data->csi_cfg(sd, 0);
> fail_power_on:
> - power_down(sd);
> + pm_runtime_put(&client->dev);
> dev_err(&client->dev, "sensor power-gating failed\n");
> mutex_unlock(&dev->input_lock);
> return ret;
> @@ -787,6 +779,7 @@ static void ov2680_remove(struct i2c_client *client)
> v4l2_device_unregister_subdev(sd);
> media_entity_cleanup(&dev->sd.entity);
> v4l2_ctrl_handler_free(&dev->ctrls.handler);
> + pm_runtime_disable(&client->dev);
> kfree(dev);
> }
>
> @@ -813,6 +806,11 @@ static int ov2680_probe(struct i2c_client *client)
> goto out_free;
> }
>
> + pm_runtime_set_suspended(&client->dev);
> + pm_runtime_enable(&client->dev);
> + pm_runtime_set_autosuspend_delay(&client->dev, 1000);
> + pm_runtime_use_autosuspend(&client->dev);
> +
> ret = ov2680_s_config(&dev->sd, client->irq, pdata);
> if (ret)
> goto out_free;
> @@ -849,6 +847,22 @@ static int ov2680_probe(struct i2c_client *client)
> return ret;
> }
>
> +static int ov2680_suspend(struct device *dev)
> +{
> + struct v4l2_subdev *sd = dev_get_drvdata(dev);
> +
> + return power_down(sd);
> +}
> +
> +static int ov2680_resume(struct device *dev)
> +{
> + struct v4l2_subdev *sd = dev_get_drvdata(dev);
> +
> + return power_up(sd);
> +}
> +
> +static DEFINE_RUNTIME_DEV_PM_OPS(ov2680_pm_ops, ov2680_suspend, ov2680_resume, NULL);
> +
> static const struct acpi_device_id ov2680_acpi_match[] = {
> {"XXOV2680"},
> {"OVTI2680"},
> @@ -859,6 +873,7 @@ MODULE_DEVICE_TABLE(acpi, ov2680_acpi_match);
> static struct i2c_driver ov2680_driver = {
> .driver = {
> .name = "ov2680",
> + .pm = pm_sleep_ptr(&ov2680_pm_ops),
> .acpi_match_table = ov2680_acpi_match,
> },
> .probe_new = ov2680_probe,
> diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
> index f0641dd611c3..58593da50f6f 100644
> --- a/drivers/staging/media/atomisp/i2c/ov2680.h
> +++ b/drivers/staging/media/atomisp/i2c/ov2680.h
> @@ -120,7 +120,6 @@ struct ov2680_device {
> struct mutex input_lock;
> struct i2c_client *client;
> struct camera_sensor_platform_data *platform_data;
> - bool power_on;
> bool is_streaming;
>
> struct ov2680_mode {
> --
> 2.39.0
>

--
With Best Regards,
Andy Shevchenko