diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2022-06-14 20:11:09 +0100 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@kernel.org> | 2022-07-17 11:23:10 +0100 |
commit | 5680fe45d66bbef32a902c04889a523fa4fc33ba (patch) | |
tree | df50b09e239b51edc3ca8095bf6c2c554397e8ea /drivers/media/mc | |
parent | b2e44430b6348f68f56e78e932e6312f12128778 (diff) |
media: mc-entity: Add a new helper function to get a remote pad
The media_entity_remote_pad_first() helper function returns the first
remote pad it finds connected to a given pad. Beside being possibly
non-deterministic (as it stops at the first enabled link), the fact that
it returns the first match makes it unsuitable for drivers that need to
guarantee that a single link is enabled, for instance when an entity can
process data from one of multiple sources at a time.
For those use cases, add a new helper function,
media_entity_remote_pad_unique(), that operates on an entity and returns
a remote pad, with a guarantee that only one link is enabled. To ease
its use in drivers, also add an inline wrapper that locates source pads
specifically. A wrapper that locates sink pads can easily be added when
needed.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Diffstat (limited to 'drivers/media/mc')
-rw-r--r-- | drivers/media/mc/mc-entity.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index 66ba0629c4ce..767846b216c5 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -921,6 +921,45 @@ struct media_pad *media_pad_remote_pad_first(const struct media_pad *pad) } EXPORT_SYMBOL_GPL(media_pad_remote_pad_first); +struct media_pad * +media_entity_remote_pad_unique(const struct media_entity *entity, + unsigned int type) +{ + struct media_pad *pad = NULL; + struct media_link *link; + + list_for_each_entry(link, &entity->links, list) { + struct media_pad *local_pad; + struct media_pad *remote_pad; + + if (((link->flags & MEDIA_LNK_FL_LINK_TYPE) != + MEDIA_LNK_FL_DATA_LINK) || + !(link->flags & MEDIA_LNK_FL_ENABLED)) + continue; + + if (type == MEDIA_PAD_FL_SOURCE) { + local_pad = link->sink; + remote_pad = link->source; + } else { + local_pad = link->source; + remote_pad = link->sink; + } + + if (local_pad->entity == entity) { + if (pad) + return ERR_PTR(-ENOTUNIQ); + + pad = remote_pad; + } + } + + if (!pad) + return ERR_PTR(-ENOLINK); + + return pad; +} +EXPORT_SYMBOL_GPL(media_entity_remote_pad_unique); + static void media_interface_init(struct media_device *mdev, struct media_interface *intf, u32 gobj_type, |