[PATCH v8 11/14] media: ov02c10: Switch to {enable,disable}_streams

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

 



Switch from s_stream() to enable_streams() and disable_streams() pad
operations. They are preferred and required for streams support.

Note this also stops calling ov02c10_stop_streaming() on enable_streams()
errors. If ov02c10_start_streaming() fails OV02C10_REG_STREAM_CONTROL bit 0
will have never been set so there is no need to clear it on errors.

Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx>
---
 drivers/media/i2c/ov02c10.c | 59 +++++++++++++++++++++----------------
 1 file changed, 33 insertions(+), 26 deletions(-)

diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c
index a46cacf301a2..da727e18a282 100644
--- a/drivers/media/i2c/ov02c10.c
+++ b/drivers/media/i2c/ov02c10.c
@@ -2,6 +2,7 @@
 // Copyright (c) 2022 Intel Corporation.
 
 #include <linux/acpi.h>
+#include <linux/cleanup.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/gpio/consumer.h>
@@ -602,41 +603,45 @@ static void ov02c10_stop_streaming(struct ov02c10 *ov02c10)
 	cci_write(ov02c10->regmap, OV02C10_REG_STREAM_CONTROL, 0, NULL);
 }
 
-static int ov02c10_set_stream(struct v4l2_subdev *sd, int enable)
+static int ov02c10_enable_streams(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_state *state,
+				  u32 pad, u64 streams_mask)
 {
-	struct ov02c10 *ov02c10 = to_ov02c10(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	int ret = 0;
+	struct ov02c10 *ov02c10 = to_ov02c10(sd);
+	int ret;
 
-	if (ov02c10->streaming == enable)
-		return 0;
+	guard(mutex)(&ov02c10->mutex);
 
-	mutex_lock(&ov02c10->mutex);
-	if (enable) {
-		ret = pm_runtime_get_sync(&client->dev);
-		if (ret < 0) {
-			pm_runtime_put_noidle(&client->dev);
-			mutex_unlock(&ov02c10->mutex);
-			return ret;
-		}
+	ret = pm_runtime_resume_and_get(&client->dev);
+	if (ret)
+		return ret;
 
-		ret = ov02c10_start_streaming(ov02c10);
-		if (ret) {
-			enable = 0;
-			ov02c10_stop_streaming(ov02c10);
-			pm_runtime_put(&client->dev);
-		}
-	} else {
-		ov02c10_stop_streaming(ov02c10);
+	ret = ov02c10_start_streaming(ov02c10);
+	if (ret == 0)
+		ov02c10->streaming = true;
+	else
 		pm_runtime_put(&client->dev);
-	}
-
-	ov02c10->streaming = enable;
-	mutex_unlock(&ov02c10->mutex);
 
 	return ret;
 }
 
+static int ov02c10_disable_streams(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_state *state,
+				   u32 pad, u64 streams_mask)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct ov02c10 *ov02c10 = to_ov02c10(sd);
+
+	guard(mutex)(&ov02c10->mutex);
+
+	ov02c10_stop_streaming(ov02c10);
+	ov02c10->streaming = false;
+	pm_runtime_put(&client->dev);
+
+	return 0;
+}
+
 /* This function tries to get power control resources */
 static int ov02c10_get_pm_resources(struct device *dev)
 {
@@ -836,7 +841,7 @@ static int ov02c10_init_state(struct v4l2_subdev *sd,
 }
 
 static const struct v4l2_subdev_video_ops ov02c10_video_ops = {
-	.s_stream = ov02c10_set_stream,
+	.s_stream = v4l2_subdev_s_stream_helper,
 };
 
 static const struct v4l2_subdev_pad_ops ov02c10_pad_ops = {
@@ -844,6 +849,8 @@ static const struct v4l2_subdev_pad_ops ov02c10_pad_ops = {
 	.get_fmt = ov02c10_get_format,
 	.enum_mbus_code = ov02c10_enum_mbus_code,
 	.enum_frame_size = ov02c10_enum_frame_size,
+	.enable_streams = ov02c10_enable_streams,
+	.disable_streams = ov02c10_disable_streams,
 };
 
 static const struct v4l2_subdev_ops ov02c10_subdev_ops = {
-- 
2.48.1





[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