summaryrefslogtreecommitdiff
path: root/drivers/media/v4l2-core/v4l2-subdev.c
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ideasonboard.com>2023-03-02 10:57:48 +0100
committerMauro Carvalho Chehab <mchehab@kernel.org>2023-03-20 00:39:13 +0100
commita1299df6718b718256fd9bf6d7f9bed44c826e61 (patch)
tree71833170020fb3e94d6c93f55c8eb73d946bd8dc /drivers/media/v4l2-core/v4l2-subdev.c
parent698a619a04bee1359358d5cba552f008709b79bc (diff)
media: subdev: Add V4L2_SUBDEV_ROUTING_NO_MULTIPLEXING
A common case with subdev routing is that on the subdevice just before the DMA engines (video nodes), no multiplexing is allowed on the source pads, as the DMA engine can only handle a single stream. In some other situations one might also want to do the same check on the sink side. Add new routing validation flags to check these: V4L2_SUBDEV_ROUTING_NO_SINK_MULTIPLEXING and V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-subdev.c')
-rw-r--r--drivers/media/v4l2-core/v4l2-subdev.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index b376c47b083d..bfb102f2121a 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -1708,7 +1708,8 @@ int v4l2_subdev_routing_validate(struct v4l2_subdev *sd,
unsigned int i, j;
int ret = -EINVAL;
- if (disallow & V4L2_SUBDEV_ROUTING_NO_STREAM_MIX) {
+ if (disallow & (V4L2_SUBDEV_ROUTING_NO_STREAM_MIX |
+ V4L2_SUBDEV_ROUTING_NO_MULTIPLEXING)) {
remote_pads = kcalloc(sd->entity.num_pads, sizeof(*remote_pads),
GFP_KERNEL);
if (!remote_pads)
@@ -1748,8 +1749,6 @@ int v4l2_subdev_routing_validate(struct v4l2_subdev *sd,
i, "sink");
goto out;
}
-
- remote_pads[route->sink_pad] = route->source_pad;
}
/*
@@ -1764,7 +1763,38 @@ int v4l2_subdev_routing_validate(struct v4l2_subdev *sd,
i, "source");
goto out;
}
+ }
+
+ /*
+ * V4L2_SUBDEV_ROUTING_NO_SINK_MULTIPLEXING: Pads on the sink
+ * side can not do stream multiplexing, i.e. there can be only
+ * a single stream in a sink pad.
+ */
+ if (disallow & V4L2_SUBDEV_ROUTING_NO_SINK_MULTIPLEXING) {
+ if (remote_pads[route->sink_pad] != U32_MAX) {
+ dev_dbg(sd->dev,
+ "route %u attempts to multiplex on %s pad %u\n",
+ i, "sink", route->sink_pad);
+ goto out;
+ }
+ }
+ /*
+ * V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING: Pads on the
+ * source side can not do stream multiplexing, i.e. there can
+ * be only a single stream in a source pad.
+ */
+ if (disallow & V4L2_SUBDEV_ROUTING_NO_SOURCE_MULTIPLEXING) {
+ if (remote_pads[route->source_pad] != U32_MAX) {
+ dev_dbg(sd->dev,
+ "route %u attempts to multiplex on %s pad %u\n",
+ i, "source", route->source_pad);
+ goto out;
+ }
+ }
+
+ if (remote_pads) {
+ remote_pads[route->sink_pad] = route->source_pad;
remote_pads[route->source_pad] = route->sink_pad;
}