From b01cc9ce7c13e0463575332dfa3171727f706afb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 30 Dec 2015 09:45:48 -0200 Subject: [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 --- drivers/media/media-entity.c | 65 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'drivers/media') 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; -- cgit v1.2.1