summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacopo Mondi <jacopo@jmondi.org>2020-11-19 17:35:46 +0100
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2021-01-12 17:00:44 +0100
commit2f038c97fd7baaf9508cf32998a5f8f1ddc09a5e (patch)
tree2ab00d92dfeed024ad5607b2ad1fc1a23c57699d
parent089b7c70f0d80f5169cc87f65b065fc80668a0eb (diff)
downloadlinux-2f038c97fd7baaf9508cf32998a5f8f1ddc09a5e.tar.bz2
media: ov5647: Rework s_stream() operation
Rework the s_stream() operation to turn the sensor on and off at stream enable/disable time using the pm_runtime infrastructure. Protect the stream on/off from being called multiple times in sequence with a 'streaming' flag. Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
-rw-r--r--drivers/media/i2c/ov5647.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 777c7b30bafd..1ac1538a3951 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -114,6 +114,7 @@ struct ov5647 {
struct v4l2_ctrl *hblank;
struct v4l2_ctrl *vblank;
struct v4l2_ctrl *exposure;
+ bool streaming;
};
static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd)
@@ -1001,14 +1002,42 @@ __ov5647_get_pad_crop(struct ov5647 *ov5647, struct v4l2_subdev_pad_config *cfg,
static int ov5647_s_stream(struct v4l2_subdev *sd, int enable)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov5647 *sensor = to_sensor(sd);
int ret;
mutex_lock(&sensor->lock);
- if (enable)
+ if (sensor->streaming == enable) {
+ mutex_unlock(&sensor->lock);
+ return 0;
+ }
+
+ if (enable) {
+ ret = pm_runtime_get_sync(&client->dev);
+ if (ret < 0)
+ goto error_unlock;
+
ret = ov5647_stream_on(sd);
- else
+ if (ret < 0) {
+ dev_err(&client->dev, "stream start failed: %d\n", ret);
+ goto error_unlock;
+ }
+ } else {
ret = ov5647_stream_off(sd);
+ if (ret < 0) {
+ dev_err(&client->dev, "stream stop failed: %d\n", ret);
+ goto error_unlock;
+ }
+ pm_runtime_put(&client->dev);
+ }
+
+ sensor->streaming = enable;
+ mutex_unlock(&sensor->lock);
+
+ return 0;
+
+error_unlock:
+ pm_runtime_put(&client->dev);
mutex_unlock(&sensor->lock);
return ret;