From: Sakari Ailus <sakari.ai...@linux.intel.com>

Two pads are considered having an active route for the purpose of
has_route() if an indirect active route can be found between the two pads.
An simple example of this is that a source pad has an active route to
another source pad if both of the pads have an active route to the same
sink pad.

Make media_entity_has_route() return true in that case, and do not rely on
drivers performing this by themselves.

Signed-off-by: Sakari Ailus <sakari.ai...@linux.intel.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund+rene...@ragnatech.se>
---
 drivers/media/media-entity.c | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 42977634d7102852..e45fc2549017615a 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -240,6 +240,9 @@ EXPORT_SYMBOL_GPL(media_entity_pads_init);
 bool media_entity_has_route(struct media_entity *entity, unsigned int pad0,
                            unsigned int pad1)
 {
+       unsigned int i;
+       bool has_route;
+
        if (pad0 >= entity->num_pads || pad1 >= entity->num_pads)
                return false;
 
@@ -253,7 +256,34 @@ bool media_entity_has_route(struct media_entity *entity, 
unsigned int pad0,
            && entity->pads[pad1].flags & MEDIA_PAD_FL_SINK)
                swap(pad0, pad1);
 
-       return entity->ops->has_route(entity, pad0, pad1);
+       has_route = entity->ops->has_route(entity, pad0, pad1);
+       /* A direct route is returned immediately */
+       if (has_route ||
+           (entity->pads[pad0].flags & MEDIA_PAD_FL_SINK &&
+            entity->pads[pad1].flags & MEDIA_PAD_FL_SOURCE))
+               return true;
+
+       /* Look for indirect routes */
+       for (i = 0; i < entity->num_pads; i++) {
+               if (i == pad0 || i == pad1)
+                       continue;
+
+               /*
+                * There are no direct routes between same types of
+                * pads, so skip checking this route
+                */
+               if (!((entity->pads[pad0].flags ^ entity->pads[i].flags) &
+                     (MEDIA_PAD_FL_SOURCE | MEDIA_PAD_FL_SINK)))
+                       continue;
+
+               /* Is there an indirect route? */
+               if (entity->ops->has_route(entity, i, pad0) &&
+                   entity->ops->has_route(entity, i, pad1))
+                       return true;
+       }
+
+       return false;
+
 }
 EXPORT_SYMBOL_GPL(media_entity_has_route);
 
-- 
2.19.1

Reply via email to