This is an automatic generated email to let you know that the following patch 
were queued:

Subject: media: v4l2-subdev: Document and enforce .s_stream() requirements
Author:  Laurent Pinchart <laurent.pinch...@ideasonboard.com>
Date:    Mon Sep 18 15:48:38 2023 +0300

The subdev .s_stream() operation must not be called to start an already
started subdev, or stop an already stopped one. This requirement has
never been formally documented. Fix it, and catch possible offenders
with a WARN_ON() in the call_s_stream() wrapper.

Signed-off-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
Signed-off-by: Sakari Ailus <sakari.ai...@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil-ci...@xs4all.nl>

 drivers/media/v4l2-core/v4l2-subdev.c | 17 ++++++++++++++++-
 include/media/v4l2-subdev.h           |  4 +++-
 2 files changed, 19 insertions(+), 2 deletions(-)

---

diff --git a/drivers/media/v4l2-core/v4l2-subdev.c 
b/drivers/media/v4l2-core/v4l2-subdev.c
index b92348ad61f6..32b7d9cd43e6 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -359,6 +359,18 @@ static int call_s_stream(struct v4l2_subdev *sd, int 
enable)
 {
        int ret;
 
+       /*
+        * The .s_stream() operation must never be called to start or stop an
+        * already started or stopped subdev. Catch offenders but don't return
+        * an error yet to avoid regressions.
+        *
+        * As .s_stream() is mutually exclusive with the .enable_streams() and
+        * .disable_streams() operation, we can use the enabled_streams field
+        * to store the subdev streaming state.
+        */
+       if (WARN_ON(!!sd->enabled_streams == !!enable))
+               return 0;
+
 #if IS_REACHABLE(CONFIG_LEDS_CLASS)
        if (!IS_ERR_OR_NULL(sd->privacy_led)) {
                if (enable)
@@ -372,9 +384,12 @@ static int call_s_stream(struct v4l2_subdev *sd, int 
enable)
 
        if (!enable && ret < 0) {
                dev_warn(sd->dev, "disabling streaming failed (%d)\n", ret);
-               return 0;
+               ret = 0;
        }
 
+       if (!ret)
+               sd->enabled_streams = enable ? BIT(0) : 0;
+
        return ret;
 }
 
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 820e38ec3dc9..5f59ff0796b7 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -446,7 +446,9 @@ enum v4l2_subdev_pre_streamon_flags {
  * @s_stream: start (enabled == 1) or stop (enabled == 0) streaming on the
  *     sub-device. Failure on stop will remove any resources acquired in
  *     streaming start, while the error code is still returned by the driver.
- *     Also see call_s_stream wrapper in v4l2-subdev.c.
+ *     The caller shall track the subdev state, and shall not start or stop an
+ *     already started or stopped subdev. Also see call_s_stream wrapper in
+ *     v4l2-subdev.c.
  *
  * @g_pixelaspect: callback to return the pixelaspect ratio.
  *

_______________________________________________
linuxtv-commits mailing list
linuxtv-commits@linuxtv.org
https://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to