From cff23f2ce2ae0ca5bede4556a8e206280092361f Mon Sep 17 00:00:00 2001 From: Andrey Skvortsov Date: Mon, 14 Aug 2023 13:27:08 +0300 Subject: media: gc2145: implement system suspend If system was suspended while camera sensor was used, data and interrupts were still coming from sensor and that caused unstable system. Sometimes system hanged during a resume. Signed-off-by: Andrey Skvortsov --- drivers/media/i2c/gc2145.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/media/i2c/gc2145.c b/drivers/media/i2c/gc2145.c index 749dce832aa0..429d86bf5f01 100644 --- a/drivers/media/i2c/gc2145.c +++ b/drivers/media/i2c/gc2145.c @@ -2275,6 +2275,42 @@ static void gc2145_remove(struct i2c_client *client) v4l2_ctrl_handler_free(&sensor->ctrls.handler); } +static int gc2145_sensor_suspend(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct gc2145_dev *sensor = to_gc2145_dev(sd); + + mutex_lock(&sensor->lock); + if (sensor->streaming) + gc2145_set_stream(sensor, false); + mutex_unlock(&sensor->lock); + + return 0; +} + +static int gc2145_sensor_resume(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct gc2145_dev *sensor = to_gc2145_dev(sd); + int ret = 0; + + mutex_lock(&sensor->lock); + if (sensor->streaming) { + ret = gc2145_set_stream(sensor, true); + if (ret) { + gc2145_set_stream(sensor, false); + sensor->streaming = false; + } + } + mutex_unlock(&sensor->lock); + + return ret; +} + +static const struct dev_pm_ops gc2145_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(gc2145_sensor_suspend, gc2145_sensor_resume) +}; + static const struct i2c_device_id gc2145_id[] = { {"gc2145", 0}, {}, @@ -2291,6 +2327,7 @@ static struct i2c_driver gc2145_i2c_driver = { .driver = { .name = "gc2145", .of_match_table = gc2145_dt_ids, + .pm = &gc2145_pm_ops, }, .id_table = gc2145_id, .probe = gc2145_probe, -- 2.35.3