void coresight_disable_path(struct list_head *path);
 int coresight_enable_path(struct list_head *path, u32 mode, void *sink_data);
 struct coresight_device *coresight_get_sink(struct list_head *path);
-struct coresight_device *coresight_get_enabled_sink(bool reset);
+struct coresight_device *
+coresight_get_enabled_sink(struct coresight_device *source);
 struct coresight_device *coresight_get_sink_by_id(u32 id);
 struct list_head *coresight_build_path(struct coresight_device *csdev,
                                       struct coresight_device *sink);
 
        return csdev;
 }
 
-static int coresight_enabled_sink(struct device *dev, const void *data)
+static struct coresight_device *
+coresight_find_enabled_sink(struct coresight_device *csdev)
 {
-       const bool *reset = data;
-       struct coresight_device *csdev = to_coresight_device(dev);
+       int i;
+       struct coresight_device *sink;
 
        if ((csdev->type == CORESIGHT_DEV_TYPE_SINK ||
             csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) &&
-            csdev->activated) {
-               /*
-                * Now that we have a handle on the sink for this session,
-                * disable the sysFS "enable_sink" flag so that possible
-                * concurrent perf session that wish to use another sink don't
-                * trip on it.  Doing so has no ramification for the current
-                * session.
-                */
-               if (*reset)
-                       csdev->activated = false;
+            csdev->activated)
+               return csdev;
 
-               return 1;
+       /*
+        * Recursively explore each port found on this element.
+        */
+       for (i = 0; i < csdev->pdata->nr_outport; i++) {
+               struct coresight_device *child_dev;
+
+               child_dev = csdev->pdata->conns[i].child_dev;
+               if (child_dev)
+                       sink = coresight_find_enabled_sink(child_dev);
+               if (sink)
+                       return sink;
        }
 
-       return 0;
+       return NULL;
 }
 
 /**
- * coresight_get_enabled_sink - returns the first enabled sink found on the bus
- * @deactivate:        Whether the 'enable_sink' flag should be reset
+ * coresight_get_enabled_sink - returns the first enabled sink using
+ * connection based search starting from the source reference
  *
- * When operated from perf the deactivate parameter should be set to 'true'.
- * That way the "enabled_sink" flag of the sink that was selected can be reset,
- * allowing for other concurrent perf sessions to choose a different sink.
- *
- * When operated from sysFS users have full control and as such the deactivate
- * parameter should be set to 'false', hence mandating users to explicitly
- * clear the flag.
+ * @source: Coresight source device reference
  */
-struct coresight_device *coresight_get_enabled_sink(bool deactivate)
+struct coresight_device *
+coresight_get_enabled_sink(struct coresight_device *source)
 {
-       struct device *dev = NULL;
-
-       dev = bus_find_device(&coresight_bustype, NULL, &deactivate,
-                             coresight_enabled_sink);
+       if (!source)
+               return NULL;
 
-       return dev ? to_coresight_device(dev) : NULL;
+       return coresight_find_enabled_sink(source);
 }
 
 static int coresight_sink_by_id(struct device *dev, const void *data)
                goto out;
        }
 
-       /*
-        * Search for a valid sink for this session but don't reset the
-        * "enable_sink" flag in sysFS.  Users get to do that explicitly.
-        */
-       sink = coresight_get_enabled_sink(false);
+       sink = coresight_get_enabled_sink(csdev);
        if (!sink) {
                ret = -EINVAL;
                goto out;