On Thu Mar 19 01:58:57 2026 +0200, Laurent Pinchart wrote:
> The media bus code passed to the .enum_frame_size() operation for the
> sink pad is required to be supported by the device, but not to match the
> current format. All entities that use the vsp1_subdev_enum_frame_size()
> helper, as well as the SRU and UDS entities that implement the operation
> manually, perform the check incorrectly.
> 
> Fix the issue by implementing the correct code check in the
> vsp1_subdev_enum_frame_size(). For the SRU and UDS, to avoid duplicating
> code, use the vsp1_subdev_enum_frame_size() as a base and override the
> enumerated size on the source pad with entity-specific constraints.
> 
> While at it, include the missing <linux/mutex.h> as the code locks
> mutexes.
> 
> Tested-by: Niklas Söderlund <[email protected]>
> Tested-by: Lad Prabhakar <[email protected]> # HiHope 
> RZ/G2M
> Link: 
> https://patch.msgid.link/20260318235907.831556-4-laurent.pinchart+rene...@ideasonboard.com
> Signed-off-by: Laurent Pinchart <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/platform/renesas/vsp1/vsp1_entity.c | 45 ++++++++++++++---------
 drivers/media/platform/renesas/vsp1/vsp1_sru.c    | 38 +++++++++----------
 drivers/media/platform/renesas/vsp1/vsp1_uds.c    | 38 +++++++++----------
 3 files changed, 62 insertions(+), 59 deletions(-)

---

diff --git a/drivers/media/platform/renesas/vsp1/vsp1_entity.c 
b/drivers/media/platform/renesas/vsp1/vsp1_entity.c
index 04b7ae6fb935..892a2adfdf3a 100644
--- a/drivers/media/platform/renesas/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/renesas/vsp1/vsp1_entity.c
@@ -7,8 +7,10 @@
  * Contact: Laurent Pinchart ([email protected])
  */
 
+#include <linux/cleanup.h>
 #include <linux/device.h>
 #include <linux/gfp.h>
+#include <linux/mutex.h>
 
 #include <media/media-entity.h>
 #include <media/v4l2-ctrls.h>
@@ -238,42 +240,51 @@ int vsp1_subdev_enum_frame_size(struct v4l2_subdev 
*subdev,
                                struct v4l2_subdev_frame_size_enum *fse)
 {
        struct vsp1_entity *entity = to_vsp1_entity(subdev);
-       struct v4l2_subdev_state *state;
-       struct v4l2_mbus_framefmt *format;
-       int ret = 0;
 
-       state = vsp1_entity_get_state(entity, sd_state, fse->which);
-       if (!state)
+       if (fse->index)
                return -EINVAL;
 
-       format = v4l2_subdev_state_get_format(state, fse->pad);
+       if (fse->pad == 0) {
+               unsigned int i;
 
-       mutex_lock(&entity->lock);
+               for (i = 0; i < entity->num_codes; ++i) {
+                       if (fse->code == entity->codes[i])
+                               break;
+               }
 
-       if (fse->index || fse->code != format->code) {
-               ret = -EINVAL;
-               goto done;
-       }
+               if (i == entity->num_codes)
+                       return -EINVAL;
 
-       if (fse->pad == 0) {
                fse->min_width = entity->min_width;
                fse->max_width = entity->max_width;
                fse->min_height = entity->min_height;
                fse->max_height = entity->max_height;
        } else {
+               struct v4l2_subdev_state *state;
+               struct v4l2_mbus_framefmt *format;
+
+               state = vsp1_entity_get_state(entity, sd_state, fse->which);
+               if (!state)
+                       return -EINVAL;
+
                /*
-                * The size on the source pad are fixed and always identical to
-                * the size on the sink pad.
+                * The media bus code and size on the source pad are fixed and
+                * always identical to the sink pad.
                 */
+               format = v4l2_subdev_state_get_format(state, 0);
+
+               guard(mutex)(&entity->lock);
+
+               if (fse->code != format->code)
+                       return -EINVAL;
+
                fse->min_width = format->width;
                fse->max_width = format->width;
                fse->min_height = format->height;
                fse->max_height = format->height;
        }
 
-done:
-       mutex_unlock(&entity->lock);
-       return ret;
+       return 0;
 }
 
 /*
diff --git a/drivers/media/platform/renesas/vsp1/vsp1_sru.c 
b/drivers/media/platform/renesas/vsp1/vsp1_sru.c
index 1dc34e6a510d..37fd36d09045 100644
--- a/drivers/media/platform/renesas/vsp1/vsp1_sru.c
+++ b/drivers/media/platform/renesas/vsp1/vsp1_sru.c
@@ -7,8 +7,10 @@
  * Contact: Laurent Pinchart ([email protected])
  */
 
+#include <linux/cleanup.h>
 #include <linux/device.h>
 #include <linux/gfp.h>
+#include <linux/mutex.h>
 
 #include <media/v4l2-subdev.h>
 
@@ -116,29 +118,25 @@ static int sru_enum_frame_size(struct v4l2_subdev *subdev,
                               struct v4l2_subdev_frame_size_enum *fse)
 {
        struct vsp1_sru *sru = to_sru(subdev);
-       struct v4l2_subdev_state *state;
-       struct v4l2_mbus_framefmt *format;
-       int ret = 0;
+       int ret;
 
-       state = vsp1_entity_get_state(&sru->entity, sd_state, fse->which);
-       if (!state)
-               return -EINVAL;
+       ret = vsp1_subdev_enum_frame_size(subdev, sd_state, fse);
+       if (ret)
+               return ret;
 
-       format = v4l2_subdev_state_get_format(state, SRU_PAD_SINK);
+       if (fse->pad == SRU_PAD_SOURCE) {
+               struct v4l2_subdev_state *state;
+               struct v4l2_mbus_framefmt *format;
 
-       mutex_lock(&sru->entity.lock);
+               state = vsp1_entity_get_state(&sru->entity, sd_state,
+                                             fse->which);
+               if (!state)
+                       return -EINVAL;
 
-       if (fse->index || fse->code != format->code) {
-               ret = -EINVAL;
-               goto done;
-       }
+               format = v4l2_subdev_state_get_format(state, SRU_PAD_SINK);
+
+               guard(mutex)(&sru->entity.lock);
 
-       if (fse->pad == SRU_PAD_SINK) {
-               fse->min_width = SRU_MIN_SIZE;
-               fse->max_width = SRU_MAX_SIZE;
-               fse->min_height = SRU_MIN_SIZE;
-               fse->max_height = SRU_MAX_SIZE;
-       } else {
                fse->min_width = format->width;
                fse->min_height = format->height;
                if (format->width <= SRU_MAX_SIZE / 2 &&
@@ -151,9 +149,7 @@ static int sru_enum_frame_size(struct v4l2_subdev *subdev,
                }
        }
 
-done:
-       mutex_unlock(&sru->entity.lock);
-       return ret;
+       return 0;
 }
 
 static void sru_try_format(struct vsp1_sru *sru,
diff --git a/drivers/media/platform/renesas/vsp1/vsp1_uds.c 
b/drivers/media/platform/renesas/vsp1/vsp1_uds.c
index 8006d49ffbea..dd4722315c56 100644
--- a/drivers/media/platform/renesas/vsp1/vsp1_uds.c
+++ b/drivers/media/platform/renesas/vsp1/vsp1_uds.c
@@ -7,8 +7,10 @@
  * Contact: Laurent Pinchart ([email protected])
  */
 
+#include <linux/cleanup.h>
 #include <linux/device.h>
 #include <linux/gfp.h>
+#include <linux/mutex.h>
 
 #include <media/v4l2-subdev.h>
 
@@ -121,38 +123,32 @@ static int uds_enum_frame_size(struct v4l2_subdev *subdev,
                               struct v4l2_subdev_frame_size_enum *fse)
 {
        struct vsp1_uds *uds = to_uds(subdev);
-       struct v4l2_subdev_state *state;
-       struct v4l2_mbus_framefmt *format;
-       int ret = 0;
+       int ret;
 
-       state = vsp1_entity_get_state(&uds->entity, sd_state, fse->which);
-       if (!state)
-               return -EINVAL;
+       ret = vsp1_subdev_enum_frame_size(subdev, sd_state, fse);
+       if (ret)
+               return ret;
 
-       format = v4l2_subdev_state_get_format(state, UDS_PAD_SINK);
+       if (fse->pad == UDS_PAD_SOURCE) {
+               struct v4l2_subdev_state *state;
+               struct v4l2_mbus_framefmt *format;
 
-       mutex_lock(&uds->entity.lock);
+               state = vsp1_entity_get_state(&uds->entity, sd_state,
+                                             fse->which);
+               if (!state)
+                       return -EINVAL;
 
-       if (fse->index || fse->code != format->code) {
-               ret = -EINVAL;
-               goto done;
-       }
+               format = v4l2_subdev_state_get_format(state, UDS_PAD_SINK);
+
+               guard(mutex)(&uds->entity.lock);
 
-       if (fse->pad == UDS_PAD_SINK) {
-               fse->min_width = UDS_MIN_SIZE;
-               fse->max_width = UDS_MAX_SIZE;
-               fse->min_height = UDS_MIN_SIZE;
-               fse->max_height = UDS_MAX_SIZE;
-       } else {
                uds_output_limits(format->width, &fse->min_width,
                                  &fse->max_width);
                uds_output_limits(format->height, &fse->min_height,
                                  &fse->max_height);
        }
 
-done:
-       mutex_unlock(&uds->entity.lock);
-       return ret;
+       return 0;
 }
 
 static void uds_try_format(struct vsp1_uds *uds,
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to