if (!event_data)
                return NULL;
 
+       /*
+        * In theory nothing prevent tracers in a trace session from being
+        * associated with different sinks, nor having a sink per tracer.  But
+        * until we have HW with this kind of topology we need to assume tracers
+        * in a trace session are using the same sink.  Therefore go through
+        * the coresight bus and pick the first enabled sink.
+        *
+        * When operated from sysFS users are responsible to enable the sink
+        * while from perf, the perf tools will do it based on the choice made
+        * on the cmd line.  As such the "enable_sink" flag in sysFS is reset.
+        */
+       sink = coresight_get_enabled_sink(true);
+       if (!sink)
+               return NULL;
+
        INIT_WORK(&event_data->work, free_event_data);
 
        mask = &event_data->mask;
                 * list of devices from source to sink that can be
                 * referenced later when the path is actually needed.
                 */
-               event_data->path[cpu] = coresight_build_path(csdev);
+               event_data->path[cpu] = coresight_build_path(csdev, sink);
                if (IS_ERR(event_data->path[cpu]))
                        goto err;
        }
 
-       /*
-        * In theory nothing prevent tracers in a trace session from being
-        * associated with different sinks, nor having a sink per tracer.  But
-        * until we have HW with this kind of topology and a way to convey
-        * sink assignement from the perf cmd line we need to assume tracers
-        * in a trace session are using the same sink.  Therefore pick the sink
-        * found at the end of the first available path.
-        */
-       cpu = cpumask_first(mask);
-       /* Grab the sink at the end of the path */
-       sink = coresight_get_sink(event_data->path[cpu]);
-       if (!sink)
-               goto err;
-
        if (!sink_ops(sink)->alloc_buffer)
                goto err;
 
 
        return csdev;
 }
 
+static int coresight_enabled_sink(struct device *dev, void *data)
+{
+       bool *reset = data;
+       struct coresight_device *csdev = to_coresight_device(dev);
+
+       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;
+
+               return 1;
+       }
+
+       return 0;
+}
+
+/**
+ * coresight_get_enabled_sink - returns the first enabled sink found on the bus
+ * @deactivate:        Whether the 'enable_sink' flag should be reset
+ *
+ * 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.
+ */
+struct coresight_device *coresight_get_enabled_sink(bool deactivate)
+{
+       struct device *dev = NULL;
+
+       dev = bus_find_device(&coresight_bustype, NULL, &deactivate,
+                             coresight_enabled_sink);
+
+       return dev ? to_coresight_device(dev) : NULL;
+}
+
 /**
  * _coresight_build_path - recursively build a path from a @csdev to a sink.
  * @csdev:     The device to start from.
  * last one.
  */
 static int _coresight_build_path(struct coresight_device *csdev,
+                                struct coresight_device *sink,
                                 struct list_head *path)
 {
        int i;
        struct coresight_node *node;
 
        /* An activated sink has been found.  Enqueue the element */
-       if ((csdev->type == CORESIGHT_DEV_TYPE_SINK ||
-            csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) && csdev->activated)
+       if (csdev == sink)
                goto out;
 
        /* Not a sink - recursively explore each port found on this element */
        for (i = 0; i < csdev->nr_outport; i++) {
                struct coresight_device *child_dev = csdev->conns[i].child_dev;
 
-               if (child_dev && _coresight_build_path(child_dev, path) == 0) {
+               if (child_dev &&
+                   _coresight_build_path(child_dev, sink, path) == 0) {
                        found = true;
                        break;
                }
        return 0;
 }
 
-struct list_head *coresight_build_path(struct coresight_device *csdev)
+struct list_head *coresight_build_path(struct coresight_device *source,
+                                      struct coresight_device *sink)
 {
        struct list_head *path;
        int rc;
 
+       if (!sink)
+               return ERR_PTR(-EINVAL);
+
        path = kzalloc(sizeof(struct list_head), GFP_KERNEL);
        if (!path)
                return ERR_PTR(-ENOMEM);
 
        INIT_LIST_HEAD(path);
 
-       rc = _coresight_build_path(csdev, path);
+       rc = _coresight_build_path(source, sink, path);
        if (rc) {
                kfree(path);
                return ERR_PTR(rc);
 int coresight_enable(struct coresight_device *csdev)
 {
        int cpu, ret = 0;
+       struct coresight_device *sink;
        struct list_head *path;
 
        mutex_lock(&coresight_mutex);
        if (csdev->enable)
                goto out;
 
-       path = coresight_build_path(csdev);
+       /*
+        * 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);
+       if (!sink) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       path = coresight_build_path(csdev, sink);
        if (IS_ERR(path)) {
                pr_err("building path(s) failed\n");
                ret = PTR_ERR(path);