diff options
author | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-12-30 12:45:48 +0100 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2016-01-11 15:19:26 +0100 |
commit | b01cc9ce7c13e0463575332dfa3171727f706afb (patch) | |
tree | 12ceed1549c68cdcb0fbfad45b537b44584a18d5 /drivers | |
parent | [media] dvb-usb-v2: postpone removal of media_device (diff) | |
download | linux-b01cc9ce7c13e0463575332dfa3171727f706afb.tar.xz linux-b01cc9ce7c13e0463575332dfa3171727f706afb.zip |
[media] media-entitiy: add a function to create multiple links
Sometimes, it is desired to create 1:n and n:1 or even
n:n links between different entities with the same
function.
This is actually needed to support DVB devices that
have multiple frontends. While we could do a function
like that internally at the DVB core, such function is
generic enough to be at media-entity, and it could be
useful on some other places.
So, add such function.
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/media-entity.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index eb38bc35320a..e89d85a7d31b 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -625,6 +625,71 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, } EXPORT_SYMBOL_GPL(media_create_pad_link); +int media_create_pad_links(const struct media_device *mdev, + const u32 source_function, + struct media_entity *source, + const u16 source_pad, + const u32 sink_function, + struct media_entity *sink, + const u16 sink_pad, + u32 flags, + const bool allow_both_undefined) +{ + struct media_entity *entity; + unsigned function; + int ret; + + /* Trivial case: 1:1 relation */ + if (source && sink) + return media_create_pad_link(source, source_pad, + sink, sink_pad, flags); + + /* Worse case scenario: n:n relation */ + if (!source && !sink) { + if (!allow_both_undefined) + return 0; + media_device_for_each_entity(source, mdev) { + if (source->function != source_function) + continue; + media_device_for_each_entity(sink, mdev) { + if (sink->function != sink_function) + continue; + ret = media_create_pad_link(source, source_pad, + sink, sink_pad, + flags); + if (ret) + return ret; + flags &= ~(MEDIA_LNK_FL_ENABLED | + MEDIA_LNK_FL_IMMUTABLE); + } + } + return 0; + } + + /* Handle 1:n and n:1 cases */ + if (source) + function = sink_function; + else + function = source_function; + + media_device_for_each_entity(entity, mdev) { + if (entity->function != function) + continue; + + if (source) + ret = media_create_pad_link(source, source_pad, + entity, sink_pad, flags); + else + ret = media_create_pad_link(entity, source_pad, + sink, sink_pad, flags); + if (ret) + return ret; + flags &= ~(MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE); + } + return 0; +} +EXPORT_SYMBOL_GPL(media_create_pad_links); + void __media_entity_remove_links(struct media_entity *entity) { struct media_link *link, *tmp; |