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]
