Skip to content

Commit

Permalink
media: mc: Expand MUST_CONNECT flag to always require an enabled link
Browse files Browse the repository at this point in the history
[ Upstream commit b3decc5 ]

The MEDIA_PAD_FL_MUST_CONNECT flag indicates that the pad requires an
enabled link to stream, but only if it has any link at all. This makes
little sense, as if a pad is part of a pipeline, there are very few use
cases for an active link to be mandatory only if links exist at all. A
review of in-tree drivers confirms they all need an enabled link for
pads marked with the MEDIA_PAD_FL_MUST_CONNECT flag.

Expand the scope of the flag by rejecting pads that have no links at
all. This requires modifying the pipeline build code to add those pads
to the pipeline.

Cc: stable@vger.kernel.org # 6.1
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
pinchartl authored and gregkh committed Apr 3, 2024
1 parent 61656ca commit e2c545b
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 16 deletions.
11 changes: 5 additions & 6 deletions Documentation/userspace-api/media/mediactl/media-types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -375,12 +375,11 @@ Types and flags used to represent the media graph elements
are origins of links.

* - ``MEDIA_PAD_FL_MUST_CONNECT``
- If this flag is set and the pad is linked to any other pad, then
at least one of those links must be enabled for the entity to be
able to stream. There could be temporary reasons (e.g. device
configuration dependent) for the pad to need enabled links even
when this flag isn't set; the absence of the flag doesn't imply
there is none.
- If this flag is set, then for this pad to be able to stream, it must
be connected by at least one enabled link. There could be temporary
reasons (e.g. device configuration dependent) for the pad to need
enabled links even when this flag isn't set; the absence of the flag
doesn't imply there is none.


One and only one of ``MEDIA_PAD_FL_SINK`` and ``MEDIA_PAD_FL_SOURCE``
Expand Down
53 changes: 43 additions & 10 deletions drivers/media/mc/mc-entity.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,14 +509,15 @@ static int media_pipeline_walk_push(struct media_pipeline_walk *walk,

/*
* Move the top entry link cursor to the next link. If all links of the entry
* have been visited, pop the entry itself.
* have been visited, pop the entry itself. Return true if the entry has been
* popped.
*/
static void media_pipeline_walk_pop(struct media_pipeline_walk *walk)
static bool media_pipeline_walk_pop(struct media_pipeline_walk *walk)
{
struct media_pipeline_walk_entry *entry;

if (WARN_ON(walk->stack.top < 0))
return;
return false;

entry = media_pipeline_walk_top(walk);

Expand All @@ -526,14 +527,16 @@ static void media_pipeline_walk_pop(struct media_pipeline_walk *walk)
walk->stack.top);

walk->stack.top--;
return;
return true;
}

entry->links = entry->links->next;

dev_dbg(walk->mdev->dev,
"media pipeline: moved entry %u to next link\n",
walk->stack.top);

return false;
}

/* Free all memory allocated while walking the pipeline. */
Expand Down Expand Up @@ -583,11 +586,12 @@ static int media_pipeline_explore_next_link(struct media_pipeline *pipe,
struct media_link *link;
struct media_pad *local;
struct media_pad *remote;
bool last_link;
int ret;

origin = entry->pad;
link = list_entry(entry->links, typeof(*link), list);
media_pipeline_walk_pop(walk);
last_link = media_pipeline_walk_pop(walk);

dev_dbg(walk->mdev->dev,
"media pipeline: exploring link '%s':%u -> '%s':%u\n",
Expand All @@ -612,7 +616,7 @@ static int media_pipeline_explore_next_link(struct media_pipeline *pipe,
local->index)) {
dev_dbg(walk->mdev->dev,
"media pipeline: skipping link (no route)\n");
return 0;
goto done;
}

/*
Expand All @@ -627,13 +631,44 @@ static int media_pipeline_explore_next_link(struct media_pipeline *pipe,
if (!(link->flags & MEDIA_LNK_FL_ENABLED)) {
dev_dbg(walk->mdev->dev,
"media pipeline: skipping link (disabled)\n");
return 0;
goto done;
}

ret = media_pipeline_add_pad(pipe, walk, remote);
if (ret)
return ret;

done:
/*
* If we're done iterating over links, iterate over pads of the entity.
* This is necessary to discover pads that are not connected with any
* link. Those are dead ends from a pipeline exploration point of view,
* but are still part of the pipeline and need to be added to enable
* proper validation.
*/
if (!last_link)
return 0;

dev_dbg(walk->mdev->dev,
"media pipeline: adding unconnected pads of '%s'\n",
local->entity->name);

media_entity_for_each_pad(origin->entity, local) {
/*
* Skip the origin pad (already handled), pad that have links
* (already discovered through iterating over links) and pads
* not internally connected.
*/
if (origin == local || !local->num_links ||
!media_entity_has_pad_interdep(origin->entity, origin->index,
local->index))
continue;

ret = media_pipeline_add_pad(pipe, walk, local);
if (ret)
return ret;
}

return 0;
}

Expand Down Expand Up @@ -745,7 +780,6 @@ __must_check int __media_pipeline_start(struct media_pad *pad,
struct media_pad *pad = ppad->pad;
struct media_entity *entity = pad->entity;
bool has_enabled_link = false;
bool has_link = false;
struct media_link *link;

dev_dbg(mdev->dev, "Validating pad '%s':%u\n", pad->entity->name,
Expand Down Expand Up @@ -775,7 +809,6 @@ __must_check int __media_pipeline_start(struct media_pad *pad,
/* Record if the pad has links and enabled links. */
if (link->flags & MEDIA_LNK_FL_ENABLED)
has_enabled_link = true;
has_link = true;

/*
* Validate the link if it's enabled and has the
Expand Down Expand Up @@ -813,7 +846,7 @@ __must_check int __media_pipeline_start(struct media_pad *pad,
* 3. If the pad has the MEDIA_PAD_FL_MUST_CONNECT flag set,
* ensure that it has either no link or an enabled link.
*/
if ((pad->flags & MEDIA_PAD_FL_MUST_CONNECT) && has_link &&
if ((pad->flags & MEDIA_PAD_FL_MUST_CONNECT) &&
!has_enabled_link) {
dev_dbg(mdev->dev,
"Pad '%s':%u must be connected by an enabled link\n",
Expand Down

0 comments on commit e2c545b

Please sign in to comment.