Skip to content

Commit 61d6c8c

Browse files
tombaHans Verkuil
authored andcommitted
media: subdev: Improve v4l2_subdev_enable/disable_streams_fallback
v4l2_subdev_enable/disable_streams_fallback() supports falling back to .s_stream() for subdevs with a single source pad. It also tracks the enabled streams for that one pad in the sd->enabled_streams field. Tracking the enabled streams with sd->enabled_streams does not make sense, as with .s_stream() there can only be a single stream per pad. Thus, as the v4l2_subdev_enable/disable_streams_fallback() only supports a single source pad, all we really need is a boolean which tells whether streaming has been enabled on this pad or not. However, as we only need a true/false state for a pad (instead of tracking which streams have been enabled for a pad), we can easily extend the fallback mechanism to support multiple source pads as we only need to keep track of which pads have been enabled. Change the sd->enabled_streams field to sd->enabled_pads, which is a 64-bit bitmask tracking the enabled source pads. With this change we can remove the restriction that v4l2_subdev_enable/disable_streams_fallback() only supports a single source pad. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Tested-by: Umang Jain <umang.jain@ideasonboard.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
1 parent 1d78042 commit 61d6c8c

File tree

2 files changed

+44
-33
lines changed

2 files changed

+44
-33
lines changed

drivers/media/v4l2-core/v4l2-subdev.c

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2159,37 +2159,43 @@ static int v4l2_subdev_enable_streams_fallback(struct v4l2_subdev *sd, u32 pad,
21592159
u64 streams_mask)
21602160
{
21612161
struct device *dev = sd->entity.graph_obj.mdev->dev;
2162-
unsigned int i;
21632162
int ret;
21642163

21652164
/*
21662165
* The subdev doesn't implement pad-based stream enable, fall back
2167-
* on the .s_stream() operation. This can only be done for subdevs that
2168-
* have a single source pad, as sd->enabled_streams is global to the
2169-
* subdev.
2166+
* to the .s_stream() operation.
21702167
*/
21712168
if (!(sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE))
21722169
return -EOPNOTSUPP;
21732170

2174-
for (i = 0; i < sd->entity.num_pads; ++i) {
2175-
if (i != pad && sd->entity.pads[i].flags & MEDIA_PAD_FL_SOURCE)
2176-
return -EOPNOTSUPP;
2177-
}
2171+
/*
2172+
* .s_stream() means there is no streams support, so the only allowed
2173+
* stream is the implicit stream 0.
2174+
*/
2175+
if (streams_mask != BIT_ULL(0))
2176+
return -EOPNOTSUPP;
2177+
2178+
/*
2179+
* We use a 64-bit bitmask for tracking enabled pads, so only subdevices
2180+
* with 64 pads or less can be supported.
2181+
*/
2182+
if (pad >= sizeof(sd->enabled_pads) * BITS_PER_BYTE)
2183+
return -EOPNOTSUPP;
21782184

2179-
if (sd->enabled_streams & streams_mask) {
2180-
dev_dbg(dev, "set of streams %#llx already enabled on %s:%u\n",
2181-
streams_mask, sd->entity.name, pad);
2185+
if (sd->enabled_pads & BIT_ULL(pad)) {
2186+
dev_dbg(dev, "pad %u already enabled on %s\n",
2187+
pad, sd->entity.name);
21822188
return -EALREADY;
21832189
}
21842190

2185-
/* Start streaming when the first streams are enabled. */
2186-
if (!sd->enabled_streams) {
2191+
/* Start streaming when the first pad is enabled. */
2192+
if (!sd->enabled_pads) {
21872193
ret = v4l2_subdev_call(sd, video, s_stream, 1);
21882194
if (ret)
21892195
return ret;
21902196
}
21912197

2192-
sd->enabled_streams |= streams_mask;
2198+
sd->enabled_pads |= BIT_ULL(pad);
21932199

21942200
return 0;
21952201
}
@@ -2276,37 +2282,43 @@ static int v4l2_subdev_disable_streams_fallback(struct v4l2_subdev *sd, u32 pad,
22762282
u64 streams_mask)
22772283
{
22782284
struct device *dev = sd->entity.graph_obj.mdev->dev;
2279-
unsigned int i;
22802285
int ret;
22812286

22822287
/*
2283-
* If the subdev doesn't implement pad-based stream enable, fall back
2284-
* on the .s_stream() operation. This can only be done for subdevs that
2285-
* have a single source pad, as sd->enabled_streams is global to the
2286-
* subdev.
2288+
* If the subdev doesn't implement pad-based stream enable, fall back
2289+
* to the .s_stream() operation.
22872290
*/
22882291
if (!(sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE))
22892292
return -EOPNOTSUPP;
22902293

2291-
for (i = 0; i < sd->entity.num_pads; ++i) {
2292-
if (i != pad && sd->entity.pads[i].flags & MEDIA_PAD_FL_SOURCE)
2293-
return -EOPNOTSUPP;
2294-
}
2294+
/*
2295+
* .s_stream() means there is no streams support, so the only allowed
2296+
* stream is the implicit stream 0.
2297+
*/
2298+
if (streams_mask != BIT_ULL(0))
2299+
return -EOPNOTSUPP;
2300+
2301+
/*
2302+
* We use a 64-bit bitmask for tracking enabled pads, so only subdevices
2303+
* with 64 pads or less can be supported.
2304+
*/
2305+
if (pad >= sizeof(sd->enabled_pads) * BITS_PER_BYTE)
2306+
return -EOPNOTSUPP;
22952307

2296-
if ((sd->enabled_streams & streams_mask) != streams_mask) {
2297-
dev_dbg(dev, "set of streams %#llx already disabled on %s:%u\n",
2298-
streams_mask, sd->entity.name, pad);
2308+
if (!(sd->enabled_pads & BIT_ULL(pad))) {
2309+
dev_dbg(dev, "pad %u already disabled on %s\n",
2310+
pad, sd->entity.name);
22992311
return -EALREADY;
23002312
}
23012313

23022314
/* Stop streaming when the last streams are disabled. */
2303-
if (!(sd->enabled_streams & ~streams_mask)) {
2315+
if (!(sd->enabled_pads & ~BIT_ULL(pad))) {
23042316
ret = v4l2_subdev_call(sd, video, s_stream, 0);
23052317
if (ret)
23062318
return ret;
23072319
}
23082320

2309-
sd->enabled_streams &= ~streams_mask;
2321+
sd->enabled_pads &= ~BIT_ULL(pad);
23102322

23112323
return 0;
23122324
}

include/media/v4l2-subdev.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,10 +1041,9 @@ struct v4l2_subdev_platform_data {
10411041
* @active_state: Active state for the subdev (NULL for subdevs tracking the
10421042
* state internally). Initialized by calling
10431043
* v4l2_subdev_init_finalize().
1044-
* @enabled_streams: Bitmask of enabled streams used by
1045-
* v4l2_subdev_enable_streams() and
1046-
* v4l2_subdev_disable_streams() helper functions for fallback
1047-
* cases.
1044+
* @enabled_pads: Bitmask of enabled pads used by v4l2_subdev_enable_streams()
1045+
* and v4l2_subdev_disable_streams() helper functions for
1046+
* fallback cases.
10481047
* @s_stream_enabled: Tracks whether streaming has been enabled with s_stream.
10491048
* This is only for call_s_stream() internal use.
10501049
*
@@ -1094,7 +1093,7 @@ struct v4l2_subdev {
10941093
* doesn't support it.
10951094
*/
10961095
struct v4l2_subdev_state *active_state;
1097-
u64 enabled_streams;
1096+
u64 enabled_pads;
10981097
bool s_stream_enabled;
10991098
};
11001099

0 commit comments

Comments
 (0)