diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index 206f17826399..7b485fc2ed19 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -388,6 +388,7 @@ int coresight_enable_source(struct coresight_device *csdev, enum cs_mode mode,
 				return ret;
 		}
 		csdev->enable = true;
+		csdev->mode = mode;
 	}
 
 	atomic_inc(&csdev->refcnt);
@@ -446,18 +447,26 @@ static void coresight_disable_helpers(struct coresight_device *csdev)
  *  the device if there are no users left.
  *
  *  @csdev: The coresight device to disable
+ *  @mode: How the coresight device is being used, perf mode or sysfs mode.
  *  @data: Opaque data to pass on to the disable function of the source device.
  *         For example in perf mode this is a pointer to the struct perf_event.
  *
  *  Returns true if the device has been disabled.
  */
-bool coresight_disable_source(struct coresight_device *csdev, void *data)
+bool coresight_disable_source(struct coresight_device *csdev, enum cs_mode mode,
+			      void *data)
 {
+	if (csdev->mode && csdev->mode != mode) {
+		dev_err(&csdev->dev, "Someone is already using the tracer\n");
+		return false;
+	}
+
 	if (atomic_dec_return(&csdev->refcnt) == 0) {
 		if (source_ops(csdev)->disable)
 			source_ops(csdev)->disable(csdev, data);
 		coresight_disable_helpers(csdev);
 		csdev->enable = false;
+		csdev->mode = CS_MODE_DISABLED;
 	}
 	return !csdev->enable;
 }
@@ -1117,6 +1126,11 @@ int coresight_enable(struct coresight_device *csdev)
 	if (ret)
 		goto out;
 
+	if (csdev->mode == CS_MODE_PERF) {
+		ret = -EBUSY;
+		goto out;
+	}
+
 	if (csdev->enable) {
 		/*
 		 * There could be multiple applications driving the software
@@ -1202,7 +1216,7 @@ void coresight_disable(struct coresight_device *csdev)
 	if (ret)
 		goto out;
 
-	if (!csdev->enable || !coresight_disable_source(csdev, NULL))
+	if (!csdev->enable || !coresight_disable_source(csdev, CS_MODE_SYSFS, NULL))
 		goto out;
 
 	switch (csdev->subtype.source_subtype) {
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index 5ca6278baff4..015aea9f2b22 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -459,6 +459,10 @@ static void etm_event_start(struct perf_event *event, int flags)
 	if (WARN_ON(ctxt->event_data))
 		goto fail;
 
+	/* Sysfs is already using the tracer */
+	if (csdev->mode == CS_MODE_SYSFS)
+		goto fail;
+
 	/*
 	 * Deal with the ring buffer API and get a handle on the
 	 * session's information.
@@ -587,7 +591,7 @@ static void etm_event_stop(struct perf_event *event, int mode)
 		return;
 
 	/* stop tracer */
-	coresight_disable_source(csdev, event);
+	coresight_disable_source(csdev, CS_MODE_PERF, event);
 
 	/* tell the core */
 	event->hw.state = PERF_HES_STOPPED;
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index 767076e07970..1f8b512ba5ac 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -233,6 +233,7 @@ void coresight_set_percpu_sink(int cpu, struct coresight_device *csdev);
 struct coresight_device *coresight_get_percpu_sink(int cpu);
 int coresight_enable_source(struct coresight_device *csdev, enum cs_mode mode,
 			    void *data);
-bool coresight_disable_source(struct coresight_device *csdev, void *data);
+bool coresight_disable_source(struct coresight_device *csdev, enum cs_mode mode,
+			      void *data);
 
 #endif
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index a269fffaf991..acbbedb9abf3 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -216,6 +216,12 @@ struct coresight_sysfs_link {
 	const char *target_name;
 };
 
+enum cs_mode {
+	CS_MODE_DISABLED,
+	CS_MODE_SYSFS,
+	CS_MODE_PERF,
+};
+
 /**
  * struct coresight_device - representation of a device as used by the framework
  * @pdata:	Platform data with device connections associated to this device.
@@ -228,6 +234,7 @@ struct coresight_sysfs_link {
  * @refcnt:	keep track of what is in use.
  * @orphan:	true if the component has connections that haven't been linked.
  * @enable:	'true' if component is currently part of an active path.
+ * @mode:	This tracer's mode, i.e sysFS, Perf or disabled.
  * @activated:	'true' only if a _sink_ has been activated.  A sink can be
  *		activated but not yet enabled.  Enabling for a _sink_
  *		happens when a source has been selected and a path is enabled
@@ -252,6 +259,7 @@ struct coresight_device {
 	atomic_t refcnt;
 	bool orphan;
 	bool enable;	/* true only if configured as part of a path */
+	enum cs_mode mode;
 	/* sink specific fields */
 	bool activated;	/* true only if a sink is part of a path */
 	struct dev_ext_attribute *ea;
@@ -290,12 +298,6 @@ static struct coresight_dev_list (var) = {				\
 
 #define to_coresight_device(d) container_of(d, struct coresight_device, dev)
 
-enum cs_mode {
-	CS_MODE_DISABLED,
-	CS_MODE_SYSFS,
-	CS_MODE_PERF,
-};
-
 #define source_ops(csdev)	csdev->ops->source_ops
 #define sink_ops(csdev)		csdev->ops->sink_ops
 #define link_ops(csdev)		csdev->ops->link_ops
