devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v9 0/6] Coresight: Add Coresight TMC Control Unit driver
@ 2025-01-24  7:25 Jie Gan
  2025-01-24  7:25 ` [PATCH v9 1/6] Coresight: Add support for new APB clock name Jie Gan
                   ` (5 more replies)
  0 siblings, 6 replies; 24+ messages in thread
From: Jie Gan @ 2025-01-24  7:25 UTC (permalink / raw)
  To: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
	Maxime Coquelin, Alexandre Torgue, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio
  Cc: Tingwei Zhang, Jinlong Mao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32

The Coresight TMC Control Unit(CTCU) device hosts miscellaneous configuration
registers to control various features related to TMC ETR device.

The CTCU device works as a helper device physically connected to the TMC ETR device.
---------------------------------------------------------
             |ETR0|             |ETR1|
              . \                 / .
              .  \               /  .
              .   \             /   .
              .    \           /    .
---------------------------------------------------
ETR0ATID0-ETR0ATID3     CTCU    ETR1ATID0-ETR1ATID3
---------------------------------------------------
Each ETR has four ATID registers with 128 bits long in total.
e.g. ETR0ATID0-ETR0ATID3 registers are used by ETR0 device.

Based on the trace id which is programed in CTCU ATID register of
specific ETR, trace data with that trace id can get into ETR's buffer
while other trace data gets ignored. The number of CTCU ATID registers
depends on the number of defined TMC ETR devices. For example, two TMC
ETR devices need eight ATID registers. ETR0 with ETR0ATID0-ETR0ATID3
and ETR1 with ETR1ATID0-ETRATID3.

The significant challenge in enabling the data filter function is how
to collect the trace ID of the source device. The introduction of
trace_id callback function addresses this challenge. The callback function
collects trace ID of the device and return it back. The trace ID will be
stored in the structure called coresight_path and transmitted to helper
and sink devices.

The coresight_path structure is created to address how to transmit
parameters needs by coresight_enable_path/coresight_disbale_path
functions.

Here is the definition of the struct coresight_path:
/**
 * struct coresight_path - data needed by enable/disable path
 * @handle:             perf aux handle for ETM.
 * @path:               path from source to sink.
 * @trace_id:           trace_id of the whole path.
 */
struct coresight_path {
        struct perf_output_handle       *handle;
        struct list_head                *path;
        u8                              trace_id;
};

The atid_offset mentioned before is the offset to ATID register in CTCU
device.

Enabling the source device will configure one bit in the ATID register based
on its trace ID.
Disabling the source devices will reset the bit in the AITD register
based on its trace ID.

Useage:
Enable:
STM device with trace ID 5 and ETR0 is activated.
Bitmap before the enablement:
ETR0ATID0:
31..................543210
==========================
0000000000000000000000...0
==========================

Bitmap after the enablement:
31..................543210
==========================
0000000000000...0000100000
==========================

The bit 5 of the ETR0ATID0 register is configured to 1 when enabling the
STM device.

Disable:
STM device with trace ID 5 and ETR0 is activated.
Bitmap before the disablement:
ETR0ATID0:
31................6543210
=========================
000000000010111...0100000
=========================

Bitmap after the disablement
ETR0ATID0:
31................6543210
=========================
000000000010111...0000000
=========================

The bit 5 of the ETR0ATID0 register is reset to 0 when disabling the STM
device.

Changes in V2:
1. Rename the device to Coresight Control Unit.
2. Introduce the trace_id function pointer to address the challeng how to
   properly collect the trace ID of the device.
3. Introduce a new way to define the qcom,ccu-atid-offset property in
device tree.
4. Disabling the filter function blocked on acquiring the ATID-offset,
   which will be addressed in a separate patch once it’s ready.
Link to V1 - https://lore.kernel.org/lkml/20240618072726.3767974-1-quic_jiegan@quicinc.com/T/#t

Changes in V3:
1. Rename the device to Coresight TMC Control Unit(CTCU).
2. Introduce a new way to define the platform related configs. The new
   structure, qcom_ctcu_config, is used to store configurations specific
   to a platform. Each platform should have its own qcom_ctcu_config structure.
3. In perf mode, the ETM devices allocate their trace IDs using the
   perf_sink_id_map. In sysfs mode, the ETM devices allocate their trace
   IDs using the id_map_default.
4. Considering the scenario where both ETR devices might be enabled simultaneously
   with multiple sources, retrieving and using trace IDs instead of id_map is more effective
   for the CTCU device in sysfs mode. For example, We can configure one ETR as sink for high
   throughput trace data like ETM and another ETR for low throughput trace data like STM.
   In this case, STM data won’t be flushed out by ETM data quickly. However, if we use id_map to
   manage the trace IDs, we need to create a separate id_map for each ETR device. Addtionally, We
   would need to iterate through the entire id_map for each configuration.
5. Add support for apb's clock name "apb". If the function fails to obtain the clock with
   the name "apb_pclk", it will attempt to acquire the clock with the name "apb".
Link to V2 - https://lore.kernel.org/linux-arm-msm/20240705090049.1656986-1-quic_jiegan@quicinc.com/T/#t

Changes in V4:
1. Add TMC description in binding file.
2. Restrict the number of ports for the CTCU device to a range of 0 to 1 in the binding file,
   because the maximum number of CTCU devices is 2 for existing projects.
Link to V3 - https://lore.kernel.org/linux-arm-kernel/20240812024141.2867655-1-quic_jiegan@quicinc.com/

Changes in V5:
1. Fix the format issue for description paragrah in dt binding file.
2. Previous discussion for why use "in-ports" property instead of "ports".
Link to V4 - https://lore.kernel.org/linux-arm-msm/20240828012706.543605-1-quic_jiegan@quicinc.com/

Changes in V6:
1. Collected reviewed-by tag from Rob for dt-binding patch.
2. Rebased on tag next-20241008.
3. Dropped all depends-on tags.
Link to V5 - https://lore.kernel.org/linux-arm-msm/20240909033458.3118238-1-quic_jiegan@quicinc.com/

Changes in V7:
1. Rebased on tag next-20241204.
2. Fix format issue for dts patch.
   - Padding the address part to 8 digits
Link to V6 - https://lore.kernel.org/linux-arm-msm/20241009112503.1851585-1-quic_jiegan@quicinc.com/

Changes in V8:
1. Rebased on tag next-20241220.
2. Use raw_spinlock_t instead of spinlock_t.
3. Remove redundant codes in CTCU driver:
   - Eliminate unnecessary parameter validations.
   - Correct log level when an error occurs.
   - Optimize codes.
4. Correct the subject prefix for DT patch.
5. Collected reviewed-by tag from Konrad Dybcib for DT patch.
Link to V7 - https://lore.kernel.org/all/20241210031545.3468561-1-quic_jiegan@quicinc.com/

Changes in V9:
1. Rebased on tag next-20250113.
2. Separate the previous trace_id patch (patch 2/5 Coresight: Add trace_id function to
   retrieving the trace ID) into two patches.
3. Introduce a new struct coresight_path instead of cs_sink_data which was
   created in previous version. The coresight_path will be initialized
   and constructed in coresight_build_path function and released by
   coresight_release_path function.
   Detail of the struct coresight_path is shown below:
/**
 * struct coresight_path - data needed by enable/disable path
 * @handle:             perf aux handle for ETM.
 * @path:               path from source to sink.
 * @trace_id:           trace_id of the whole path.
 */
struct coresight_path {
        struct perf_output_handle       *handle;
        struct list_head                *path;
        u8                              trace_id;
};

4. Introduce an array of atomic in CTCU driver to represent the refcnt or each
   enabled trace_id for each sink. The reason is there is a scenario that more
   than one TPDM device physically connected to the same TPDA device has
   been enabled. The CTCU driver must verify the refcnt before resetting the
   bit of the atid register according to the trace_id of the TPDA device.
5. Remove redundant codes in CTCU driver.
6. Add reviewed-by tag to the commit message for APB clock path(patch
   1/5).
Link to V8 - https://lore.kernel.org/all/20241226011022.1477160-1-quic_jiegan@quicinc.com/

Jie Gan (6):
  Coresight: Add support for new APB clock name
  Coresight: Add trace_id function to retrieving the trace ID
  Coresight: Introduce a new struct coresight_path
  dt-bindings: arm: Add Coresight TMC Control Unit hardware
  Coresight: Add Coresight TMC Control Unit driver
  arm64: dts: qcom: sa8775p: Add CTCU and ETR nodes

 .../bindings/arm/qcom,coresight-ctcu.yaml     |  84 ++++++
 arch/arm64/boot/dts/qcom/sa8775p.dtsi         | 153 ++++++++++
 drivers/hwtracing/coresight/Kconfig           |  12 +
 drivers/hwtracing/coresight/Makefile          |   1 +
 drivers/hwtracing/coresight/coresight-core.c  |  87 ++++--
 drivers/hwtracing/coresight/coresight-ctcu.c  | 276 ++++++++++++++++++
 drivers/hwtracing/coresight/coresight-ctcu.h  |  30 ++
 drivers/hwtracing/coresight/coresight-dummy.c |  13 +
 drivers/hwtracing/coresight/coresight-etb10.c |   3 +-
 .../hwtracing/coresight/coresight-etm-perf.c  |  52 ++--
 .../hwtracing/coresight/coresight-etm-perf.h  |   2 +-
 .../coresight/coresight-etm3x-core.c          |  29 ++
 .../coresight/coresight-etm4x-core.c          |  28 ++
 drivers/hwtracing/coresight/coresight-priv.h  |  21 +-
 drivers/hwtracing/coresight/coresight-stm.c   |  13 +
 drivers/hwtracing/coresight/coresight-sysfs.c |  32 +-
 .../hwtracing/coresight/coresight-tmc-etf.c   |   3 +-
 .../hwtracing/coresight/coresight-tmc-etr.c   |   6 +-
 drivers/hwtracing/coresight/coresight-tpda.c  |  12 +
 drivers/hwtracing/coresight/coresight-trbe.c  |   4 +-
 drivers/hwtracing/coresight/ultrasoc-smb.c    |   3 +-
 include/linux/coresight.h                     |  15 +-
 22 files changed, 800 insertions(+), 79 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml
 create mode 100644 drivers/hwtracing/coresight/coresight-ctcu.c
 create mode 100644 drivers/hwtracing/coresight/coresight-ctcu.h

-- 
2.34.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v9 1/6] Coresight: Add support for new APB clock name
  2025-01-24  7:25 [PATCH v9 0/6] Coresight: Add Coresight TMC Control Unit driver Jie Gan
@ 2025-01-24  7:25 ` Jie Gan
  2025-01-24  7:25 ` [PATCH v9 2/6] Coresight: Add trace_id function to retrieving the trace ID Jie Gan
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 24+ messages in thread
From: Jie Gan @ 2025-01-24  7:25 UTC (permalink / raw)
  To: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
	Maxime Coquelin, Alexandre Torgue, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio
  Cc: Tingwei Zhang, Jinlong Mao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32

Add support for new APB clock-name. If the function fails
to obtain the clock with the name "apb_pclk", it will
attempt to acquire the clock with the name "apb".

Reviewed-by: James Clark <james.clark@linaro.org>
Signed-off-by: Jie Gan <quic_jiegan@quicinc.com>
---
 include/linux/coresight.h | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 17276965ff1d..157c4bd009a1 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -459,8 +459,11 @@ static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
 	int ret;
 
 	pclk = clk_get(dev, "apb_pclk");
-	if (IS_ERR(pclk))
-		return NULL;
+	if (IS_ERR(pclk)) {
+		pclk = clk_get(dev, "apb");
+		if (IS_ERR(pclk))
+			return NULL;
+	}
 
 	ret = clk_prepare_enable(pclk);
 	if (ret) {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v9 2/6] Coresight: Add trace_id function to retrieving the trace ID
  2025-01-24  7:25 [PATCH v9 0/6] Coresight: Add Coresight TMC Control Unit driver Jie Gan
  2025-01-24  7:25 ` [PATCH v9 1/6] Coresight: Add support for new APB clock name Jie Gan
@ 2025-01-24  7:25 ` Jie Gan
  2025-01-24  7:25 ` [PATCH v9 3/6] Coresight: Introduce a new struct coresight_path Jie Gan
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 24+ messages in thread
From: Jie Gan @ 2025-01-24  7:25 UTC (permalink / raw)
  To: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
	Maxime Coquelin, Alexandre Torgue, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio
  Cc: Tingwei Zhang, Jinlong Mao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32

Add 'trace_id' function pointer in ops. It's responsible for
retrieving the device's trace ID.

Signed-off-by: Jie Gan <quic_jiegan@quicinc.com>
---
 drivers/hwtracing/coresight/coresight-dummy.c | 13 +++++++++
 .../coresight/coresight-etm3x-core.c          | 29 +++++++++++++++++++
 .../coresight/coresight-etm4x-core.c          | 28 ++++++++++++++++++
 drivers/hwtracing/coresight/coresight-stm.c   | 13 +++++++++
 drivers/hwtracing/coresight/coresight-tpda.c  | 12 ++++++++
 include/linux/coresight.h                     |  5 ++++
 6 files changed, 100 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-dummy.c b/drivers/hwtracing/coresight/coresight-dummy.c
index 9be53be8964b..dfcf24e9c49a 100644
--- a/drivers/hwtracing/coresight/coresight-dummy.c
+++ b/drivers/hwtracing/coresight/coresight-dummy.c
@@ -41,6 +41,18 @@ static void dummy_source_disable(struct coresight_device *csdev,
 	dev_dbg(csdev->dev.parent, "Dummy source disabled\n");
 }
 
+static int dummy_source_trace_id(struct coresight_device *csdev, enum cs_mode mode,
+				 struct coresight_trace_id_map *id_map)
+{
+	struct dummy_drvdata *drvdata;
+
+	if (csdev == NULL)
+		return -EINVAL;
+
+	drvdata = dev_get_drvdata(csdev->dev.parent);
+	return drvdata->traceid;
+}
+
 static int dummy_sink_enable(struct coresight_device *csdev, enum cs_mode mode,
 				void *data)
 {
@@ -59,6 +71,7 @@ static int dummy_sink_disable(struct coresight_device *csdev)
 static const struct coresight_ops_source dummy_source_ops = {
 	.enable	= dummy_source_enable,
 	.disable = dummy_source_disable,
+	.trace_id = dummy_source_trace_id,
 };
 
 static const struct coresight_ops dummy_source_cs_ops = {
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
index c103f4c70f5d..74c6a2ffd07a 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
@@ -697,10 +697,39 @@ static void etm_disable(struct coresight_device *csdev,
 		coresight_set_mode(csdev, CS_MODE_DISABLED);
 }
 
+static int etm_trace_id(struct coresight_device *csdev, enum cs_mode mode,
+			struct coresight_trace_id_map *id_map)
+{
+	struct etm_drvdata *drvdata;
+	int trace_id;
+
+	if (csdev == NULL)
+		return -EINVAL;
+
+	drvdata = dev_get_drvdata(csdev->dev.parent);
+	switch (mode) {
+	case CS_MODE_SYSFS:
+		trace_id = etm_read_alloc_trace_id(drvdata);
+		break;
+	case CS_MODE_PERF:
+		trace_id = coresight_trace_id_read_cpu_id_map(drvdata->cpu, id_map);
+		if (IS_VALID_CS_TRACE_ID(trace_id))
+			drvdata->traceid = (u8)trace_id;
+		break;
+	default:
+		trace_id = -EINVAL;
+		break;
+	}
+
+	return trace_id;
+}
+
+
 static const struct coresight_ops_source etm_source_ops = {
 	.cpu_id		= etm_cpu_id,
 	.enable		= etm_enable,
 	.disable	= etm_disable,
+	.trace_id	= etm_trace_id,
 };
 
 static const struct coresight_ops etm_cs_ops = {
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 2c1a60577728..e8934a9df928 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -1060,10 +1060,38 @@ static void etm4_disable(struct coresight_device *csdev,
 		coresight_set_mode(csdev, CS_MODE_DISABLED);
 }
 
+static int etm4_trace_id(struct coresight_device *csdev, enum cs_mode mode,
+			 struct coresight_trace_id_map *id_map)
+{
+	struct etmv4_drvdata *drvdata;
+	int trace_id;
+
+	if (csdev == NULL)
+		return -EINVAL;
+
+	drvdata = dev_get_drvdata(csdev->dev.parent);
+	switch (mode) {
+	case CS_MODE_SYSFS:
+		trace_id = etm4_read_alloc_trace_id(drvdata);
+		break;
+	case CS_MODE_PERF:
+		trace_id = coresight_trace_id_read_cpu_id_map(drvdata->cpu, id_map);
+		if (IS_VALID_CS_TRACE_ID(trace_id))
+			drvdata->trcid = (u8)trace_id;
+		break;
+	default:
+		trace_id = -EINVAL;
+		break;
+	}
+
+	return trace_id;
+}
+
 static const struct coresight_ops_source etm4_source_ops = {
 	.cpu_id		= etm4_cpu_id,
 	.enable		= etm4_enable,
 	.disable	= etm4_disable,
+	.trace_id	= etm4_trace_id,
 };
 
 static const struct coresight_ops etm4_cs_ops = {
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index b581a30a1cd9..13efd5c2e0c4 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -281,9 +281,22 @@ static void stm_disable(struct coresight_device *csdev,
 	}
 }
 
+static int stm_trace_id(struct coresight_device *csdev, enum cs_mode mode,
+			struct coresight_trace_id_map *id_map)
+{
+	struct stm_drvdata *drvdata;
+
+	if (csdev == NULL)
+		return -EINVAL;
+
+	drvdata = dev_get_drvdata(csdev->dev.parent);
+	return drvdata->traceid;
+}
+
 static const struct coresight_ops_source stm_source_ops = {
 	.enable		= stm_enable,
 	.disable	= stm_disable,
+	.trace_id	= stm_trace_id,
 };
 
 static const struct coresight_ops stm_cs_ops = {
diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
index 189a4abc2561..3632c1791c96 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.c
+++ b/drivers/hwtracing/coresight/coresight-tpda.c
@@ -241,9 +241,21 @@ static void tpda_disable(struct coresight_device *csdev,
 	dev_dbg(drvdata->dev, "TPDA inport %d disabled\n", in->dest_port);
 }
 
+static int tpda_trace_id(struct coresight_device *csdev)
+{
+	struct tpda_drvdata *drvdata;
+
+	if (csdev == NULL)
+		return -EINVAL;
+
+	drvdata = dev_get_drvdata(csdev->dev.parent);
+	return drvdata->atid;
+}
+
 static const struct coresight_ops_link tpda_link_ops = {
 	.enable		= tpda_enable,
 	.disable	= tpda_disable,
+	.trace_id	= tpda_trace_id,
 };
 
 static const struct coresight_ops tpda_cs_ops = {
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 157c4bd009a1..82fbcc70a21c 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -368,6 +368,7 @@ struct coresight_ops_sink {
  * Operations available for links.
  * @enable:	enables flow between iport and oport.
  * @disable:	disables flow between iport and oport.
+ * @trace_id:	Collect the traceid.
  */
 struct coresight_ops_link {
 	int (*enable)(struct coresight_device *csdev,
@@ -376,6 +377,7 @@ struct coresight_ops_link {
 	void (*disable)(struct coresight_device *csdev,
 			struct coresight_connection *in,
 			struct coresight_connection *out);
+	int (*trace_id)(struct coresight_device *csdev);
 };
 
 /**
@@ -385,6 +387,7 @@ struct coresight_ops_link {
  *		is associated to.
  * @enable:	enables tracing for a source.
  * @disable:	disables tracing for a source.
+ * @trace_id:	collect the traceid.
  */
 struct coresight_ops_source {
 	int (*cpu_id)(struct coresight_device *csdev);
@@ -392,6 +395,8 @@ struct coresight_ops_source {
 		      enum cs_mode mode, struct coresight_trace_id_map *id_map);
 	void (*disable)(struct coresight_device *csdev,
 			struct perf_event *event);
+	int (*trace_id)(struct coresight_device *csdev, enum cs_mode mode,
+			struct coresight_trace_id_map *id_map);
 };
 
 /**
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v9 3/6] Coresight: Introduce a new struct coresight_path
  2025-01-24  7:25 [PATCH v9 0/6] Coresight: Add Coresight TMC Control Unit driver Jie Gan
  2025-01-24  7:25 ` [PATCH v9 1/6] Coresight: Add support for new APB clock name Jie Gan
  2025-01-24  7:25 ` [PATCH v9 2/6] Coresight: Add trace_id function to retrieving the trace ID Jie Gan
@ 2025-01-24  7:25 ` Jie Gan
  2025-01-28 11:54   ` James Clark
  2025-01-31 16:43   ` [PATCH v9 3/6] Coresight: Introduce a new struct coresight_path James Clark
  2025-01-24  7:25 ` [PATCH v9 4/6] dt-bindings: arm: Add Coresight TMC Control Unit hardware Jie Gan
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 24+ messages in thread
From: Jie Gan @ 2025-01-24  7:25 UTC (permalink / raw)
  To: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
	Maxime Coquelin, Alexandre Torgue, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio
  Cc: Tingwei Zhang, Jinlong Mao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32

Add 'struct coresight_path' to store the data that is needed by
coresight_enable_path/coresight_disable_path. The structure
will be transmitted to the helper and sink device to enable
related funcationalities.

Signed-off-by: Jie Gan <quic_jiegan@quicinc.com>
---
 drivers/hwtracing/coresight/coresight-core.c  | 87 ++++++++++++++-----
 drivers/hwtracing/coresight/coresight-etb10.c |  3 +-
 .../hwtracing/coresight/coresight-etm-perf.c  | 52 ++++++-----
 .../hwtracing/coresight/coresight-etm-perf.h  |  2 +-
 drivers/hwtracing/coresight/coresight-priv.h  | 21 +++--
 drivers/hwtracing/coresight/coresight-sysfs.c | 32 +++----
 .../hwtracing/coresight/coresight-tmc-etf.c   |  3 +-
 .../hwtracing/coresight/coresight-tmc-etr.c   |  6 +-
 drivers/hwtracing/coresight/coresight-trbe.c  |  4 +-
 drivers/hwtracing/coresight/ultrasoc-smb.c    |  3 +-
 10 files changed, 137 insertions(+), 76 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index 0a9380350fb5..11d5d5320b1a 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -23,6 +23,7 @@
 #include "coresight-etm-perf.h"
 #include "coresight-priv.h"
 #include "coresight-syscfg.h"
+#include "coresight-trace-id.h"
 
 /*
  * Mutex used to lock all sysfs enable and disable actions and loading and
@@ -331,12 +332,12 @@ static int coresight_enable_helper(struct coresight_device *csdev,
 	return helper_ops(csdev)->enable(csdev, mode, data);
 }
 
-static void coresight_disable_helper(struct coresight_device *csdev)
+static void coresight_disable_helper(struct coresight_device *csdev, void *data)
 {
-	helper_ops(csdev)->disable(csdev, NULL);
+	helper_ops(csdev)->disable(csdev, data);
 }
 
-static void coresight_disable_helpers(struct coresight_device *csdev)
+static void coresight_disable_helpers(struct coresight_device *csdev, void *data)
 {
 	int i;
 	struct coresight_device *helper;
@@ -344,7 +345,7 @@ static void coresight_disable_helpers(struct coresight_device *csdev)
 	for (i = 0; i < csdev->pdata->nr_outconns; ++i) {
 		helper = csdev->pdata->out_conns[i]->dest_dev;
 		if (helper && coresight_is_helper(helper))
-			coresight_disable_helper(helper);
+			coresight_disable_helper(helper, data);
 	}
 }
 
@@ -361,7 +362,7 @@ static void coresight_disable_helpers(struct coresight_device *csdev)
 void coresight_disable_source(struct coresight_device *csdev, void *data)
 {
 	source_ops(csdev)->disable(csdev, data);
-	coresight_disable_helpers(csdev);
+	coresight_disable_helpers(csdev, NULL);
 }
 EXPORT_SYMBOL_GPL(coresight_disable_source);
 
@@ -370,11 +371,12 @@ EXPORT_SYMBOL_GPL(coresight_disable_source);
  * @nd in the list. If @nd is NULL, all the components, except the SOURCE are
  * disabled.
  */
-static void coresight_disable_path_from(struct list_head *path,
+static void coresight_disable_path_from(struct coresight_path *cs_path,
 					struct coresight_node *nd)
 {
 	u32 type;
 	struct coresight_device *csdev, *parent, *child;
+	struct list_head *path = cs_path->path;
 
 	if (!nd)
 		nd = list_first_entry(path, struct coresight_node, link);
@@ -417,13 +419,13 @@ static void coresight_disable_path_from(struct list_head *path,
 		}
 
 		/* Disable all helpers adjacent along the path last */
-		coresight_disable_helpers(csdev);
+		coresight_disable_helpers(csdev, cs_path);
 	}
 }
 
-void coresight_disable_path(struct list_head *path)
+void coresight_disable_path(struct coresight_path *cs_path)
 {
-	coresight_disable_path_from(path, NULL);
+	coresight_disable_path_from(cs_path, NULL);
 }
 EXPORT_SYMBOL_GPL(coresight_disable_path);
 
@@ -446,14 +448,14 @@ static int coresight_enable_helpers(struct coresight_device *csdev,
 	return 0;
 }
 
-int coresight_enable_path(struct list_head *path, enum cs_mode mode,
-			  void *sink_data)
+int coresight_enable_path(struct coresight_path *cs_path, enum cs_mode mode)
 {
 	int ret = 0;
 	u32 type;
 	struct coresight_node *nd;
 	struct coresight_device *csdev, *parent, *child;
 	struct coresight_device *source;
+	struct list_head *path = cs_path->path;
 
 	source = coresight_get_source(path);
 	list_for_each_entry_reverse(nd, path, link) {
@@ -461,7 +463,7 @@ int coresight_enable_path(struct list_head *path, enum cs_mode mode,
 		type = csdev->type;
 
 		/* Enable all helpers adjacent to the path first */
-		ret = coresight_enable_helpers(csdev, mode, sink_data);
+		ret = coresight_enable_helpers(csdev, mode, cs_path);
 		if (ret)
 			goto err;
 		/*
@@ -477,7 +479,7 @@ int coresight_enable_path(struct list_head *path, enum cs_mode mode,
 
 		switch (type) {
 		case CORESIGHT_DEV_TYPE_SINK:
-			ret = coresight_enable_sink(csdev, mode, sink_data);
+			ret = coresight_enable_sink(csdev, mode, cs_path);
 			/*
 			 * Sink is the first component turned on. If we
 			 * failed to enable the sink, there are no components
@@ -505,7 +507,7 @@ int coresight_enable_path(struct list_head *path, enum cs_mode mode,
 out:
 	return ret;
 err:
-	coresight_disable_path_from(path, nd);
+	coresight_disable_path_from(cs_path, nd);
 	goto out;
 }
 
@@ -668,11 +670,12 @@ static void coresight_drop_device(struct coresight_device *csdev)
 static int _coresight_build_path(struct coresight_device *csdev,
 				 struct coresight_device *source,
 				 struct coresight_device *sink,
-				 struct list_head *path)
+				 struct coresight_path *cs_path)
 {
 	int i, ret;
 	bool found = false;
 	struct coresight_node *node;
+	struct list_head *path = cs_path->path;
 
 	/* The sink has been found.  Enqueue the element */
 	if (csdev == sink)
@@ -680,12 +683,21 @@ static int _coresight_build_path(struct coresight_device *csdev,
 
 	if (coresight_is_percpu_source(csdev) && coresight_is_percpu_sink(sink) &&
 	    sink == per_cpu(csdev_sink, source_ops(csdev)->cpu_id(csdev))) {
-		if (_coresight_build_path(sink, source, sink, path) == 0) {
+		if (_coresight_build_path(sink, source, sink, cs_path) == 0) {
 			found = true;
 			goto out;
 		}
 	}
 
+	/* Attempt to read the trace_id from TPDA device */
+	if (!IS_VALID_CS_TRACE_ID(cs_path->trace_id) &&
+	    (csdev->type == CORESIGHT_DEV_TYPE_LINK) &&
+	    (link_ops(csdev)->trace_id != NULL)) {
+		ret = link_ops(csdev)->trace_id(csdev);
+		if (IS_VALID_CS_TRACE_ID(ret))
+			cs_path->trace_id = ret;
+	}
+
 	/* Not a sink - recursively explore each port found on this element */
 	for (i = 0; i < csdev->pdata->nr_outconns; i++) {
 		struct coresight_device *child_dev;
@@ -696,7 +708,7 @@ static int _coresight_build_path(struct coresight_device *csdev,
 			continue;
 
 		if (child_dev &&
-		    _coresight_build_path(child_dev, source, sink, path) == 0) {
+		    _coresight_build_path(child_dev, source, sink, cs_path) == 0) {
 			found = true;
 			break;
 		}
@@ -726,28 +738,53 @@ static int _coresight_build_path(struct coresight_device *csdev,
 	return 0;
 }
 
-struct list_head *coresight_build_path(struct coresight_device *source,
+struct coresight_path *coresight_build_path(struct coresight_device *source,
 				       struct coresight_device *sink)
 {
+	struct coresight_path *cs_path;
 	struct list_head *path;
 	int rc;
 
 	if (!sink)
 		return ERR_PTR(-EINVAL);
 
+	cs_path = kzalloc(sizeof(struct coresight_path), GFP_KERNEL);
+	if (!cs_path)
+		return ERR_PTR(-ENOMEM);
+
 	path = kzalloc(sizeof(struct list_head), GFP_KERNEL);
-	if (!path)
+	if (!path) {
+		kfree(cs_path);
 		return ERR_PTR(-ENOMEM);
+	}
 
 	INIT_LIST_HEAD(path);
+	cs_path->path = path;
+	/*
+	 * Since not all source devices have a defined trace_id function,
+	 * make sure to check for it before use.
+	 *
+	 * Assert the mode is CS_MODE_SYSFS, the trace_id will be assigned
+	 * again later if the mode is CS_MODE_PERF.
+	 */
+	if (source_ops(source)->trace_id != NULL) {
+		rc = source_ops(source)->trace_id(source, CS_MODE_SYSFS, NULL);
+		if(IS_VALID_CS_TRACE_ID(rc))
+			cs_path->trace_id = rc;
+		else 
+			cs_path->trace_id = 0;
+	}
+	else
+		cs_path->trace_id = 0;
 
-	rc = _coresight_build_path(source, source, sink, path);
+	rc = _coresight_build_path(source, source, sink, cs_path);
 	if (rc) {
 		kfree(path);
+		kfree(cs_path);
 		return ERR_PTR(rc);
 	}
 
-	return path;
+	return cs_path;
 }
 
 /**
@@ -757,12 +794,12 @@ struct list_head *coresight_build_path(struct coresight_device *source,
  * Go through all the elements of a path and 1) removed it from the list and
  * 2) free the memory allocated for each node.
  */
-void coresight_release_path(struct list_head *path)
+void coresight_release_path(struct coresight_path *cs_path)
 {
 	struct coresight_device *csdev;
 	struct coresight_node *nd, *next;
 
-	list_for_each_entry_safe(nd, next, path, link) {
+	list_for_each_entry_safe(nd, next, cs_path->path, link) {
 		csdev = nd->csdev;
 
 		coresight_drop_device(csdev);
@@ -770,7 +807,9 @@ void coresight_release_path(struct list_head *path)
 		kfree(nd);
 	}
 
-	kfree(path);
+	cs_path->handle = NULL;
+	kfree(cs_path->path);
+	kfree(cs_path);
 }
 
 /* return true if the device is a suitable type for a default sink */
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index aea9ac9c4bd0..05430d8931d1 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -173,7 +173,8 @@ static int etb_enable_perf(struct coresight_device *csdev, void *data)
 	pid_t pid;
 	unsigned long flags;
 	struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-	struct perf_output_handle *handle = data;
+	struct coresight_path *cs_path = (struct coresight_path *)data;
+	struct perf_output_handle *handle = cs_path->handle;
 	struct cs_buffers *buf = etm_perf_sink_config(handle);
 
 	spin_lock_irqsave(&drvdata->spinlock, flags);
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index ad6a8f4b70b6..b6765abb0a26 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -136,13 +136,13 @@ static const struct attribute_group *etm_pmu_attr_groups[] = {
 	NULL,
 };
 
-static inline struct list_head **
+static inline struct coresight_path **
 etm_event_cpu_path_ptr(struct etm_event_data *data, int cpu)
 {
-	return per_cpu_ptr(data->path, cpu);
+	return per_cpu_ptr(data->cs_path, cpu);
 }
 
-static inline struct list_head *
+static inline struct coresight_path *
 etm_event_cpu_path(struct etm_event_data *data, int cpu)
 {
 	return *etm_event_cpu_path_ptr(data, cpu);
@@ -197,6 +197,7 @@ static void free_sink_buffer(struct etm_event_data *event_data)
 	int cpu;
 	cpumask_t *mask = &event_data->mask;
 	struct coresight_device *sink;
+	struct coresight_path *cs_path;
 
 	if (!event_data->snk_config)
 		return;
@@ -205,7 +206,8 @@ static void free_sink_buffer(struct etm_event_data *event_data)
 		return;
 
 	cpu = cpumask_first(mask);
-	sink = coresight_get_sink(etm_event_cpu_path(event_data, cpu));
+	cs_path = etm_event_cpu_path(event_data, cpu);
+	sink = coresight_get_sink(cs_path->path);
 	sink_ops(sink)->free_buffer(event_data->snk_config);
 }
 
@@ -226,11 +228,11 @@ static void free_event_data(struct work_struct *work)
 		cscfg_deactivate_config(event_data->cfg_hash);
 
 	for_each_cpu(cpu, mask) {
-		struct list_head **ppath;
+		struct coresight_path **ppath;
 
 		ppath = etm_event_cpu_path_ptr(event_data, cpu);
 		if (!(IS_ERR_OR_NULL(*ppath))) {
-			struct coresight_device *sink = coresight_get_sink(*ppath);
+			struct coresight_device *sink = coresight_get_sink((*ppath)->path);
 
 			/*
 			 * Mark perf event as done for trace id allocator, but don't call
@@ -247,7 +249,7 @@ static void free_event_data(struct work_struct *work)
 		*ppath = NULL;
 	}
 
-	free_percpu(event_data->path);
+	free_percpu(event_data->cs_path);
 	kfree(event_data);
 }
 
@@ -276,9 +278,9 @@ static void *alloc_event_data(int cpu)
 	 * unused memory when dealing with single CPU trace scenarios is small
 	 * compared to the cost of searching through an optimized array.
 	 */
-	event_data->path = alloc_percpu(struct list_head *);
+	event_data->cs_path = alloc_percpu(struct coresight_path *);
 
-	if (!event_data->path) {
+	if (!event_data->cs_path) {
 		kfree(event_data);
 		return NULL;
 	}
@@ -352,7 +354,7 @@ static void *etm_setup_aux(struct perf_event *event, void **pages,
 	 * CPUs, we can handle it and fail the session.
 	 */
 	for_each_cpu(cpu, mask) {
-		struct list_head *path;
+		struct coresight_path *cs_path;
 		struct coresight_device *csdev;
 
 		csdev = per_cpu(csdev_src, cpu);
@@ -400,8 +402,8 @@ static void *etm_setup_aux(struct perf_event *event, void **pages,
 		 * list of devices from source to sink that can be
 		 * referenced later when the path is actually needed.
 		 */
-		path = coresight_build_path(csdev, sink);
-		if (IS_ERR(path)) {
+		cs_path = coresight_build_path(csdev, sink);
+		if (IS_ERR(cs_path)) {
 			cpumask_clear_cpu(cpu, mask);
 			continue;
 		}
@@ -410,12 +412,13 @@ static void *etm_setup_aux(struct perf_event *event, void **pages,
 		trace_id = coresight_trace_id_get_cpu_id_map(cpu, &sink->perf_sink_id_map);
 		if (!IS_VALID_CS_TRACE_ID(trace_id)) {
 			cpumask_clear_cpu(cpu, mask);
-			coresight_release_path(path);
+			coresight_release_path(cs_path);
 			continue;
 		}
 
 		coresight_trace_id_perf_start(&sink->perf_sink_id_map);
-		*etm_event_cpu_path_ptr(event_data, cpu) = path;
+		cs_path->trace_id = trace_id;
+		*etm_event_cpu_path_ptr(event_data, cpu) = cs_path;
 	}
 
 	/* no sink found for any CPU - cannot trace */
@@ -458,7 +461,7 @@ static void etm_event_start(struct perf_event *event, int flags)
 	struct etm_ctxt *ctxt = this_cpu_ptr(&etm_ctxt);
 	struct perf_output_handle *handle = &ctxt->handle;
 	struct coresight_device *sink, *csdev = per_cpu(csdev_src, cpu);
-	struct list_head *path;
+	struct coresight_path *cs_path;
 	u64 hw_id;
 	u8 trace_id;
 
@@ -492,14 +495,15 @@ static void etm_event_start(struct perf_event *event, int flags)
 	if (!cpumask_test_cpu(cpu, &event_data->mask))
 		goto out;
 
-	path = etm_event_cpu_path(event_data, cpu);
+	cs_path = etm_event_cpu_path(event_data, cpu);
 	/* We need a sink, no need to continue without one */
-	sink = coresight_get_sink(path);
+	sink = coresight_get_sink(cs_path->path);
 	if (WARN_ON_ONCE(!sink))
 		goto fail_end_stop;
 
+	cs_path->handle = handle;
 	/* Nothing will happen without a path */
-	if (coresight_enable_path(path, CS_MODE_PERF, handle))
+	if (coresight_enable_path(cs_path, CS_MODE_PERF))
 		goto fail_end_stop;
 
 	/* Finally enable the tracer */
@@ -534,7 +538,7 @@ static void etm_event_start(struct perf_event *event, int flags)
 	return;
 
 fail_disable_path:
-	coresight_disable_path(path);
+	coresight_disable_path(cs_path);
 fail_end_stop:
 	/*
 	 * Check if the handle is still associated with the event,
@@ -558,7 +562,7 @@ static void etm_event_stop(struct perf_event *event, int mode)
 	struct etm_ctxt *ctxt = this_cpu_ptr(&etm_ctxt);
 	struct perf_output_handle *handle = &ctxt->handle;
 	struct etm_event_data *event_data;
-	struct list_head *path;
+	struct coresight_path *cs_path;
 
 	/*
 	 * If we still have access to the event_data via handle,
@@ -595,11 +599,11 @@ static void etm_event_stop(struct perf_event *event, int mode)
 	if (!csdev)
 		return;
 
-	path = etm_event_cpu_path(event_data, cpu);
-	if (!path)
+	cs_path = etm_event_cpu_path(event_data, cpu);
+	if (!cs_path)
 		return;
 
-	sink = coresight_get_sink(path);
+	sink = coresight_get_sink(cs_path->path);
 	if (!sink)
 		return;
 
@@ -643,7 +647,7 @@ static void etm_event_stop(struct perf_event *event, int mode)
 	}
 
 	/* Disabling the path make its elements available to other sessions */
-	coresight_disable_path(path);
+	coresight_disable_path(cs_path);
 }
 
 static int etm_event_add(struct perf_event *event, int mode)
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.h b/drivers/hwtracing/coresight/coresight-etm-perf.h
index 744531158d6b..ff92421bb97f 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.h
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.h
@@ -59,7 +59,7 @@ struct etm_event_data {
 	cpumask_t aux_hwid_done;
 	void *snk_config;
 	u32 cfg_hash;
-	struct list_head * __percpu *path;
+	struct coresight_path * __percpu *cs_path;
 };
 
 int etm_perf_symlink(struct coresight_device *csdev, bool link);
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index 76403530f33e..6ed7aef6cb43 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -108,6 +108,18 @@ struct cs_buffers {
 	void			**data_pages;
 };
 
+/**
+ * struct coresight_path - data needed by enable/disable path
+ * @handle:		perf aux handle for ETM.
+ * @path:		path from source to sink.
+ * @trace_id:		trace_id of the whole path.
+ */
+struct coresight_path {
+	struct perf_output_handle	*handle;
+	struct list_head		*path;
+	u8				trace_id;
+};
+
 static inline void coresight_insert_barrier_packet(void *buf)
 {
 	if (buf)
@@ -132,16 +144,15 @@ static inline void CS_UNLOCK(void __iomem *addr)
 	} while (0);
 }
 
-void coresight_disable_path(struct list_head *path);
-int coresight_enable_path(struct list_head *path, enum cs_mode mode,
-			  void *sink_data);
+void coresight_disable_path(struct coresight_path *cs_path);
+int coresight_enable_path(struct coresight_path *cs_path, enum cs_mode mode);
 struct coresight_device *coresight_get_sink(struct list_head *path);
 struct coresight_device *coresight_get_sink_by_id(u32 id);
 struct coresight_device *
 coresight_find_default_sink(struct coresight_device *csdev);
-struct list_head *coresight_build_path(struct coresight_device *csdev,
+struct coresight_path *coresight_build_path(struct coresight_device *csdev,
 				       struct coresight_device *sink);
-void coresight_release_path(struct list_head *path);
+void coresight_release_path(struct coresight_path *cs_path);
 int coresight_add_sysfs_link(struct coresight_sysfs_link *info);
 void coresight_remove_sysfs_link(struct coresight_sysfs_link *info);
 int coresight_create_conns_sysfs_group(struct coresight_device *csdev);
diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/hwtracing/coresight/coresight-sysfs.c
index a01c9e54e2ed..04e76cc1bfdf 100644
--- a/drivers/hwtracing/coresight/coresight-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-sysfs.c
@@ -22,7 +22,7 @@ static DEFINE_IDR(path_idr);
  * When operating Coresight drivers from the sysFS interface, only a single
  * path can exist from a tracer (associated to a CPU) to a sink.
  */
-static DEFINE_PER_CPU(struct list_head *, tracer_path);
+static DEFINE_PER_CPU(struct coresight_path *, tracer_path);
 
 ssize_t coresight_simple_show_pair(struct device *_dev,
 			      struct device_attribute *attr, char *buf)
@@ -167,7 +167,7 @@ int coresight_enable_sysfs(struct coresight_device *csdev)
 {
 	int cpu, ret = 0;
 	struct coresight_device *sink;
-	struct list_head *path;
+	struct coresight_path *cs_path;
 	enum coresight_dev_subtype_source subtype;
 	u32 hash;
 
@@ -202,14 +202,14 @@ int coresight_enable_sysfs(struct coresight_device *csdev)
 		goto out;
 	}
 
-	path = coresight_build_path(csdev, sink);
-	if (IS_ERR(path)) {
+	cs_path = coresight_build_path(csdev, sink);
+	if (IS_ERR(cs_path)) {
 		pr_err("building path(s) failed\n");
-		ret = PTR_ERR(path);
+		ret = PTR_ERR(cs_path);
 		goto out;
 	}
 
-	ret = coresight_enable_path(path, CS_MODE_SYSFS, NULL);
+	ret = coresight_enable_path(cs_path, CS_MODE_SYSFS);
 	if (ret)
 		goto err_path;
 
@@ -227,7 +227,7 @@ int coresight_enable_sysfs(struct coresight_device *csdev)
 		 * a per-cpu variable will do just fine.
 		 */
 		cpu = source_ops(csdev)->cpu_id(csdev);
-		per_cpu(tracer_path, cpu) = path;
+		per_cpu(tracer_path, cpu) = cs_path;
 		break;
 	case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE:
 	case CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM:
@@ -237,7 +237,7 @@ int coresight_enable_sysfs(struct coresight_device *csdev)
 		 * and map the ID to the pointer of the path.
 		 */
 		hash = hashlen_hash(hashlen_string(NULL, dev_name(&csdev->dev)));
-		ret = idr_alloc_u32(&path_idr, path, &hash, hash, GFP_KERNEL);
+		ret = idr_alloc_u32(&path_idr, cs_path, &hash, hash, GFP_KERNEL);
 		if (ret)
 			goto err_source;
 		break;
@@ -251,10 +251,10 @@ int coresight_enable_sysfs(struct coresight_device *csdev)
 	return ret;
 
 err_source:
-	coresight_disable_path(path);
+	coresight_disable_path(cs_path);
 
 err_path:
-	coresight_release_path(path);
+	coresight_release_path(cs_path);
 	goto out;
 }
 EXPORT_SYMBOL_GPL(coresight_enable_sysfs);
@@ -262,7 +262,7 @@ EXPORT_SYMBOL_GPL(coresight_enable_sysfs);
 void coresight_disable_sysfs(struct coresight_device *csdev)
 {
 	int cpu, ret;
-	struct list_head *path = NULL;
+	struct coresight_path *cs_path = NULL;
 	u32 hash;
 
 	mutex_lock(&coresight_mutex);
@@ -277,7 +277,7 @@ void coresight_disable_sysfs(struct coresight_device *csdev)
 	switch (csdev->subtype.source_subtype) {
 	case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC:
 		cpu = source_ops(csdev)->cpu_id(csdev);
-		path = per_cpu(tracer_path, cpu);
+		cs_path = per_cpu(tracer_path, cpu);
 		per_cpu(tracer_path, cpu) = NULL;
 		break;
 	case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE:
@@ -285,8 +285,8 @@ void coresight_disable_sysfs(struct coresight_device *csdev)
 	case CORESIGHT_DEV_SUBTYPE_SOURCE_OTHERS:
 		hash = hashlen_hash(hashlen_string(NULL, dev_name(&csdev->dev)));
 		/* Find the path by the hash. */
-		path = idr_find(&path_idr, hash);
-		if (path == NULL) {
+		cs_path = idr_find(&path_idr, hash);
+		if (cs_path == NULL) {
 			pr_err("Path is not found for %s\n", dev_name(&csdev->dev));
 			goto out;
 		}
@@ -297,8 +297,8 @@ void coresight_disable_sysfs(struct coresight_device *csdev)
 		break;
 	}
 
-	coresight_disable_path(path);
-	coresight_release_path(path);
+	coresight_disable_path(cs_path);
+	coresight_release_path(cs_path);
 
 out:
 	mutex_unlock(&coresight_mutex);
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index d4f641cd9de6..e6b07f917556 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -250,7 +250,8 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
 	pid_t pid;
 	unsigned long flags;
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-	struct perf_output_handle *handle = data;
+	struct coresight_path *cs_path= (struct coresight_path *)data;
+	struct perf_output_handle *handle = cs_path->handle;
 	struct cs_buffers *buf = etm_perf_sink_config(handle);
 
 	spin_lock_irqsave(&drvdata->spinlock, flags);
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index a48bb85d0e7f..82a872882e24 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1254,7 +1254,8 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
 struct etr_buf *tmc_etr_get_buffer(struct coresight_device *csdev,
 				   enum cs_mode mode, void *data)
 {
-	struct perf_output_handle *handle = data;
+	struct coresight_path *cs_path = (struct coresight_path *)data;
+	struct perf_output_handle *handle = cs_path->handle;
 	struct etr_perf_buffer *etr_perf;
 
 	switch (mode) {
@@ -1648,7 +1649,8 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
 	pid_t pid;
 	unsigned long flags;
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-	struct perf_output_handle *handle = data;
+	struct coresight_path *cs_path = (struct coresight_path *)data;
+	struct perf_output_handle *handle = cs_path->handle;
 	struct etr_perf_buffer *etr_perf = etm_perf_sink_config(handle);
 
 	spin_lock_irqsave(&drvdata->spinlock, flags);
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index fff67aac8418..f9a9b96cce13 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -22,6 +22,7 @@
 
 #include "coresight-self-hosted-trace.h"
 #include "coresight-trbe.h"
+#include "coresight-priv.h"
 
 #define PERF_IDX2OFF(idx, buf) ((idx) % ((buf)->nr_pages << PAGE_SHIFT))
 
@@ -1015,7 +1016,8 @@ static int arm_trbe_enable(struct coresight_device *csdev, enum cs_mode mode,
 {
 	struct trbe_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 	struct trbe_cpudata *cpudata = dev_get_drvdata(&csdev->dev);
-	struct perf_output_handle *handle = data;
+	struct coresight_path *cs_path = (struct coresight_path *)data;
+	struct perf_output_handle *handle = cs_path->handle;
 	struct trbe_buf *buf = etm_perf_sink_config(handle);
 
 	WARN_ON(cpudata->cpu != smp_processor_id());
diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/hwtracing/coresight/ultrasoc-smb.c
index dc3c9504dd7c..9be88394b3bb 100644
--- a/drivers/hwtracing/coresight/ultrasoc-smb.c
+++ b/drivers/hwtracing/coresight/ultrasoc-smb.c
@@ -216,7 +216,8 @@ static void smb_enable_sysfs(struct coresight_device *csdev)
 static int smb_enable_perf(struct coresight_device *csdev, void *data)
 {
 	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
-	struct perf_output_handle *handle = data;
+	struct coresight_path *cs_path = (struct coresight_path *)data;
+	struct perf_output_handle *handle = cs_path->handle;
 	struct cs_buffers *buf = etm_perf_sink_config(handle);
 	pid_t pid;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v9 4/6] dt-bindings: arm: Add Coresight TMC Control Unit hardware
  2025-01-24  7:25 [PATCH v9 0/6] Coresight: Add Coresight TMC Control Unit driver Jie Gan
                   ` (2 preceding siblings ...)
  2025-01-24  7:25 ` [PATCH v9 3/6] Coresight: Introduce a new struct coresight_path Jie Gan
@ 2025-01-24  7:25 ` Jie Gan
  2025-01-24  7:25 ` [PATCH v9 5/6] Coresight: Add Coresight TMC Control Unit driver Jie Gan
  2025-01-24  7:25 ` [PATCH v9 6/6] arm64: dts: qcom: sa8775p: Add CTCU and ETR nodes Jie Gan
  5 siblings, 0 replies; 24+ messages in thread
From: Jie Gan @ 2025-01-24  7:25 UTC (permalink / raw)
  To: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
	Maxime Coquelin, Alexandre Torgue, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio
  Cc: Tingwei Zhang, Jinlong Mao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32

Add binding file to specify how to define a Coresight TMC
Control Unit device in device tree.

It is responsible for controlling the data filter function
based on the source device's Trace ID for TMC ETR device.
The trace data with that Trace id can get into ETR's buffer
while other trace data gets ignored.

Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Jie Gan <quic_jiegan@quicinc.com>
---
 .../bindings/arm/qcom,coresight-ctcu.yaml     | 84 +++++++++++++++++++
 1 file changed, 84 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml

diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml
new file mode 100644
index 000000000000..843b52eaf872
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml
@@ -0,0 +1,84 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/qcom,coresight-ctcu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: CoreSight TMC Control Unit
+
+maintainers:
+  - Yuanfang Zhang <quic_yuanfang@quicinc.com>
+  - Mao Jinlong <quic_jinlmao@quicinc.com>
+  - Jie Gan <quic_jiegan@quicinc.com>
+
+description: |
+  The Trace Memory Controller(TMC) is used for Embedded Trace Buffer(ETB),
+  Embedded Trace FIFO(ETF) and Embedded Trace Router(ETR) configurations.
+  The configuration mode (ETB, ETF, ETR) is discovered at boot time when
+  the device is probed.
+
+  The Coresight TMC Control unit controls various Coresight behaviors.
+  It works as a helper device when connected to TMC ETR device.
+  It is responsible for controlling the data filter function based on
+  the source device's Trace ID for TMC ETR device. The trace data with
+  that Trace id can get into ETR's buffer while other trace data gets
+  ignored.
+
+properties:
+  compatible:
+    enum:
+      - qcom,sa8775p-ctcu
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: apb
+
+  in-ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    patternProperties:
+      '^port(@[0-1])?$':
+        description: Input connections from CoreSight Trace bus
+        $ref: /schemas/graph.yaml#/properties/port
+
+required:
+  - compatible
+  - reg
+  - in-ports
+
+additionalProperties: false
+
+examples:
+  - |
+    ctcu@1001000 {
+        compatible = "qcom,sa8775p-ctcu";
+        reg = <0x1001000 0x1000>;
+
+        clocks = <&aoss_qmp>;
+        clock-names = "apb";
+
+        in-ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port@0 {
+                reg = <0>;
+                ctcu_in_port0: endpoint {
+                    remote-endpoint = <&etr0_out_port>;
+                };
+            };
+
+            port@1 {
+                reg = <1>;
+                ctcu_in_port1: endpoint {
+                    remote-endpoint = <&etr1_out_port>;
+                };
+            };
+        };
+    };
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v9 5/6] Coresight: Add Coresight TMC Control Unit driver
  2025-01-24  7:25 [PATCH v9 0/6] Coresight: Add Coresight TMC Control Unit driver Jie Gan
                   ` (3 preceding siblings ...)
  2025-01-24  7:25 ` [PATCH v9 4/6] dt-bindings: arm: Add Coresight TMC Control Unit hardware Jie Gan
@ 2025-01-24  7:25 ` Jie Gan
  2025-01-28 11:55   ` James Clark
  2025-01-24  7:25 ` [PATCH v9 6/6] arm64: dts: qcom: sa8775p: Add CTCU and ETR nodes Jie Gan
  5 siblings, 1 reply; 24+ messages in thread
From: Jie Gan @ 2025-01-24  7:25 UTC (permalink / raw)
  To: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
	Maxime Coquelin, Alexandre Torgue, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio
  Cc: Tingwei Zhang, Jinlong Mao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32

The Coresight TMC Control Unit hosts miscellaneous configuration registers
which control various features related to TMC ETR sink.

Based on the trace ID, which is programmed in the related CTCU ATID
register of a specific ETR, trace data with that trace ID gets into
the ETR buffer, while other trace data gets dropped.

Enabling source device sets one bit of the ATID register based on
source device's trace ID.
Disabling source device resets the bit according to the source
device's trace ID.

Signed-off-by: Jie Gan <quic_jiegan@quicinc.com>
---
 drivers/hwtracing/coresight/Kconfig          |  12 +
 drivers/hwtracing/coresight/Makefile         |   1 +
 drivers/hwtracing/coresight/coresight-ctcu.c | 276 +++++++++++++++++++
 drivers/hwtracing/coresight/coresight-ctcu.h |  30 ++
 include/linux/coresight.h                    |   3 +-
 5 files changed, 321 insertions(+), 1 deletion(-)
 create mode 100644 drivers/hwtracing/coresight/coresight-ctcu.c
 create mode 100644 drivers/hwtracing/coresight/coresight-ctcu.h

diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
index 06f0a7594169..ecd7086a5b83 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -133,6 +133,18 @@ config CORESIGHT_STM
 	  To compile this driver as a module, choose M here: the
 	  module will be called coresight-stm.
 
+config CORESIGHT_CTCU
+	tristate "CoreSight TMC Control Unit driver"
+	depends on CORESIGHT_LINK_AND_SINK_TMC
+	help
+	  This driver provides support for CoreSight TMC Control Unit
+	  that hosts miscellaneous configuration registers. This is
+	  primarily used for controlling the behaviors of the TMC
+	  ETR device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called coresight-ctcu.
+
 config CORESIGHT_CPU_DEBUG
 	tristate "CoreSight CPU Debug driver"
 	depends on ARM || ARM64
diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index 4ba478211b31..1b7869910a12 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -51,3 +51,4 @@ coresight-cti-y := coresight-cti-core.o	coresight-cti-platform.o \
 		   coresight-cti-sysfs.o
 obj-$(CONFIG_ULTRASOC_SMB) += ultrasoc-smb.o
 obj-$(CONFIG_CORESIGHT_DUMMY) += coresight-dummy.o
+obj-$(CONFIG_CORESIGHT_CTCU) += coresight-ctcu.o
diff --git a/drivers/hwtracing/coresight/coresight-ctcu.c b/drivers/hwtracing/coresight/coresight-ctcu.c
new file mode 100644
index 000000000000..1b7413dcf325
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-ctcu.c
@@ -0,0 +1,276 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/coresight.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "coresight-ctcu.h"
+#include "coresight-priv.h"
+
+DEFINE_CORESIGHT_DEVLIST(ctcu_devs, "ctcu");
+
+#define ctcu_writel(drvdata, val, offset)	__raw_writel((val), drvdata->base + offset)
+#define ctcu_readl(drvdata, offset)		__raw_readl(drvdata->base + offset)
+
+/*
+ * The TMC Coresight Control Unit uses four ATID registers to control the data
+ * filter function based on the trace ID for each TMC ETR sink. The length of
+ * each ATID register is 32 bits. Therefore, the ETR has a related field in
+ * CTCU that is 128 bits long. Each trace ID is represented by one bit in that
+ * filed.
+ * e.g. ETR0ATID0 layout, set bit 5 for traceid 5
+ *                                           bit5
+ * ------------------------------------------------------
+ * |   |28|   |24|   |20|   |16|   |12|   |8|  1|4|   |0|
+ * ------------------------------------------------------
+ *
+ * e.g. ETR0:
+ * 127                     0 from ATID_offset for ETR0ATID0
+ * -------------------------
+ * |ATID3|ATID2|ATID1|ATID0|
+ */
+#define CTCU_ATID_REG_OFFSET(traceid, atid_offset) \
+		((traceid / 32) * 4 + atid_offset)
+
+#define CTCU_ATID_REG_BIT(traceid)	(traceid % 32)
+#define CTCU_ATID_REG_SIZE		0x10
+
+struct ctcu_atid_config {
+	const u32 atid_offset;
+	const u32 port_num;
+};
+
+struct ctcu_config {
+	const struct ctcu_atid_config *atid_config;
+	int num_atid_config;
+};
+
+static const struct ctcu_atid_config sa8775p_atid_cfgs[] = {
+	{0xf8,  0},
+	{0x108, 1},
+};
+
+static const struct ctcu_config sa8775p_cfgs = {
+	.atid_config		= sa8775p_atid_cfgs,
+	.num_atid_config	= ARRAY_SIZE(sa8775p_atid_cfgs),
+};
+
+/*
+ * __ctcu_set_etr_traceid: Set bit in the ATID register based on trace ID when enable is true.
+ * Reset the bit of the ATID register based on trace ID when enable is false.
+ *
+ * @csdev:	coresight_device struct related to the device
+ * @traceid:	trace ID of the source tracer.
+ * @enable:	True for set bit and false for reset bit.
+ *
+ * Returns 0 indicates success. Non-zero result means failure.
+ */
+static int __ctcu_set_etr_traceid(struct coresight_device *csdev, u8 traceid, int port_num,
+				  bool enable)
+{
+	struct ctcu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+	u32 atid_offset, reg_offset, val;
+	int bit;
+
+	atid_offset = drvdata->atid_offset[port_num];
+	if (atid_offset == 0)
+		return -EINVAL;
+
+	bit = CTCU_ATID_REG_BIT(traceid);
+	reg_offset = CTCU_ATID_REG_OFFSET(traceid, atid_offset);
+	if (reg_offset - atid_offset > CTCU_ATID_REG_SIZE) {
+		return -EINVAL;
+	}
+
+	guard(raw_spinlock_irqsave)(&drvdata->spin_lock);
+	CS_UNLOCK(drvdata->base);
+	val = ctcu_readl(drvdata, reg_offset);
+	if (enable)
+		val = val | BIT(bit);
+	else
+		val = val & ~BIT(bit);
+
+	ctcu_writel(drvdata, val, reg_offset);
+	CS_LOCK(drvdata->base);
+
+	return 0;
+}
+
+static int ctcu_get_active_port(struct coresight_device *sink, struct coresight_device *helper)
+{
+	int i;
+
+	for (i = 0; i < sink->pdata->nr_outconns; ++i) {
+		if (sink->pdata->out_conns[i]->dest_dev)
+			return sink->pdata->out_conns[i]->dest_port;
+	}
+
+	return -EINVAL;
+}
+
+/*
+ * ctcu_set_etr_traceid: Retrieve the ATID offset and trace ID.
+ *
+ * Returns 0 indicates success. None-zero result means failure.
+ */
+static int ctcu_set_etr_traceid(struct coresight_device *csdev, struct coresight_path *cs_path,
+				bool enable)
+{
+	struct coresight_device *sink = coresight_get_sink(cs_path->path);
+	struct ctcu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+	u8 trace_id = cs_path->trace_id;
+	int port_num;
+
+	if ((sink == NULL) || !IS_VALID_CS_TRACE_ID(trace_id) || IS_ERR_OR_NULL(drvdata)) {
+		dev_err(&csdev->dev, "Invalid parameters\n");
+		return -EINVAL;
+	}
+
+	port_num = ctcu_get_active_port(sink, csdev);
+	if (port_num < 0)
+		return -EINVAL;
+
+	/*
+	 * Skip the disable session if more than one TPDM device that
+	 * connected to the same TPDA device has been enabled.
+	 */
+	if (enable)
+		atomic_inc(&drvdata->traceid_refcnt[port_num][trace_id]);
+	else {
+		if (atomic_dec_return(&drvdata->traceid_refcnt[port_num][trace_id]) > 0) {
+			dev_dbg(&csdev->dev, "Skip the disable session\n");
+			return 0;
+		}
+	}
+
+	dev_dbg(&csdev->dev, "traceid is %d\n", cs_path->trace_id);
+
+	return __ctcu_set_etr_traceid(csdev, trace_id, port_num, enable);
+}
+
+static int ctcu_enable(struct coresight_device *csdev, enum cs_mode mode,
+		       void *data)
+{
+	struct coresight_path *cs_path = (struct coresight_path *)data;
+
+	return ctcu_set_etr_traceid(csdev, cs_path, true);
+}
+
+static int ctcu_disable(struct coresight_device *csdev, void *data)
+{
+	struct coresight_path *cs_path = (struct coresight_path *)data;
+
+	return ctcu_set_etr_traceid(csdev, cs_path, false);
+}
+
+static const struct coresight_ops_helper ctcu_helper_ops = {
+	.enable = ctcu_enable,
+	.disable = ctcu_disable,
+};
+
+static const struct coresight_ops ctcu_ops = {
+	.helper_ops = &ctcu_helper_ops,
+};
+
+static int ctcu_probe(struct platform_device *pdev)
+{
+	int i;
+	void __iomem *base;
+	struct device *dev = &pdev->dev;
+	struct coresight_platform_data *pdata;
+	struct ctcu_drvdata *drvdata;
+	struct coresight_desc desc = { 0 };
+	const struct ctcu_config *cfgs;
+	const struct ctcu_atid_config *atid_cfg;
+
+	desc.name = coresight_alloc_device_name(&ctcu_devs, dev);
+	if (!desc.name)
+		return -ENOMEM;
+
+	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+
+	pdata = coresight_get_platform_data(dev);
+	if (IS_ERR(pdata))
+		return PTR_ERR(pdata);
+	dev->platform_data = pdata;
+
+	base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
+	if (!base)
+		return -ENOMEM;
+
+	drvdata->apb_clk = coresight_get_enable_apb_pclk(dev);
+	if (IS_ERR(drvdata->apb_clk))
+		return -ENODEV;
+
+	cfgs = of_device_get_match_data(dev);
+	if (cfgs) {
+		if (cfgs->num_atid_config <= ATID_MAX_NUM) {
+			for (i = 0; i < cfgs->num_atid_config; i++) {
+				atid_cfg = &cfgs->atid_config[i];
+				drvdata->atid_offset[i] = atid_cfg->atid_offset;
+			}
+		}
+	}
+
+	drvdata->base = base;
+	drvdata->dev = dev;
+	platform_set_drvdata(pdev, drvdata);
+
+	desc.type = CORESIGHT_DEV_TYPE_HELPER;
+	desc.subtype.helper_subtype = CORESIGHT_DEV_SUBTYPE_HELPER_CTCU;
+	desc.pdata = pdata;
+	desc.dev = dev;
+	desc.ops = &ctcu_ops;
+
+	drvdata->csdev = coresight_register(&desc);
+	if (IS_ERR(drvdata->csdev)) {
+		if (!IS_ERR_OR_NULL(drvdata->apb_clk))
+			clk_put(drvdata->apb_clk);
+
+		return PTR_ERR(drvdata->csdev);
+	}
+
+	return 0;
+}
+
+static void ctcu_remove(struct platform_device *pdev)
+{
+	struct ctcu_drvdata *drvdata = platform_get_drvdata(pdev);
+
+	coresight_unregister(drvdata->csdev);
+	if (!IS_ERR_OR_NULL(drvdata->apb_clk))
+		clk_put(drvdata->apb_clk);
+}
+
+static const struct of_device_id ctcu_match[] = {
+	{.compatible = "qcom,sa8775p-ctcu", .data = &sa8775p_cfgs},
+	{}
+};
+
+static struct platform_driver ctcu_driver = {
+	.probe          = ctcu_probe,
+	.remove         = ctcu_remove,
+	.driver         = {
+		.name   = "coresight-ctcu",
+		.of_match_table = ctcu_match,
+		.suppress_bind_attrs = true,
+	},
+};
+module_platform_driver(ctcu_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CoreSight TMC Control Unit driver");
diff --git a/drivers/hwtracing/coresight/coresight-ctcu.h b/drivers/hwtracing/coresight/coresight-ctcu.h
new file mode 100644
index 000000000000..9885cc7b2042
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-ctcu.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _CORESIGHT_CTCU_H
+#define _CORESIGHT_CTCU_H
+#include "coresight-trace-id.h"
+
+/* Maximum number of supported sink devices for a single CTCU in current projects. */
+#define ATID_MAX_NUM 	2
+
+struct ctcu_traceid_entry {
+	struct hlist_node       hlist;
+	atomic_t                refcnt[ATID_MAX_NUM];
+	u8                      trace_id;
+};
+
+struct ctcu_drvdata {
+	void __iomem		*base;
+	struct clk		*apb_clk;
+	phys_addr_t		pbase;
+	struct device		*dev;
+	struct coresight_device	*csdev;
+	raw_spinlock_t		spin_lock;
+	u32			atid_offset[ATID_MAX_NUM];
+	/* refcnt for each traceid of each sink */
+	atomic_t		traceid_refcnt[ATID_MAX_NUM][CORESIGHT_TRACE_ID_RES_TOP];
+};
+#endif
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 82fbcc70a21c..87f9baa7fefe 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -71,7 +71,8 @@ enum coresight_dev_subtype_source {
 
 enum coresight_dev_subtype_helper {
 	CORESIGHT_DEV_SUBTYPE_HELPER_CATU,
-	CORESIGHT_DEV_SUBTYPE_HELPER_ECT_CTI
+	CORESIGHT_DEV_SUBTYPE_HELPER_ECT_CTI,
+	CORESIGHT_DEV_SUBTYPE_HELPER_CTCU,
 };
 
 /**
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH v9 6/6] arm64: dts: qcom: sa8775p: Add CTCU and ETR nodes
  2025-01-24  7:25 [PATCH v9 0/6] Coresight: Add Coresight TMC Control Unit driver Jie Gan
                   ` (4 preceding siblings ...)
  2025-01-24  7:25 ` [PATCH v9 5/6] Coresight: Add Coresight TMC Control Unit driver Jie Gan
@ 2025-01-24  7:25 ` Jie Gan
  5 siblings, 0 replies; 24+ messages in thread
From: Jie Gan @ 2025-01-24  7:25 UTC (permalink / raw)
  To: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
	Maxime Coquelin, Alexandre Torgue, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio
  Cc: Tingwei Zhang, Jinlong Mao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32,
	Konrad Dybcio

Add CTCU and ETR nodes in DT to enable related functionalities.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Jie Gan <quic_jiegan@quicinc.com>
---
 arch/arm64/boot/dts/qcom/sa8775p.dtsi | 153 ++++++++++++++++++++++++++
 1 file changed, 153 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sa8775p.dtsi b/arch/arm64/boot/dts/qcom/sa8775p.dtsi
index 3394ae2d1300..31aa94d2a043 100644
--- a/arch/arm64/boot/dts/qcom/sa8775p.dtsi
+++ b/arch/arm64/boot/dts/qcom/sa8775p.dtsi
@@ -2429,6 +2429,35 @@ crypto: crypto@1dfa000 {
 			interconnect-names = "memory";
 		};
 
+		ctcu@4001000 {
+			compatible = "qcom,sa8775p-ctcu";
+			reg = <0x0 0x04001000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb";
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					ctcu_in0: endpoint {
+						remote-endpoint = <&etr0_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					ctcu_in1: endpoint {
+						remote-endpoint = <&etr1_out>;
+					};
+				};
+			};
+		};
+
 		stm: stm@4002000 {
 			compatible = "arm,coresight-stm", "arm,primecell";
 			reg = <0x0 0x4002000 0x0 0x1000>,
@@ -2633,6 +2662,122 @@ qdss_funnel_in1: endpoint {
 			};
 		};
 
+		replicator@4046000 {
+			compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+			reg = <0x0 0x04046000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				port {
+					qdss_rep_in: endpoint {
+						remote-endpoint = <&swao_rep_out0>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					qdss_rep_out0: endpoint {
+						remote-endpoint = <&etr_rep_in>;
+					};
+				};
+			};
+		};
+
+		tmc_etr: tmc@4048000 {
+			compatible = "arm,coresight-tmc", "arm,primecell";
+			reg = <0x0 0x04048000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			iommus = <&apps_smmu 0x04c0 0x00>;
+
+			arm,scatter-gather;
+
+			in-ports {
+				port {
+					etr0_in: endpoint {
+						remote-endpoint = <&etr_rep_out0>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					etr0_out: endpoint {
+						remote-endpoint = <&ctcu_in0>;
+					};
+				};
+			};
+		};
+
+		replicator@404e000 {
+			compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+			reg = <0x0 0x0404e000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				port {
+					etr_rep_in: endpoint {
+						remote-endpoint = <&qdss_rep_out0>;
+					};
+				};
+			};
+
+			out-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					etr_rep_out0: endpoint {
+						remote-endpoint = <&etr0_in>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					etr_rep_out1: endpoint {
+						remote-endpoint = <&etr1_in>;
+					};
+				};
+			};
+		};
+
+		tmc_etr1: tmc@404f000 {
+			compatible = "arm,coresight-tmc", "arm,primecell";
+			reg = <0x0 0x0404f000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			iommus = <&apps_smmu 0x04a0 0x40>;
+
+			arm,scatter-gather;
+			arm,buffer-size = <0x400000>;
+
+			in-ports {
+				port {
+					etr1_in: endpoint {
+						remote-endpoint = <&etr_rep_out1>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					etr1_out: endpoint {
+						remote-endpoint = <&ctcu_in1>;
+					};
+				};
+			};
+		};
+
 		funnel@4b04000 {
 			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
 			reg = <0x0 0x4b04000 0x0 0x1000>;
@@ -2708,6 +2853,14 @@ out-ports {
 				#address-cells = <1>;
 				#size-cells = <0>;
 
+				port@0 {
+					reg = <0>;
+
+					swao_rep_out0: endpoint {
+						remote-endpoint = <&qdss_rep_in>;
+					};
+				};
+
 				port@1 {
 					reg = <1>;
 					swao_rep_out1: endpoint {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH v9 3/6] Coresight: Introduce a new struct coresight_path
  2025-01-24  7:25 ` [PATCH v9 3/6] Coresight: Introduce a new struct coresight_path Jie Gan
@ 2025-01-28 11:54   ` James Clark
  2025-01-29  0:57     ` Jie Gan
  2025-01-31 16:43   ` [PATCH v9 3/6] Coresight: Introduce a new struct coresight_path James Clark
  1 sibling, 1 reply; 24+ messages in thread
From: James Clark @ 2025-01-28 11:54 UTC (permalink / raw)
  To: Jie Gan
  Cc: Tingwei Zhang, Jinlong Mao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32,
	Suzuki K Poulose, Mike Leach, Alexander Shishkin, Maxime Coquelin,
	Alexandre Torgue, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Konrad Dybcio



On 24/01/2025 7:25 am, Jie Gan wrote:
> Add 'struct coresight_path' to store the data that is needed by
> coresight_enable_path/coresight_disable_path. The structure
> will be transmitted to the helper and sink device to enable
> related funcationalities.
> 
> Signed-off-by: Jie Gan <quic_jiegan@quicinc.com>
> ---
>   drivers/hwtracing/coresight/coresight-core.c  | 87 ++++++++++++++-----
>   drivers/hwtracing/coresight/coresight-etb10.c |  3 +-
>   .../hwtracing/coresight/coresight-etm-perf.c  | 52 ++++++-----
>   .../hwtracing/coresight/coresight-etm-perf.h  |  2 +-
>   drivers/hwtracing/coresight/coresight-priv.h  | 21 +++--
>   drivers/hwtracing/coresight/coresight-sysfs.c | 32 +++----
>   .../hwtracing/coresight/coresight-tmc-etf.c   |  3 +-
>   .../hwtracing/coresight/coresight-tmc-etr.c   |  6 +-
>   drivers/hwtracing/coresight/coresight-trbe.c  |  4 +-
>   drivers/hwtracing/coresight/ultrasoc-smb.c    |  3 +-
>   10 files changed, 137 insertions(+), 76 deletions(-)
> 

[...]


>   	INIT_LIST_HEAD(path);
> +	cs_path->path = path;
> +	/*
> +	 * Since not all source devices have a defined trace_id function,
> +	 * make sure to check for it before use.
> +	 *
> +	 * Assert the mode is CS_MODE_SYSFS, the trace_id will be assigned
> +	 * again later if the mode is CS_MODE_PERF.
> +	 */
> +	if (source_ops(source)->trace_id != NULL) {
> +		rc = source_ops(source)->trace_id(source, CS_MODE_SYSFS, NULL);

I don't think we should do this. Doesn't this consume two trace IDs for 
each session? And I'm not even sure if it's released properly if it's 
overwritten.

It should be possible to consolidate the all the trace ID allocation to 
a single step when building the path, or another function that gets 
called just after the path is built. At the moment the ID can be 
allocated from about 5 different places and it's quite hard to 
understand, especially with these new changes. I have some of it coded 
up, let me finish it off and I can share it.

> +		if(IS_VALID_CS_TRACE_ID(rc))
> +			cs_path->trace_id = rc;
> +		else
> +			cs_path->trace_id = 0;
> +	}
> +	else
> +		cs_path->trace_id = 0;

[...]

> +/**
> + * struct coresight_path - data needed by enable/disable path
> + * @handle:		perf aux handle for ETM.
> + * @path:		path from source to sink.
> + * @trace_id:		trace_id of the whole path.
> + */
> +struct coresight_path {
> +	struct perf_output_handle	*handle;

This is only needed to avoid adding *handle to the enable function call 
signature, but having it here implies it needs to be stored. And then we 
need to manage the lifecycle of it by nulling it on deletion. All of 
this can be avoided by just adding handle to enable().

Unrelated to this patch, but I'm not sure why we were passing around 
void* for handle either. It just makes the code hard to read and implies 
some flexibility that doesn't exist. It's always "struct 
perf_output_handle", so we can change void* to that in the enable 
functions. I also have a patch for this that I'll share in a bit.

> +	struct list_head		*path;
> +	u8				trace_id;
> +};
> +
>   static inline void coresight_insert_barrier_packet(void *buf)
>   {
>   	if (buf)
> @@ -132,16 +144,15 @@ static inline void CS_UNLOCK(void __iomem *addr)
>   	} while (0);
>   }
>   
> -void coresight_disable_path(struct list_head *path);
> -int coresight_enable_path(struct list_head *path, enum cs_mode mode,
> -			  void *sink_data);
> +void coresight_disable_path(struct coresight_path *cs_path);
> +int coresight_enable_path(struct coresight_path *cs_path, enum cs_mode mode);
>   struct coresight_device *coresight_get_sink(struct list_head *path);

This needs to be exported otherwise the build fails because you use it 
in a module in another commit. I assume you are building as static?



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v9 5/6] Coresight: Add Coresight TMC Control Unit driver
  2025-01-24  7:25 ` [PATCH v9 5/6] Coresight: Add Coresight TMC Control Unit driver Jie Gan
@ 2025-01-28 11:55   ` James Clark
  2025-01-29  0:46     ` Jie Gan
  0 siblings, 1 reply; 24+ messages in thread
From: James Clark @ 2025-01-28 11:55 UTC (permalink / raw)
  To: Jie Gan
  Cc: Tingwei Zhang, Jinlong Mao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32,
	Suzuki K Poulose, Mike Leach, Alexander Shishkin, Maxime Coquelin,
	Alexandre Torgue, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Konrad Dybcio



On 24/01/2025 7:25 am, Jie Gan wrote:
> The Coresight TMC Control Unit hosts miscellaneous configuration registers
> which control various features related to TMC ETR sink.
> 
> Based on the trace ID, which is programmed in the related CTCU ATID
> register of a specific ETR, trace data with that trace ID gets into
> the ETR buffer, while other trace data gets dropped.
> 
> Enabling source device sets one bit of the ATID register based on
> source device's trace ID.
> Disabling source device resets the bit according to the source
> device's trace ID.
> 
> Signed-off-by: Jie Gan <quic_jiegan@quicinc.com>
> ---
>   drivers/hwtracing/coresight/Kconfig          |  12 +
>   drivers/hwtracing/coresight/Makefile         |   1 +
>   drivers/hwtracing/coresight/coresight-ctcu.c | 276 +++++++++++++++++++
>   drivers/hwtracing/coresight/coresight-ctcu.h |  30 ++
>   include/linux/coresight.h                    |   3 +-
>   5 files changed, 321 insertions(+), 1 deletion(-)
>   create mode 100644 drivers/hwtracing/coresight/coresight-ctcu.c
>   create mode 100644 drivers/hwtracing/coresight/coresight-ctcu.h
 >

[...]

> +/*
> + * ctcu_set_etr_traceid: Retrieve the ATID offset and trace ID.
> + *
> + * Returns 0 indicates success. None-zero result means failure.
> + */
> +static int ctcu_set_etr_traceid(struct coresight_device *csdev, struct coresight_path *cs_path,
> +				bool enable)
> +{
> +	struct coresight_device *sink = coresight_get_sink(cs_path->path);
> +	struct ctcu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> +	u8 trace_id = cs_path->trace_id;
> +	int port_num;
> +
> +	if ((sink == NULL) || !IS_VALID_CS_TRACE_ID(trace_id) || IS_ERR_OR_NULL(drvdata)) {
> +		dev_err(&csdev->dev, "Invalid parameters\n");
> +		return -EINVAL;
> +	}
> +
> +	port_num = ctcu_get_active_port(sink, csdev);
> +	if (port_num < 0)
> +		return -EINVAL;
> +
> +	/*
> +	 * Skip the disable session if more than one TPDM device that
> +	 * connected to the same TPDA device has been enabled.
> +	 */
> +	if (enable)
> +		atomic_inc(&drvdata->traceid_refcnt[port_num][trace_id]);
> +	else {
> +		if (atomic_dec_return(&drvdata->traceid_refcnt[port_num][trace_id]) > 0) {
> +			dev_dbg(&csdev->dev, "Skip the disable session\n");
> +			return 0;
> +		}
> +	}
> +
> +	dev_dbg(&csdev->dev, "traceid is %d\n", cs_path->trace_id);
> +
> +	return __ctcu_set_etr_traceid(csdev, trace_id, port_num, enable);

Hi Jie,

Using atomic_dec_return() here doesn't prevent __ctcu_set_etr_traceid() 
from running concurrent enable and disables. Once you pass the 
atomic_dec_return() a second call to enable it will mess it up.

I think you need a spinlock around the whole thing and then the 
refcounts don't need to be atomics.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v9 5/6] Coresight: Add Coresight TMC Control Unit driver
  2025-01-28 11:55   ` James Clark
@ 2025-01-29  0:46     ` Jie Gan
  2025-01-29 10:35       ` James Clark
  0 siblings, 1 reply; 24+ messages in thread
From: Jie Gan @ 2025-01-29  0:46 UTC (permalink / raw)
  To: James Clark
  Cc: Tingwei Zhang, Jinlong Mao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32,
	Suzuki K Poulose, Mike Leach, Alexander Shishkin, Maxime Coquelin,
	Alexandre Torgue, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Konrad Dybcio



On 1/28/2025 7:55 PM, James Clark wrote:
> 
> 
> On 24/01/2025 7:25 am, Jie Gan wrote:
>> The Coresight TMC Control Unit hosts miscellaneous configuration 
>> registers
>> which control various features related to TMC ETR sink.
>>
>> Based on the trace ID, which is programmed in the related CTCU ATID
>> register of a specific ETR, trace data with that trace ID gets into
>> the ETR buffer, while other trace data gets dropped.
>>
>> Enabling source device sets one bit of the ATID register based on
>> source device's trace ID.
>> Disabling source device resets the bit according to the source
>> device's trace ID.
>>
>> Signed-off-by: Jie Gan <quic_jiegan@quicinc.com>
>> ---
>>   drivers/hwtracing/coresight/Kconfig          |  12 +
>>   drivers/hwtracing/coresight/Makefile         |   1 +
>>   drivers/hwtracing/coresight/coresight-ctcu.c | 276 +++++++++++++++++++
>>   drivers/hwtracing/coresight/coresight-ctcu.h |  30 ++
>>   include/linux/coresight.h                    |   3 +-
>>   5 files changed, 321 insertions(+), 1 deletion(-)
>>   create mode 100644 drivers/hwtracing/coresight/coresight-ctcu.c
>>   create mode 100644 drivers/hwtracing/coresight/coresight-ctcu.h
>  >
> 
> [...]
> 
>> +/*
>> + * ctcu_set_etr_traceid: Retrieve the ATID offset and trace ID.
>> + *
>> + * Returns 0 indicates success. None-zero result means failure.
>> + */
>> +static int ctcu_set_etr_traceid(struct coresight_device *csdev, 
>> struct coresight_path *cs_path,
>> +                bool enable)
>> +{
>> +    struct coresight_device *sink = coresight_get_sink(cs_path->path);
>> +    struct ctcu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>> +    u8 trace_id = cs_path->trace_id;
>> +    int port_num;
>> +
>> +    if ((sink == NULL) || !IS_VALID_CS_TRACE_ID(trace_id) || 
>> IS_ERR_OR_NULL(drvdata)) {
>> +        dev_err(&csdev->dev, "Invalid parameters\n");
>> +        return -EINVAL;
>> +    }
>> +
>> +    port_num = ctcu_get_active_port(sink, csdev);
>> +    if (port_num < 0)
>> +        return -EINVAL;
>> +
>> +    /*
>> +     * Skip the disable session if more than one TPDM device that
>> +     * connected to the same TPDA device has been enabled.
>> +     */
>> +    if (enable)
>> +        atomic_inc(&drvdata->traceid_refcnt[port_num][trace_id]);
>> +    else {
>> +        if (atomic_dec_return(&drvdata->traceid_refcnt[port_num] 
>> [trace_id]) > 0) {
>> +            dev_dbg(&csdev->dev, "Skip the disable session\n");
>> +            return 0;
>> +        }
>> +    }
>> +
>> +    dev_dbg(&csdev->dev, "traceid is %d\n", cs_path->trace_id);
>> +
>> +    return __ctcu_set_etr_traceid(csdev, trace_id, port_num, enable);
> 
> Hi Jie,
> 
> Using atomic_dec_return() here doesn't prevent __ctcu_set_etr_traceid() 
> from running concurrent enable and disables. Once you pass the 
> atomic_dec_return() a second call to enable it will mess it up.
> 
> I think you need a spinlock around the whole thing and then the 
> refcounts don't need to be atomics.
> 
Hi, James
Thanks for comment. I may not fully tested my codes here. What I was 
thinking is there's no way the refcnt could become a negative number 
under current framework. So I just added spinlock in 
__ctcu_set_etr_traceid() to ensure concurrent sessions correctly 
manipulate the register.

As the trace_id related to the bit of the ATID register, I think the 
concurrent processes are working fine with spinlock around read/write 
register.

I may not fully got your point here. Please help me to correct it.

Thanks,
Jie



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v9 3/6] Coresight: Introduce a new struct coresight_path
  2025-01-28 11:54   ` James Clark
@ 2025-01-29  0:57     ` Jie Gan
  2025-01-31 16:36       ` [PATCH 0/3] coresight: Alloc trace ID after building the path James Clark
  0 siblings, 1 reply; 24+ messages in thread
From: Jie Gan @ 2025-01-29  0:57 UTC (permalink / raw)
  To: James Clark
  Cc: Tingwei Zhang, Jinlong Mao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32,
	Suzuki K Poulose, Mike Leach, Alexander Shishkin, Maxime Coquelin,
	Alexandre Torgue, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Konrad Dybcio



On 1/28/2025 7:54 PM, James Clark wrote:
> 
> 
> On 24/01/2025 7:25 am, Jie Gan wrote:
>> Add 'struct coresight_path' to store the data that is needed by
>> coresight_enable_path/coresight_disable_path. The structure
>> will be transmitted to the helper and sink device to enable
>> related funcationalities.
>>
>> Signed-off-by: Jie Gan <quic_jiegan@quicinc.com>
>> ---
>>   drivers/hwtracing/coresight/coresight-core.c  | 87 ++++++++++++++-----
>>   drivers/hwtracing/coresight/coresight-etb10.c |  3 +-
>>   .../hwtracing/coresight/coresight-etm-perf.c  | 52 ++++++-----
>>   .../hwtracing/coresight/coresight-etm-perf.h  |  2 +-
>>   drivers/hwtracing/coresight/coresight-priv.h  | 21 +++--
>>   drivers/hwtracing/coresight/coresight-sysfs.c | 32 +++----
>>   .../hwtracing/coresight/coresight-tmc-etf.c   |  3 +-
>>   .../hwtracing/coresight/coresight-tmc-etr.c   |  6 +-
>>   drivers/hwtracing/coresight/coresight-trbe.c  |  4 +-
>>   drivers/hwtracing/coresight/ultrasoc-smb.c    |  3 +-
>>   10 files changed, 137 insertions(+), 76 deletions(-)
>>
> 
> [...]
> 
> 
>>       INIT_LIST_HEAD(path);
>> +    cs_path->path = path;
>> +    /*
>> +     * Since not all source devices have a defined trace_id function,
>> +     * make sure to check for it before use.
>> +     *
>> +     * Assert the mode is CS_MODE_SYSFS, the trace_id will be assigned
>> +     * again later if the mode is CS_MODE_PERF.
>> +     */
>> +    if (source_ops(source)->trace_id != NULL) {
>> +        rc = source_ops(source)->trace_id(source, CS_MODE_SYSFS, NULL);
> 
> I don't think we should do this. Doesn't this consume two trace IDs for 
> each session? And I'm not even sure if it's released properly if it's 
> overwritten.
Yes, you are right, we may waste our trace ID here.
> 
> It should be possible to consolidate the all the trace ID allocation to 
> a single step when building the path, or another function that gets 
> called just after the path is built. At the moment the ID can be 
> allocated from about 5 different places and it's quite hard to 
> understand, especially with these new changes. I have some of it coded 
> up, let me finish it off and I can share it.
Waiting for your update. I am also looking forward to another solution.

> 
>> +        if(IS_VALID_CS_TRACE_ID(rc))
>> +            cs_path->trace_id = rc;
>> +        else
>> +            cs_path->trace_id = 0;
>> +    }
>> +    else
>> +        cs_path->trace_id = 0;
> 
> [...]
> 
>> +/**
>> + * struct coresight_path - data needed by enable/disable path
>> + * @handle:        perf aux handle for ETM.
>> + * @path:        path from source to sink.
>> + * @trace_id:        trace_id of the whole path.
>> + */
>> +struct coresight_path {
>> +    struct perf_output_handle    *handle;
> 
> This is only needed to avoid adding *handle to the enable function call 
> signature, but having it here implies it needs to be stored. And then we 
> need to manage the lifecycle of it by nulling it on deletion. All of 
> this can be avoided by just adding handle to enable().
> 
> Unrelated to this patch, but I'm not sure why we were passing around 
> void* for handle either. It just makes the code hard to read and implies 
> some flexibility that doesn't exist. It's always "struct 
> perf_output_handle", so we can change void* to that in the enable 
> functions. I also have a patch for this that I'll share in a bit.
> 
Thanks for support. I am totally agree with you. It's not related to the 
patch series and it looks like a hack here.

Waiting for your update.

>> +    struct list_head        *path;
>> +    u8                trace_id;
>> +};
>> +
>>   static inline void coresight_insert_barrier_packet(void *buf)
>>   {
>>       if (buf)
>> @@ -132,16 +144,15 @@ static inline void CS_UNLOCK(void __iomem *addr)
>>       } while (0);
>>   }
>> -void coresight_disable_path(struct list_head *path);
>> -int coresight_enable_path(struct list_head *path, enum cs_mode mode,
>> -              void *sink_data);
>> +void coresight_disable_path(struct coresight_path *cs_path);
>> +int coresight_enable_path(struct coresight_path *cs_path, enum 
>> cs_mode mode);
>>   struct coresight_device *coresight_get_sink(struct list_head *path);
> 
> This needs to be exported otherwise the build fails because you use it 
> in a module in another commit. I assume you are building as static?
> 
> 
Yes, you are right. I made a mistake here. I did not test it with build 
as module. Sorry about the mistake.

Thanks,
Jie



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v9 5/6] Coresight: Add Coresight TMC Control Unit driver
  2025-01-29  0:46     ` Jie Gan
@ 2025-01-29 10:35       ` James Clark
  2025-01-29 13:02         ` Jie Gan
  0 siblings, 1 reply; 24+ messages in thread
From: James Clark @ 2025-01-29 10:35 UTC (permalink / raw)
  To: Jie Gan
  Cc: Tingwei Zhang, Jinlong Mao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32,
	Suzuki K Poulose, Mike Leach, Alexander Shishkin, Maxime Coquelin,
	Alexandre Torgue, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Konrad Dybcio



On 29/01/2025 12:46 am, Jie Gan wrote:
> 
> 
> On 1/28/2025 7:55 PM, James Clark wrote:
>>
>>
>> On 24/01/2025 7:25 am, Jie Gan wrote:
>>> The Coresight TMC Control Unit hosts miscellaneous configuration 
>>> registers
>>> which control various features related to TMC ETR sink.
>>>
>>> Based on the trace ID, which is programmed in the related CTCU ATID
>>> register of a specific ETR, trace data with that trace ID gets into
>>> the ETR buffer, while other trace data gets dropped.
>>>
>>> Enabling source device sets one bit of the ATID register based on
>>> source device's trace ID.
>>> Disabling source device resets the bit according to the source
>>> device's trace ID.
>>>
>>> Signed-off-by: Jie Gan <quic_jiegan@quicinc.com>
>>> ---
>>>   drivers/hwtracing/coresight/Kconfig          |  12 +
>>>   drivers/hwtracing/coresight/Makefile         |   1 +
>>>   drivers/hwtracing/coresight/coresight-ctcu.c | 276 +++++++++++++++++++
>>>   drivers/hwtracing/coresight/coresight-ctcu.h |  30 ++
>>>   include/linux/coresight.h                    |   3 +-
>>>   5 files changed, 321 insertions(+), 1 deletion(-)
>>>   create mode 100644 drivers/hwtracing/coresight/coresight-ctcu.c
>>>   create mode 100644 drivers/hwtracing/coresight/coresight-ctcu.h
>>  >
>>
>> [...]
>>
>>> +/*
>>> + * ctcu_set_etr_traceid: Retrieve the ATID offset and trace ID.
>>> + *
>>> + * Returns 0 indicates success. None-zero result means failure.
>>> + */
>>> +static int ctcu_set_etr_traceid(struct coresight_device *csdev, 
>>> struct coresight_path *cs_path,
>>> +                bool enable)
>>> +{
>>> +    struct coresight_device *sink = coresight_get_sink(cs_path->path);
>>> +    struct ctcu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>>> +    u8 trace_id = cs_path->trace_id;
>>> +    int port_num;
>>> +
>>> +    if ((sink == NULL) || !IS_VALID_CS_TRACE_ID(trace_id) || 
>>> IS_ERR_OR_NULL(drvdata)) {
>>> +        dev_err(&csdev->dev, "Invalid parameters\n");
>>> +        return -EINVAL;
>>> +    }
>>> +
>>> +    port_num = ctcu_get_active_port(sink, csdev);
>>> +    if (port_num < 0)
>>> +        return -EINVAL;
>>> +
>>> +    /*
>>> +     * Skip the disable session if more than one TPDM device that
>>> +     * connected to the same TPDA device has been enabled.
>>> +     */
>>> +    if (enable)
>>> +        atomic_inc(&drvdata->traceid_refcnt[port_num][trace_id]);
>>> +    else {
>>> +        if (atomic_dec_return(&drvdata->traceid_refcnt[port_num] 
>>> [trace_id]) > 0) {
>>> +            dev_dbg(&csdev->dev, "Skip the disable session\n");
>>> +            return 0;
>>> +        }
>>> +    }
>>> +
>>> +    dev_dbg(&csdev->dev, "traceid is %d\n", cs_path->trace_id);
>>> +
>>> +    return __ctcu_set_etr_traceid(csdev, trace_id, port_num, enable);
>>
>> Hi Jie,
>>
>> Using atomic_dec_return() here doesn't prevent 
>> __ctcu_set_etr_traceid() from running concurrent enable and disables. 
>> Once you pass the atomic_dec_return() a second call to enable it will 
>> mess it up.
>>
>> I think you need a spinlock around the whole thing and then the 
>> refcounts don't need to be atomics.
>>
> Hi, James
> Thanks for comment. I may not fully tested my codes here. What I was 
> thinking is there's no way the refcnt could become a negative number 
> under current framework. So I just added spinlock in 
> __ctcu_set_etr_traceid() to ensure concurrent sessions correctly 
> manipulate the register.
> 
> As the trace_id related to the bit of the ATID register, I think the 
> concurrent processes are working fine with spinlock around read/write 
> register.
> 
> I may not fully got your point here. Please help me to correct it.
> 
> Thanks,
> Jie
> 
> 

No it can't become negative, but the refcount can be a different state 
to the one that was actually written:


   CPU0                             CPU1
   ----                             ----
   ctcu_set_etr_traceid(enable)
                                    ctcu_set_etr_traceid(disable)
   atomic_inc()
   recount == 1
                                    atomic_dec()
                                    recount == 0

                                    __ctcu_set_etr_traceid(disable)
                                    Lock and write disable state to
                                    device

   __ctcu_set_etr_traceid(enable)
   Lock and write enable state to
   device


As you can see this leaves the device in an enabled state but the 
refcount is 0.

This is also quite large if you use atomic types:

  /* refcnt for each traceid of each sink */
  atomic_t traceid_refcnt[ATID_MAX_NUM][CORESIGHT_TRACE_ID_RES_TOP];

Presumably you can't have the refcount for each ID be higher than the 
max number of TPDMs connected? If you make the locked area a bit wider 
you don't need atomic types and also solve the above problem. So you 
could do u8, or DECLARE_BITMAP() and bitmap_read() etc to read 3 bit 
values. Or however wide it needs to be.


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v9 5/6] Coresight: Add Coresight TMC Control Unit driver
  2025-01-29 10:35       ` James Clark
@ 2025-01-29 13:02         ` Jie Gan
  2025-01-29 14:07           ` James Clark
  0 siblings, 1 reply; 24+ messages in thread
From: Jie Gan @ 2025-01-29 13:02 UTC (permalink / raw)
  To: James Clark
  Cc: Tingwei Zhang, Jinlong Mao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32,
	Suzuki K Poulose, Mike Leach, Alexander Shishkin, Maxime Coquelin,
	Alexandre Torgue, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Konrad Dybcio



On 1/29/2025 6:35 PM, James Clark wrote:
> 
> 
> On 29/01/2025 12:46 am, Jie Gan wrote:
>>
>>
>> On 1/28/2025 7:55 PM, James Clark wrote:
>>>
>>>
>>> On 24/01/2025 7:25 am, Jie Gan wrote:
>>>> The Coresight TMC Control Unit hosts miscellaneous configuration 
>>>> registers
>>>> which control various features related to TMC ETR sink.
>>>>
>>>> Based on the trace ID, which is programmed in the related CTCU ATID
>>>> register of a specific ETR, trace data with that trace ID gets into
>>>> the ETR buffer, while other trace data gets dropped.
>>>>
>>>> Enabling source device sets one bit of the ATID register based on
>>>> source device's trace ID.
>>>> Disabling source device resets the bit according to the source
>>>> device's trace ID.
>>>>
>>>> Signed-off-by: Jie Gan <quic_jiegan@quicinc.com>
>>>> ---
>>>>   drivers/hwtracing/coresight/Kconfig          |  12 +
>>>>   drivers/hwtracing/coresight/Makefile         |   1 +
>>>>   drivers/hwtracing/coresight/coresight-ctcu.c | 276 +++++++++++++++ 
>>>> ++++
>>>>   drivers/hwtracing/coresight/coresight-ctcu.h |  30 ++
>>>>   include/linux/coresight.h                    |   3 +-
>>>>   5 files changed, 321 insertions(+), 1 deletion(-)
>>>>   create mode 100644 drivers/hwtracing/coresight/coresight-ctcu.c
>>>>   create mode 100644 drivers/hwtracing/coresight/coresight-ctcu.h
>>>  >
>>>
>>> [...]
>>>
>>>> +/*
>>>> + * ctcu_set_etr_traceid: Retrieve the ATID offset and trace ID.
>>>> + *
>>>> + * Returns 0 indicates success. None-zero result means failure.
>>>> + */
>>>> +static int ctcu_set_etr_traceid(struct coresight_device *csdev, 
>>>> struct coresight_path *cs_path,
>>>> +                bool enable)
>>>> +{
>>>> +    struct coresight_device *sink = coresight_get_sink(cs_path->path);
>>>> +    struct ctcu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>>>> +    u8 trace_id = cs_path->trace_id;
>>>> +    int port_num;
>>>> +
>>>> +    if ((sink == NULL) || !IS_VALID_CS_TRACE_ID(trace_id) || 
>>>> IS_ERR_OR_NULL(drvdata)) {
>>>> +        dev_err(&csdev->dev, "Invalid parameters\n");
>>>> +        return -EINVAL;
>>>> +    }
>>>> +
>>>> +    port_num = ctcu_get_active_port(sink, csdev);
>>>> +    if (port_num < 0)
>>>> +        return -EINVAL;
>>>> +
>>>> +    /*
>>>> +     * Skip the disable session if more than one TPDM device that
>>>> +     * connected to the same TPDA device has been enabled.
>>>> +     */
>>>> +    if (enable)
>>>> +        atomic_inc(&drvdata->traceid_refcnt[port_num][trace_id]);
>>>> +    else {
>>>> +        if (atomic_dec_return(&drvdata->traceid_refcnt[port_num] 
>>>> [trace_id]) > 0) {
>>>> +            dev_dbg(&csdev->dev, "Skip the disable session\n");
>>>> +            return 0;
>>>> +        }
>>>> +    }
>>>> +
>>>> +    dev_dbg(&csdev->dev, "traceid is %d\n", cs_path->trace_id);
>>>> +
>>>> +    return __ctcu_set_etr_traceid(csdev, trace_id, port_num, enable);
>>>
>>> Hi Jie,
>>>
>>> Using atomic_dec_return() here doesn't prevent 
>>> __ctcu_set_etr_traceid() from running concurrent enable and disables. 
>>> Once you pass the atomic_dec_return() a second call to enable it will 
>>> mess it up.
>>>
>>> I think you need a spinlock around the whole thing and then the 
>>> refcounts don't need to be atomics.
>>>
>> Hi, James
>> Thanks for comment. I may not fully tested my codes here. What I was 
>> thinking is there's no way the refcnt could become a negative number 
>> under current framework. So I just added spinlock in 
>> __ctcu_set_etr_traceid() to ensure concurrent sessions correctly 
>> manipulate the register.
>>
>> As the trace_id related to the bit of the ATID register, I think the 
>> concurrent processes are working fine with spinlock around read/write 
>> register.
>>
>> I may not fully got your point here. Please help me to correct it.
>>
>> Thanks,
>> Jie
>>
>>
> 
> No it can't become negative, but the refcount can be a different state 
> to the one that was actually written:
> 
> 
>    CPU0                             CPU1
>    ----                             ----
>    ctcu_set_etr_traceid(enable)
>                                     ctcu_set_etr_traceid(disable)
>    atomic_inc()
>    recount == 1
>                                     atomic_dec()
>                                     recount == 0
> 
>                                     __ctcu_set_etr_traceid(disable)
>                                     Lock and write disable state to
>                                     device
> 
>    __ctcu_set_etr_traceid(enable)
>    Lock and write enable state to
>    device
> 
> 
> As you can see this leaves the device in an enabled state but the 
> refcount is 0.
Yes, you are right. I didnt consider this scenario. We definitely need 
spinlock here.

> 
> This is also quite large if you use atomic types:
> 
>   /* refcnt for each traceid of each sink */
>   atomic_t traceid_refcnt[ATID_MAX_NUM][CORESIGHT_TRACE_ID_RES_TOP];
> 
> Presumably you can't have the refcount for each ID be higher than the 
> max number of TPDMs connected? If you make the locked area a bit wider 
> you don't need atomic types and also solve the above problem. So you 
> could do u8, or DECLARE_BITMAP() and bitmap_read() etc to read 3 bit 
> values. Or however wide it needs to be.
The original purpose of using atomic here is trying to narrow the locked 
area.

I think u8 is ok here.
u8 traceid_refcnt[ATID_MAX_NUM][CORESIGHT_TRACE_ID_RES_TOP] will cost 
224 bytes, I think it's acceptable here.

Thanks,
Jie

> 


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v9 5/6] Coresight: Add Coresight TMC Control Unit driver
  2025-01-29 13:02         ` Jie Gan
@ 2025-01-29 14:07           ` James Clark
  0 siblings, 0 replies; 24+ messages in thread
From: James Clark @ 2025-01-29 14:07 UTC (permalink / raw)
  To: Jie Gan
  Cc: Tingwei Zhang, Jinlong Mao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32,
	Suzuki K Poulose, Mike Leach, Alexander Shishkin, Maxime Coquelin,
	Alexandre Torgue, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Konrad Dybcio



On 29/01/2025 1:02 pm, Jie Gan wrote:
> 
> 
> On 1/29/2025 6:35 PM, James Clark wrote:
>>
>>
>> On 29/01/2025 12:46 am, Jie Gan wrote:
>>>
>>>
>>> On 1/28/2025 7:55 PM, James Clark wrote:
>>>>
>>>>
>>>> On 24/01/2025 7:25 am, Jie Gan wrote:
>>>>> The Coresight TMC Control Unit hosts miscellaneous configuration 
>>>>> registers
>>>>> which control various features related to TMC ETR sink.
>>>>>
>>>>> Based on the trace ID, which is programmed in the related CTCU ATID
>>>>> register of a specific ETR, trace data with that trace ID gets into
>>>>> the ETR buffer, while other trace data gets dropped.
>>>>>
>>>>> Enabling source device sets one bit of the ATID register based on
>>>>> source device's trace ID.
>>>>> Disabling source device resets the bit according to the source
>>>>> device's trace ID.
>>>>>
>>>>> Signed-off-by: Jie Gan <quic_jiegan@quicinc.com>
>>>>> ---
>>>>>   drivers/hwtracing/coresight/Kconfig          |  12 +
>>>>>   drivers/hwtracing/coresight/Makefile         |   1 +
>>>>>   drivers/hwtracing/coresight/coresight-ctcu.c | 276 ++++++++++++++ 
>>>>> + ++++
>>>>>   drivers/hwtracing/coresight/coresight-ctcu.h |  30 ++
>>>>>   include/linux/coresight.h                    |   3 +-
>>>>>   5 files changed, 321 insertions(+), 1 deletion(-)
>>>>>   create mode 100644 drivers/hwtracing/coresight/coresight-ctcu.c
>>>>>   create mode 100644 drivers/hwtracing/coresight/coresight-ctcu.h
>>>>  >
>>>>
>>>> [...]
>>>>
>>>>> +/*
>>>>> + * ctcu_set_etr_traceid: Retrieve the ATID offset and trace ID.
>>>>> + *
>>>>> + * Returns 0 indicates success. None-zero result means failure.
>>>>> + */
>>>>> +static int ctcu_set_etr_traceid(struct coresight_device *csdev, 
>>>>> struct coresight_path *cs_path,
>>>>> +                bool enable)
>>>>> +{
>>>>> +    struct coresight_device *sink = coresight_get_sink(cs_path- 
>>>>> >path);
>>>>> +    struct ctcu_drvdata *drvdata = dev_get_drvdata(csdev- 
>>>>> >dev.parent);
>>>>> +    u8 trace_id = cs_path->trace_id;
>>>>> +    int port_num;
>>>>> +
>>>>> +    if ((sink == NULL) || !IS_VALID_CS_TRACE_ID(trace_id) || 
>>>>> IS_ERR_OR_NULL(drvdata)) {
>>>>> +        dev_err(&csdev->dev, "Invalid parameters\n");
>>>>> +        return -EINVAL;
>>>>> +    }
>>>>> +
>>>>> +    port_num = ctcu_get_active_port(sink, csdev);
>>>>> +    if (port_num < 0)
>>>>> +        return -EINVAL;
>>>>> +
>>>>> +    /*
>>>>> +     * Skip the disable session if more than one TPDM device that
>>>>> +     * connected to the same TPDA device has been enabled.
>>>>> +     */
>>>>> +    if (enable)
>>>>> +        atomic_inc(&drvdata->traceid_refcnt[port_num][trace_id]);
>>>>> +    else {
>>>>> +        if (atomic_dec_return(&drvdata->traceid_refcnt[port_num] 
>>>>> [trace_id]) > 0) {
>>>>> +            dev_dbg(&csdev->dev, "Skip the disable session\n");
>>>>> +            return 0;
>>>>> +        }
>>>>> +    }
>>>>> +
>>>>> +    dev_dbg(&csdev->dev, "traceid is %d\n", cs_path->trace_id);
>>>>> +
>>>>> +    return __ctcu_set_etr_traceid(csdev, trace_id, port_num, enable);
>>>>
>>>> Hi Jie,
>>>>
>>>> Using atomic_dec_return() here doesn't prevent 
>>>> __ctcu_set_etr_traceid() from running concurrent enable and 
>>>> disables. Once you pass the atomic_dec_return() a second call to 
>>>> enable it will mess it up.
>>>>
>>>> I think you need a spinlock around the whole thing and then the 
>>>> refcounts don't need to be atomics.
>>>>
>>> Hi, James
>>> Thanks for comment. I may not fully tested my codes here. What I was 
>>> thinking is there's no way the refcnt could become a negative number 
>>> under current framework. So I just added spinlock in 
>>> __ctcu_set_etr_traceid() to ensure concurrent sessions correctly 
>>> manipulate the register.
>>>
>>> As the trace_id related to the bit of the ATID register, I think the 
>>> concurrent processes are working fine with spinlock around read/write 
>>> register.
>>>
>>> I may not fully got your point here. Please help me to correct it.
>>>
>>> Thanks,
>>> Jie
>>>
>>>
>>
>> No it can't become negative, but the refcount can be a different state 
>> to the one that was actually written:
>>
>>
>>    CPU0                             CPU1
>>    ----                             ----
>>    ctcu_set_etr_traceid(enable)
>>                                     ctcu_set_etr_traceid(disable)
>>    atomic_inc()
>>    recount == 1
>>                                     atomic_dec()
>>                                     recount == 0
>>
>>                                     __ctcu_set_etr_traceid(disable)
>>                                     Lock and write disable state to
>>                                     device
>>
>>    __ctcu_set_etr_traceid(enable)
>>    Lock and write enable state to
>>    device
>>
>>
>> As you can see this leaves the device in an enabled state but the 
>> refcount is 0.
> Yes, you are right. I didnt consider this scenario. We definitely need 
> spinlock here.
> 
>>
>> This is also quite large if you use atomic types:
>>
>>   /* refcnt for each traceid of each sink */
>>   atomic_t traceid_refcnt[ATID_MAX_NUM][CORESIGHT_TRACE_ID_RES_TOP];
>>
>> Presumably you can't have the refcount for each ID be higher than the 
>> max number of TPDMs connected? If you make the locked area a bit wider 
>> you don't need atomic types and also solve the above problem. So you 
>> could do u8, or DECLARE_BITMAP() and bitmap_read() etc to read 3 bit 
>> values. Or however wide it needs to be.
> The original purpose of using atomic here is trying to narrow the locked 
> area.
> 
> I think u8 is ok here.
> u8 traceid_refcnt[ATID_MAX_NUM][CORESIGHT_TRACE_ID_RES_TOP] will cost 
> 224 bytes, I think it's acceptable here.
> 
> Thanks,
> Jie
> 

Yep u8 sounds ok then



^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 0/3] coresight: Alloc trace ID after building the path
  2025-01-29  0:57     ` Jie Gan
@ 2025-01-31 16:36       ` James Clark
  2025-01-31 16:36         ` [PATCH 1/3] coresight: Don't save handle in path James Clark
                           ` (3 more replies)
  0 siblings, 4 replies; 24+ messages in thread
From: James Clark @ 2025-01-31 16:36 UTC (permalink / raw)
  To: quic_jiegan
  Cc: quic_tingweiz, quic_jinlmao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32,
	suzuki.poulose, mike.leach, alexander.shishkin, mcoquelin.stm32,
	alexandre.torgue, robh, krzk+dt, conor+dt, andersson, konradybcio,
	James Clark

Proof of concept to support CTCU device. Applies to Jie's patchset in
the parent email. I think this would be a good simplification, it
removes some code and makes things a bit clearer, and works for both the
old and new CTCU requirements. It will require merging into the parent
patchset somehow as it undoes some of those changes.

James Clark (3):
  coresight: Don't save handle in path
  coresight: Export coresight_get_sink()
  coresight: Alloc trace ID after building the path

 drivers/hwtracing/coresight/coresight-core.c  | 107 +++++++++++++-----
 drivers/hwtracing/coresight/coresight-dummy.c |   9 +-
 drivers/hwtracing/coresight/coresight-etb10.c |   8 +-
 .../hwtracing/coresight/coresight-etm-perf.c  |  20 ++--
 drivers/hwtracing/coresight/coresight-etm.h   |   1 -
 .../coresight/coresight-etm3x-core.c          |  84 ++------------
 .../coresight/coresight-etm3x-sysfs.c         |   3 +-
 .../coresight/coresight-etm4x-core.c          |  83 ++------------
 .../coresight/coresight-etm4x-sysfs.c         |   4 +-
 drivers/hwtracing/coresight/coresight-etm4x.h |   1 -
 drivers/hwtracing/coresight/coresight-priv.h  |  17 +--
 drivers/hwtracing/coresight/coresight-stm.c   |   5 +-
 drivers/hwtracing/coresight/coresight-sysfs.c |   6 +-
 .../hwtracing/coresight/coresight-tmc-etf.c   |   9 +-
 .../hwtracing/coresight/coresight-tmc-etr.c   |  13 +--
 drivers/hwtracing/coresight/coresight-tmc.h   |   2 +-
 drivers/hwtracing/coresight/coresight-tpda.c  |   3 +-
 drivers/hwtracing/coresight/coresight-tpdm.c  |   3 +-
 drivers/hwtracing/coresight/coresight-tpiu.c  |   2 +-
 drivers/hwtracing/coresight/coresight-trbe.c  |   4 +-
 drivers/hwtracing/coresight/ultrasoc-smb.c    |   8 +-
 include/linux/coresight.h                     |  25 +++-
 22 files changed, 159 insertions(+), 258 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 1/3] coresight: Don't save handle in path
  2025-01-31 16:36       ` [PATCH 0/3] coresight: Alloc trace ID after building the path James Clark
@ 2025-01-31 16:36         ` James Clark
  2025-02-06  3:02           ` Jie Gan
  2025-01-31 16:36         ` [PATCH 2/3] coresight: Export coresight_get_sink() James Clark
                           ` (2 subsequent siblings)
  3 siblings, 1 reply; 24+ messages in thread
From: James Clark @ 2025-01-31 16:36 UTC (permalink / raw)
  To: quic_jiegan
  Cc: quic_tingweiz, quic_jinlmao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32,
	suzuki.poulose, mike.leach, alexander.shishkin, mcoquelin.stm32,
	alexandre.torgue, robh, krzk+dt, conor+dt, andersson, konradybcio,
	James Clark

Signed-off-by: James Clark <james.clark@linaro.org>
---
 drivers/hwtracing/coresight/coresight-core.c     | 10 +++++-----
 drivers/hwtracing/coresight/coresight-dummy.c    |  2 +-
 drivers/hwtracing/coresight/coresight-etb10.c    |  8 +++-----
 drivers/hwtracing/coresight/coresight-etm-perf.c |  3 +--
 drivers/hwtracing/coresight/coresight-priv.h     |  4 ++--
 drivers/hwtracing/coresight/coresight-sysfs.c    |  2 +-
 drivers/hwtracing/coresight/coresight-tmc-etf.c  |  9 ++++-----
 drivers/hwtracing/coresight/coresight-tmc-etr.c  | 13 +++++--------
 drivers/hwtracing/coresight/coresight-tmc.h      |  2 +-
 drivers/hwtracing/coresight/coresight-tpiu.c     |  2 +-
 drivers/hwtracing/coresight/coresight-trbe.c     |  4 +---
 drivers/hwtracing/coresight/ultrasoc-smb.c       |  8 +++-----
 include/linux/coresight.h                        |  2 +-
 13 files changed, 29 insertions(+), 40 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index 11d5d5320b1a..253ef02fde12 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -272,9 +272,9 @@ void coresight_add_helper(struct coresight_device *csdev,
 EXPORT_SYMBOL_GPL(coresight_add_helper);
 
 static int coresight_enable_sink(struct coresight_device *csdev,
-				 enum cs_mode mode, void *data)
+				 enum cs_mode mode, struct perf_output_handle *handle)
 {
-	return sink_ops(csdev)->enable(csdev, mode, data);
+	return sink_ops(csdev)->enable(csdev, mode, handle);
 }
 
 static void coresight_disable_sink(struct coresight_device *csdev)
@@ -448,7 +448,8 @@ static int coresight_enable_helpers(struct coresight_device *csdev,
 	return 0;
 }
 
-int coresight_enable_path(struct coresight_path *cs_path, enum cs_mode mode)
+int coresight_enable_path(struct coresight_path *cs_path, enum cs_mode mode,
+			  struct perf_output_handle *handle)
 {
 	int ret = 0;
 	u32 type;
@@ -479,7 +480,7 @@ int coresight_enable_path(struct coresight_path *cs_path, enum cs_mode mode)
 
 		switch (type) {
 		case CORESIGHT_DEV_TYPE_SINK:
-			ret = coresight_enable_sink(csdev, mode, cs_path);
+			ret = coresight_enable_sink(csdev, mode, handle);
 			/*
 			 * Sink is the first component turned on. If we
 			 * failed to enable the sink, there are no components
@@ -807,7 +808,6 @@ void coresight_release_path(struct coresight_path *cs_path)
 		kfree(nd);
 	}
 
-	cs_path->handle = NULL;
 	kfree(cs_path->path);
 	kfree(cs_path);
 }
diff --git a/drivers/hwtracing/coresight/coresight-dummy.c b/drivers/hwtracing/coresight/coresight-dummy.c
index dfcf24e9c49a..6f86d33efef4 100644
--- a/drivers/hwtracing/coresight/coresight-dummy.c
+++ b/drivers/hwtracing/coresight/coresight-dummy.c
@@ -54,7 +54,7 @@ static int dummy_source_trace_id(struct coresight_device *csdev, enum cs_mode mo
 }
 
 static int dummy_sink_enable(struct coresight_device *csdev, enum cs_mode mode,
-				void *data)
+				struct perf_output_handle *handle)
 {
 	dev_dbg(csdev->dev.parent, "Dummy sink enabled\n");
 
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index 05430d8931d1..e373b0f590bf 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -167,14 +167,12 @@ static int etb_enable_sysfs(struct coresight_device *csdev)
 	return ret;
 }
 
-static int etb_enable_perf(struct coresight_device *csdev, void *data)
+static int etb_enable_perf(struct coresight_device *csdev, struct perf_output_handle *handle)
 {
 	int ret = 0;
 	pid_t pid;
 	unsigned long flags;
 	struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-	struct coresight_path *cs_path = (struct coresight_path *)data;
-	struct perf_output_handle *handle = cs_path->handle;
 	struct cs_buffers *buf = etm_perf_sink_config(handle);
 
 	spin_lock_irqsave(&drvdata->spinlock, flags);
@@ -225,7 +223,7 @@ static int etb_enable_perf(struct coresight_device *csdev, void *data)
 }
 
 static int etb_enable(struct coresight_device *csdev, enum cs_mode mode,
-		      void *data)
+		      struct perf_output_handle *handle)
 {
 	int ret;
 
@@ -234,7 +232,7 @@ static int etb_enable(struct coresight_device *csdev, enum cs_mode mode,
 		ret = etb_enable_sysfs(csdev);
 		break;
 	case CS_MODE_PERF:
-		ret = etb_enable_perf(csdev, data);
+		ret = etb_enable_perf(csdev, handle);
 		break;
 	default:
 		ret = -EINVAL;
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index b6765abb0a26..0fad9968c2c0 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -501,9 +501,8 @@ static void etm_event_start(struct perf_event *event, int flags)
 	if (WARN_ON_ONCE(!sink))
 		goto fail_end_stop;
 
-	cs_path->handle = handle;
 	/* Nothing will happen without a path */
-	if (coresight_enable_path(cs_path, CS_MODE_PERF))
+	if (coresight_enable_path(cs_path, CS_MODE_PERF, handle))
 		goto fail_end_stop;
 
 	/* Finally enable the tracer */
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index 8e02a222b9f8..7bd43304f461 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -112,7 +112,6 @@ struct cs_buffers {
  * @trace_id:		trace_id of the whole path.
  */
 struct coresight_path {
-	struct perf_output_handle	*handle;
 	struct list_head		*path;
 	u8				trace_id;
 };
@@ -142,7 +141,8 @@ static inline void CS_UNLOCK(void __iomem *addr)
 }
 
 void coresight_disable_path(struct coresight_path *cs_path);
-int coresight_enable_path(struct coresight_path *cs_path, enum cs_mode mode);
+int coresight_enable_path(struct coresight_path *cs_path, enum cs_mode mode,
+			  struct perf_output_handle *handle);
 struct coresight_device *coresight_get_sink(struct list_head *path);
 struct coresight_device *coresight_get_sink_by_id(u32 id);
 struct coresight_device *
diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/hwtracing/coresight/coresight-sysfs.c
index 04e76cc1bfdf..f9a6b838726c 100644
--- a/drivers/hwtracing/coresight/coresight-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-sysfs.c
@@ -209,7 +209,7 @@ int coresight_enable_sysfs(struct coresight_device *csdev)
 		goto out;
 	}
 
-	ret = coresight_enable_path(cs_path, CS_MODE_SYSFS);
+	ret = coresight_enable_path(cs_path, CS_MODE_SYSFS, NULL);
 	if (ret)
 		goto err_path;
 
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index e6b07f917556..fdf1c2511d67 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -244,14 +244,13 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
 	return ret;
 }
 
-static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
+static int tmc_enable_etf_sink_perf(struct coresight_device *csdev,
+				    struct perf_output_handle *handle)
 {
 	int ret = 0;
 	pid_t pid;
 	unsigned long flags;
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-	struct coresight_path *cs_path= (struct coresight_path *)data;
-	struct perf_output_handle *handle = cs_path->handle;
 	struct cs_buffers *buf = etm_perf_sink_config(handle);
 
 	spin_lock_irqsave(&drvdata->spinlock, flags);
@@ -303,7 +302,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
 }
 
 static int tmc_enable_etf_sink(struct coresight_device *csdev,
-			       enum cs_mode mode, void *data)
+			       enum cs_mode mode, struct perf_output_handle *handle)
 {
 	int ret;
 
@@ -312,7 +311,7 @@ static int tmc_enable_etf_sink(struct coresight_device *csdev,
 		ret = tmc_enable_etf_sink_sysfs(csdev);
 		break;
 	case CS_MODE_PERF:
-		ret = tmc_enable_etf_sink_perf(csdev, data);
+		ret = tmc_enable_etf_sink_perf(csdev, handle);
 		break;
 	/* We shouldn't be here */
 	default:
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index 82a872882e24..2d0bd06bab2a 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1252,10 +1252,8 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
 }
 
 struct etr_buf *tmc_etr_get_buffer(struct coresight_device *csdev,
-				   enum cs_mode mode, void *data)
+				   enum cs_mode mode, struct perf_output_handle *handle)
 {
-	struct coresight_path *cs_path = (struct coresight_path *)data;
-	struct perf_output_handle *handle = cs_path->handle;
 	struct etr_perf_buffer *etr_perf;
 
 	switch (mode) {
@@ -1643,14 +1641,13 @@ tmc_update_etr_buffer(struct coresight_device *csdev,
 	return size;
 }
 
-static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
+static int tmc_enable_etr_sink_perf(struct coresight_device *csdev,
+				    struct perf_output_handle *handle)
 {
 	int rc = 0;
 	pid_t pid;
 	unsigned long flags;
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-	struct coresight_path *cs_path = (struct coresight_path *)data;
-	struct perf_output_handle *handle = cs_path->handle;
 	struct etr_perf_buffer *etr_perf = etm_perf_sink_config(handle);
 
 	spin_lock_irqsave(&drvdata->spinlock, flags);
@@ -1698,13 +1695,13 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
 }
 
 static int tmc_enable_etr_sink(struct coresight_device *csdev,
-			       enum cs_mode mode, void *data)
+			       enum cs_mode mode, struct perf_output_handle *handle)
 {
 	switch (mode) {
 	case CS_MODE_SYSFS:
 		return tmc_enable_etr_sink_sysfs(csdev);
 	case CS_MODE_PERF:
-		return tmc_enable_etr_sink_perf(csdev, data);
+		return tmc_enable_etr_sink_perf(csdev, handle);
 	default:
 		return -EINVAL;
 	}
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index 2671926be62a..e991afd43742 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -336,7 +336,7 @@ struct coresight_device *tmc_etr_get_catu_device(struct tmc_drvdata *drvdata);
 void tmc_etr_set_catu_ops(const struct etr_buf_operations *catu);
 void tmc_etr_remove_catu_ops(void);
 struct etr_buf *tmc_etr_get_buffer(struct coresight_device *csdev,
-				   enum cs_mode mode, void *data);
+				   enum cs_mode mode, struct perf_output_handle *handle);
 extern const struct attribute_group coresight_etr_group;
 
 #endif
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
index 97ef36f03ec2..ccf463ac7bf5 100644
--- a/drivers/hwtracing/coresight/coresight-tpiu.c
+++ b/drivers/hwtracing/coresight/coresight-tpiu.c
@@ -75,7 +75,7 @@ static void tpiu_enable_hw(struct csdev_access *csa)
 }
 
 static int tpiu_enable(struct coresight_device *csdev, enum cs_mode mode,
-		       void *__unused)
+		       struct perf_output_handle *__unused)
 {
 	struct tpiu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index 5005efd88a66..997d5976d2d2 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -1009,12 +1009,10 @@ static int __arm_trbe_enable(struct trbe_buf *buf,
 }
 
 static int arm_trbe_enable(struct coresight_device *csdev, enum cs_mode mode,
-			   void *data)
+			   struct perf_output_handle *handle)
 {
 	struct trbe_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 	struct trbe_cpudata *cpudata = dev_get_drvdata(&csdev->dev);
-	struct coresight_path *cs_path = (struct coresight_path *)data;
-	struct perf_output_handle *handle = cs_path->handle;
 	struct trbe_buf *buf = etm_perf_sink_config(handle);
 
 	WARN_ON(cpudata->cpu != smp_processor_id());
diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/hwtracing/coresight/ultrasoc-smb.c
index 9be88394b3bb..1574b5067206 100644
--- a/drivers/hwtracing/coresight/ultrasoc-smb.c
+++ b/drivers/hwtracing/coresight/ultrasoc-smb.c
@@ -213,11 +213,9 @@ static void smb_enable_sysfs(struct coresight_device *csdev)
 	coresight_set_mode(csdev, CS_MODE_SYSFS);
 }
 
-static int smb_enable_perf(struct coresight_device *csdev, void *data)
+static int smb_enable_perf(struct coresight_device *csdev, struct perf_output_handle *handle)
 {
 	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
-	struct coresight_path *cs_path = (struct coresight_path *)data;
-	struct perf_output_handle *handle = cs_path->handle;
 	struct cs_buffers *buf = etm_perf_sink_config(handle);
 	pid_t pid;
 
@@ -241,7 +239,7 @@ static int smb_enable_perf(struct coresight_device *csdev, void *data)
 }
 
 static int smb_enable(struct coresight_device *csdev, enum cs_mode mode,
-		      void *data)
+		      struct perf_output_handle *handle)
 {
 	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
 	int ret = 0;
@@ -262,7 +260,7 @@ static int smb_enable(struct coresight_device *csdev, enum cs_mode mode,
 		smb_enable_sysfs(csdev);
 		break;
 	case CS_MODE_PERF:
-		ret = smb_enable_perf(csdev, data);
+		ret = smb_enable_perf(csdev, handle);
 		break;
 	default:
 		ret = -EINVAL;
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 87f9baa7fefe..a859fc00eef9 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -353,7 +353,7 @@ enum cs_mode {
  */
 struct coresight_ops_sink {
 	int (*enable)(struct coresight_device *csdev, enum cs_mode mode,
-		      void *data);
+		      struct perf_output_handle *handle);
 	int (*disable)(struct coresight_device *csdev);
 	void *(*alloc_buffer)(struct coresight_device *csdev,
 			      struct perf_event *event, void **pages,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 2/3] coresight: Export coresight_get_sink()
  2025-01-31 16:36       ` [PATCH 0/3] coresight: Alloc trace ID after building the path James Clark
  2025-01-31 16:36         ` [PATCH 1/3] coresight: Don't save handle in path James Clark
@ 2025-01-31 16:36         ` James Clark
  2025-01-31 16:36         ` [PATCH 3/3] coresight: Alloc trace ID after building the path James Clark
  2025-02-05  4:13         ` [PATCH 0/3] " Jie Gan
  3 siblings, 0 replies; 24+ messages in thread
From: James Clark @ 2025-01-31 16:36 UTC (permalink / raw)
  To: quic_jiegan
  Cc: quic_tingweiz, quic_jinlmao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32,
	suzuki.poulose, mike.leach, alexander.shishkin, mcoquelin.stm32,
	alexandre.torgue, robh, krzk+dt, conor+dt, andersson, konradybcio,
	James Clark

Signed-off-by: James Clark <james.clark@linaro.org>
---
 drivers/hwtracing/coresight/coresight-core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index 253ef02fde12..f31c8477f7b7 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -526,6 +526,7 @@ struct coresight_device *coresight_get_sink(struct list_head *path)
 
 	return csdev;
 }
+EXPORT_SYMBOL_GPL(coresight_get_sink);
 
 u32 coresight_get_sink_id(struct coresight_device *csdev)
 {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 3/3] coresight: Alloc trace ID after building the path
  2025-01-31 16:36       ` [PATCH 0/3] coresight: Alloc trace ID after building the path James Clark
  2025-01-31 16:36         ` [PATCH 1/3] coresight: Don't save handle in path James Clark
  2025-01-31 16:36         ` [PATCH 2/3] coresight: Export coresight_get_sink() James Clark
@ 2025-01-31 16:36         ` James Clark
  2025-02-05  4:13         ` [PATCH 0/3] " Jie Gan
  3 siblings, 0 replies; 24+ messages in thread
From: James Clark @ 2025-01-31 16:36 UTC (permalink / raw)
  To: quic_jiegan
  Cc: quic_tingweiz, quic_jinlmao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32,
	suzuki.poulose, mike.leach, alexander.shishkin, mcoquelin.stm32,
	alexandre.torgue, robh, krzk+dt, conor+dt, andersson, konradybcio,
	James Clark

This reduces the number of places that the ID allocation happens to just
sysfs trctraceid_show() and when the path is built. And it consolidates
some duplicate code by doing everything the same way whether it's sysfs
mode, Perf mode, or if the trace ID is needed in advance for helper
devices like CTCUs.

Signed-off-by: James Clark <james.clark@linaro.org>
---
 drivers/hwtracing/coresight/coresight-core.c  | 96 ++++++++++++++-----
 drivers/hwtracing/coresight/coresight-dummy.c |  7 +-
 .../hwtracing/coresight/coresight-etm-perf.c  | 17 ++--
 drivers/hwtracing/coresight/coresight-etm.h   |  1 -
 .../coresight/coresight-etm3x-core.c          | 84 ++--------------
 .../coresight/coresight-etm3x-sysfs.c         |  3 +-
 .../coresight/coresight-etm4x-core.c          | 83 ++--------------
 .../coresight/coresight-etm4x-sysfs.c         |  4 +-
 drivers/hwtracing/coresight/coresight-etm4x.h |  1 -
 drivers/hwtracing/coresight/coresight-priv.h  | 13 +--
 drivers/hwtracing/coresight/coresight-stm.c   |  5 +-
 drivers/hwtracing/coresight/coresight-sysfs.c |  4 +
 drivers/hwtracing/coresight/coresight-tpda.c  |  3 +-
 drivers/hwtracing/coresight/coresight-tpdm.c  |  3 +-
 include/linux/coresight.h                     | 23 ++++-
 15 files changed, 129 insertions(+), 218 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index f31c8477f7b7..88041000c0e9 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -657,6 +657,51 @@ static void coresight_drop_device(struct coresight_device *csdev)
 	}
 }
 
+/**
+ * Links or sources will read their existing or alloc a trace ID, if their ID
+ * callback is set.
+ */
+static int coresight_get_trace_id(struct coresight_device *csdev,
+				     enum cs_mode mode,
+				     struct coresight_device *sink)
+{
+	if (csdev->type == CORESIGHT_DEV_TYPE_LINK && link_ops(csdev)->trace_id)
+		return link_ops(csdev)->trace_id(csdev, mode, sink);
+
+	if (csdev->type == CORESIGHT_DEV_TYPE_SOURCE && source_ops(csdev)->trace_id)
+		return source_ops(csdev)->trace_id(csdev, mode, sink);
+
+	return 0;
+}
+
+/**
+ * Call this after creating the path and before enabling it. This leaves
+ * the trace ID set on the path and returns the ID, or an error if it
+ * couldn't be assigned.
+ */
+int coresight_path_assign_trace_id(struct coresight_path *path,
+				  enum cs_mode mode)
+{
+	struct coresight_device *sink = coresight_get_sink(path->path);
+	struct coresight_node *nd;
+	int ret;
+
+	list_for_each_entry(nd, path->path, link) {
+		/* Assign a trace ID to the path for the first device that wants to do it */
+		ret = coresight_get_trace_id(nd->csdev, mode, sink);
+
+		/*
+		 * 0 in this context is that it didn't want to assign so keep searching.
+		 * Non 0 is either success or fail, return it either way.
+		 */
+		if (ret != 0) {
+			path->trace_id = ret;
+			return ret;
+		}
+	}
+	return 0;
+}
+
 /**
  * _coresight_build_path - recursively build a path from a @csdev to a sink.
  * @csdev:	The device to start from.
@@ -691,15 +736,6 @@ static int _coresight_build_path(struct coresight_device *csdev,
 		}
 	}
 
-	/* Attempt to read the trace_id from TPDA device */
-	if (!IS_VALID_CS_TRACE_ID(cs_path->trace_id) &&
-	    (csdev->type == CORESIGHT_DEV_TYPE_LINK) &&
-	    (link_ops(csdev)->trace_id != NULL)) {
-		ret = link_ops(csdev)->trace_id(csdev);
-		if (IS_VALID_CS_TRACE_ID(ret))
-			cs_path->trace_id = ret;
-	}
-
 	/* Not a sink - recursively explore each port found on this element */
 	for (i = 0; i < csdev->pdata->nr_outconns; i++) {
 		struct coresight_device *child_dev;
@@ -762,22 +798,6 @@ struct coresight_path *coresight_build_path(struct coresight_device *source,
 
 	INIT_LIST_HEAD(path);
 	cs_path->path = path;
-	/*
-	 * Since not all source devices have a defined trace_id function,
-	 * make sure to check for it before use.
-	 *
-	 * Assert the mode is CS_MODE_SYSFS, the trace_id will be assigned
-	 * again later if the mode is CS_MODE_PERF.
-	 */
-	if (source_ops(source)->trace_id != NULL) {
-		rc = source_ops(source)->trace_id(source, CS_MODE_SYSFS, NULL);
-		if(IS_VALID_CS_TRACE_ID(rc))
-			cs_path->trace_id = rc;
-		else 
-			cs_path->trace_id = 0;
-	}
-	else
-		cs_path->trace_id = 0;
 
 	rc = _coresight_build_path(source, source, sink, cs_path);
 	if (rc) {
@@ -1555,6 +1575,32 @@ void coresight_remove_driver(struct amba_driver *amba_drv,
 }
 EXPORT_SYMBOL_GPL(coresight_remove_driver);
 
+int coresight_etm_get_trace_id(struct coresight_device *csdev, enum cs_mode mode,
+			       struct coresight_device *sink)
+{
+	int trace_id;
+	int cpu = source_ops(csdev)->cpu_id(csdev);
+
+	switch (mode) {
+	case CS_MODE_SYSFS:
+		trace_id = coresight_trace_id_get_cpu_id(cpu);
+		break;
+	case CS_MODE_PERF:
+		trace_id = coresight_trace_id_get_cpu_id_map(cpu, &sink->perf_sink_id_map);
+		break;
+	default:
+		trace_id = -EINVAL;
+		break;
+	}
+
+	if (!IS_VALID_CS_TRACE_ID(trace_id))
+		dev_err(&csdev->dev,
+			"Failed to allocate trace ID on CPU%d\n", cpu);
+
+	return trace_id;
+}
+EXPORT_SYMBOL_GPL(coresight_etm_get_trace_id);
+
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
 MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
diff --git a/drivers/hwtracing/coresight/coresight-dummy.c b/drivers/hwtracing/coresight/coresight-dummy.c
index 6f86d33efef4..a8a991e81725 100644
--- a/drivers/hwtracing/coresight/coresight-dummy.c
+++ b/drivers/hwtracing/coresight/coresight-dummy.c
@@ -22,9 +22,8 @@ struct dummy_drvdata {
 DEFINE_CORESIGHT_DEVLIST(source_devs, "dummy_source");
 DEFINE_CORESIGHT_DEVLIST(sink_devs, "dummy_sink");
 
-static int dummy_source_enable(struct coresight_device *csdev,
-			       struct perf_event *event, enum cs_mode mode,
-			       __maybe_unused struct coresight_trace_id_map *id_map)
+static int dummy_source_enable(struct coresight_device *csdev, struct perf_event *event,
+			       enum cs_mode mode, struct coresight_path *path)
 {
 	if (!coresight_take_mode(csdev, mode))
 		return -EBUSY;
@@ -42,7 +41,7 @@ static void dummy_source_disable(struct coresight_device *csdev,
 }
 
 static int dummy_source_trace_id(struct coresight_device *csdev, enum cs_mode mode,
-				 struct coresight_trace_id_map *id_map)
+				 struct coresight_device *sink)
 {
 	struct dummy_drvdata *drvdata;
 
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index 0fad9968c2c0..e5bd8d577259 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -407,17 +407,16 @@ static void *etm_setup_aux(struct perf_event *event, void **pages,
 			cpumask_clear_cpu(cpu, mask);
 			continue;
 		}
-
 		/* ensure we can allocate a trace ID for this CPU */
-		trace_id = coresight_trace_id_get_cpu_id_map(cpu, &sink->perf_sink_id_map);
-		if (!IS_VALID_CS_TRACE_ID(trace_id)) {
+		trace_id = coresight_path_assign_trace_id(cs_path, CS_MODE_PERF);
+
+		/* Can be 0 and valid, ETE doesn't need an ID */
+		if (trace_id < 0) {
 			cpumask_clear_cpu(cpu, mask);
 			coresight_release_path(cs_path);
 			continue;
 		}
-
 		coresight_trace_id_perf_start(&sink->perf_sink_id_map);
-		cs_path->trace_id = trace_id;
 		*etm_event_cpu_path_ptr(event_data, cpu) = cs_path;
 	}
 
@@ -463,7 +462,6 @@ static void etm_event_start(struct perf_event *event, int flags)
 	struct coresight_device *sink, *csdev = per_cpu(csdev_src, cpu);
 	struct coresight_path *cs_path;
 	u64 hw_id;
-	u8 trace_id;
 
 	if (!csdev)
 		goto fail;
@@ -506,8 +504,7 @@ static void etm_event_start(struct perf_event *event, int flags)
 		goto fail_end_stop;
 
 	/* Finally enable the tracer */
-	if (source_ops(csdev)->enable(csdev, event, CS_MODE_PERF,
-				      &sink->perf_sink_id_map))
+	if (source_ops(csdev)->enable(csdev, event, CS_MODE_PERF, cs_path))
 		goto fail_disable_path;
 
 	/*
@@ -517,13 +514,11 @@ static void etm_event_start(struct perf_event *event, int flags)
 	if (!cpumask_test_cpu(cpu, &event_data->aux_hwid_done)) {
 		cpumask_set_cpu(cpu, &event_data->aux_hwid_done);
 
-		trace_id = coresight_trace_id_read_cpu_id_map(cpu, &sink->perf_sink_id_map);
-
 		hw_id = FIELD_PREP(CS_AUX_HW_ID_MAJOR_VERSION_MASK,
 				CS_AUX_HW_ID_MAJOR_VERSION);
 		hw_id |= FIELD_PREP(CS_AUX_HW_ID_MINOR_VERSION_MASK,
 				CS_AUX_HW_ID_MINOR_VERSION);
-		hw_id |= FIELD_PREP(CS_AUX_HW_ID_TRACE_ID_MASK, trace_id);
+		hw_id |= FIELD_PREP(CS_AUX_HW_ID_TRACE_ID_MASK, cs_path->trace_id);
 		hw_id |= FIELD_PREP(CS_AUX_HW_ID_SINK_ID_MASK, coresight_get_sink_id(sink));
 
 		perf_report_aux_output_id(event, hw_id);
diff --git a/drivers/hwtracing/coresight/coresight-etm.h b/drivers/hwtracing/coresight/coresight-etm.h
index e02c3ea972c9..171f1384f7c0 100644
--- a/drivers/hwtracing/coresight/coresight-etm.h
+++ b/drivers/hwtracing/coresight/coresight-etm.h
@@ -284,6 +284,5 @@ extern const struct attribute_group *coresight_etm_groups[];
 void etm_set_default(struct etm_config *config);
 void etm_config_trace_mode(struct etm_config *config);
 struct etm_config *get_etm_config(struct etm_drvdata *drvdata);
-int etm_read_alloc_trace_id(struct etm_drvdata *drvdata);
 void etm_release_trace_id(struct etm_drvdata *drvdata);
 #endif
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
index 74c6a2ffd07a..cb8a30a3b48e 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
@@ -455,26 +455,6 @@ static int etm_cpu_id(struct coresight_device *csdev)
 	return drvdata->cpu;
 }
 
-int etm_read_alloc_trace_id(struct etm_drvdata *drvdata)
-{
-	int trace_id;
-
-	/*
-	 * This will allocate a trace ID to the cpu,
-	 * or return the one currently allocated.
-	 *
-	 * trace id function has its own lock
-	 */
-	trace_id = coresight_trace_id_get_cpu_id(drvdata->cpu);
-	if (IS_VALID_CS_TRACE_ID(trace_id))
-		drvdata->traceid = (u8)trace_id;
-	else
-		dev_err(&drvdata->csdev->dev,
-			"Failed to allocate trace ID for %s on CPU%d\n",
-			dev_name(&drvdata->csdev->dev), drvdata->cpu);
-	return trace_id;
-}
-
 void etm_release_trace_id(struct etm_drvdata *drvdata)
 {
 	coresight_trace_id_put_cpu_id(drvdata->cpu);
@@ -482,38 +462,22 @@ void etm_release_trace_id(struct etm_drvdata *drvdata)
 
 static int etm_enable_perf(struct coresight_device *csdev,
 			   struct perf_event *event,
-			   struct coresight_trace_id_map *id_map)
+			   struct coresight_path *path)
 {
 	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-	int trace_id;
 
 	if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id()))
 		return -EINVAL;
 
 	/* Configure the tracer based on the session's specifics */
 	etm_parse_event_config(drvdata, event);
-
-	/*
-	 * perf allocates cpu ids as part of _setup_aux() - device needs to use
-	 * the allocated ID. This reads the current version without allocation.
-	 *
-	 * This does not use the trace id lock to prevent lock_dep issues
-	 * with perf locks - we know the ID cannot change until perf shuts down
-	 * the session
-	 */
-	trace_id = coresight_trace_id_read_cpu_id_map(drvdata->cpu, id_map);
-	if (!IS_VALID_CS_TRACE_ID(trace_id)) {
-		dev_err(&drvdata->csdev->dev, "Failed to set trace ID for %s on CPU%d\n",
-			dev_name(&drvdata->csdev->dev), drvdata->cpu);
-		return -EINVAL;
-	}
-	drvdata->traceid = (u8)trace_id;
+	drvdata->traceid = path->trace_id;
 
 	/* And enable it */
 	return etm_enable_hw(drvdata);
 }
 
-static int etm_enable_sysfs(struct coresight_device *csdev)
+static int etm_enable_sysfs(struct coresight_device *csdev, struct coresight_path *path)
 {
 	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 	struct etm_enable_arg arg = { };
@@ -521,10 +485,7 @@ static int etm_enable_sysfs(struct coresight_device *csdev)
 
 	spin_lock(&drvdata->spinlock);
 
-	/* sysfs needs to allocate and set a trace ID */
-	ret = etm_read_alloc_trace_id(drvdata);
-	if (ret < 0)
-		goto unlock_enable_sysfs;
+	drvdata->traceid = path->trace_id;
 
 	/*
 	 * Configure the ETM only if the CPU is online.  If it isn't online
@@ -545,7 +506,6 @@ static int etm_enable_sysfs(struct coresight_device *csdev)
 	if (ret)
 		etm_release_trace_id(drvdata);
 
-unlock_enable_sysfs:
 	spin_unlock(&drvdata->spinlock);
 
 	if (!ret)
@@ -554,7 +514,7 @@ static int etm_enable_sysfs(struct coresight_device *csdev)
 }
 
 static int etm_enable(struct coresight_device *csdev, struct perf_event *event,
-		      enum cs_mode mode, struct coresight_trace_id_map *id_map)
+		      enum cs_mode mode, struct coresight_path *path)
 {
 	int ret;
 	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
@@ -566,10 +526,10 @@ static int etm_enable(struct coresight_device *csdev, struct perf_event *event,
 
 	switch (mode) {
 	case CS_MODE_SYSFS:
-		ret = etm_enable_sysfs(csdev);
+		ret = etm_enable_sysfs(csdev, path);
 		break;
 	case CS_MODE_PERF:
-		ret = etm_enable_perf(csdev, event, id_map);
+		ret = etm_enable_perf(csdev, event, path);
 		break;
 	default:
 		ret = -EINVAL;
@@ -697,39 +657,11 @@ static void etm_disable(struct coresight_device *csdev,
 		coresight_set_mode(csdev, CS_MODE_DISABLED);
 }
 
-static int etm_trace_id(struct coresight_device *csdev, enum cs_mode mode,
-			struct coresight_trace_id_map *id_map)
-{
-	struct etm_drvdata *drvdata;
-	int trace_id;
-
-	if (csdev == NULL)
-		return -EINVAL;
-
-	drvdata = dev_get_drvdata(csdev->dev.parent);
-	switch (mode) {
-	case CS_MODE_SYSFS:
-		trace_id = etm_read_alloc_trace_id(drvdata);
-		break;
-	case CS_MODE_PERF:
-		trace_id = coresight_trace_id_read_cpu_id_map(drvdata->cpu, id_map);
-		if (IS_VALID_CS_TRACE_ID(trace_id))
-			drvdata->traceid = (u8)trace_id;
-		break;
-	default:
-		trace_id = -EINVAL;
-		break;
-	}
-
-	return trace_id;
-}
-
-
 static const struct coresight_ops_source etm_source_ops = {
 	.cpu_id		= etm_cpu_id,
 	.enable		= etm_enable,
 	.disable	= etm_disable,
-	.trace_id	= etm_trace_id,
+	.trace_id	= coresight_etm_get_trace_id,
 };
 
 static const struct coresight_ops etm_cs_ops = {
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
index 68c644be9813..b9006451f515 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
@@ -1190,10 +1190,9 @@ static DEVICE_ATTR_RO(cpu);
 static ssize_t traceid_show(struct device *dev,
 			    struct device_attribute *attr, char *buf)
 {
-	int trace_id;
 	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	int trace_id = coresight_etm_get_trace_id(drvdata->csdev, CS_MODE_SYSFS, NULL);
 
-	trace_id = etm_read_alloc_trace_id(drvdata);
 	if (trace_id < 0)
 		return trace_id;
 
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 0ca8868a7ebf..d7e7703123d2 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -232,25 +232,6 @@ static int etm4_cpu_id(struct coresight_device *csdev)
 	return drvdata->cpu;
 }
 
-int etm4_read_alloc_trace_id(struct etmv4_drvdata *drvdata)
-{
-	int trace_id;
-
-	/*
-	 * This will allocate a trace ID to the cpu,
-	 * or return the one currently allocated.
-	 * The trace id function has its own lock
-	 */
-	trace_id = coresight_trace_id_get_cpu_id(drvdata->cpu);
-	if (IS_VALID_CS_TRACE_ID(trace_id))
-		drvdata->trcid = (u8)trace_id;
-	else
-		dev_err(&drvdata->csdev->dev,
-			"Failed to allocate trace ID for %s on CPU%d\n",
-			dev_name(&drvdata->csdev->dev), drvdata->cpu);
-	return trace_id;
-}
-
 void etm4_release_trace_id(struct etmv4_drvdata *drvdata)
 {
 	coresight_trace_id_put_cpu_id(drvdata->cpu);
@@ -753,9 +734,9 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
 
 static int etm4_enable_perf(struct coresight_device *csdev,
 			    struct perf_event *event,
-			    struct coresight_trace_id_map *id_map)
+			    struct coresight_path *path)
 {
-	int ret = 0, trace_id;
+	int ret = 0;
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
 	if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id())) {
@@ -768,22 +749,7 @@ static int etm4_enable_perf(struct coresight_device *csdev,
 	if (ret)
 		goto out;
 
-	/*
-	 * perf allocates cpu ids as part of _setup_aux() - device needs to use
-	 * the allocated ID. This reads the current version without allocation.
-	 *
-	 * This does not use the trace id lock to prevent lock_dep issues
-	 * with perf locks - we know the ID cannot change until perf shuts down
-	 * the session
-	 */
-	trace_id = coresight_trace_id_read_cpu_id_map(drvdata->cpu, id_map);
-	if (!IS_VALID_CS_TRACE_ID(trace_id)) {
-		dev_err(&drvdata->csdev->dev, "Failed to set trace ID for %s on CPU%d\n",
-			dev_name(&drvdata->csdev->dev), drvdata->cpu);
-		ret = -EINVAL;
-		goto out;
-	}
-	drvdata->trcid = (u8)trace_id;
+	drvdata->trcid = path->trace_id;
 
 	/* And enable it */
 	ret = etm4_enable_hw(drvdata);
@@ -792,7 +758,7 @@ static int etm4_enable_perf(struct coresight_device *csdev,
 	return ret;
 }
 
-static int etm4_enable_sysfs(struct coresight_device *csdev)
+static int etm4_enable_sysfs(struct coresight_device *csdev, struct coresight_path *path)
 {
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 	struct etm4_enable_arg arg = { };
@@ -809,10 +775,7 @@ static int etm4_enable_sysfs(struct coresight_device *csdev)
 
 	spin_lock(&drvdata->spinlock);
 
-	/* sysfs needs to read and allocate a trace ID */
-	ret = etm4_read_alloc_trace_id(drvdata);
-	if (ret < 0)
-		goto unlock_sysfs_enable;
+	drvdata->trcid = path->trace_id;
 
 	/*
 	 * Executing etm4_enable_hw on the cpu whose ETM is being enabled
@@ -829,7 +792,6 @@ static int etm4_enable_sysfs(struct coresight_device *csdev)
 	if (ret)
 		etm4_release_trace_id(drvdata);
 
-unlock_sysfs_enable:
 	spin_unlock(&drvdata->spinlock);
 
 	if (!ret)
@@ -838,7 +800,7 @@ static int etm4_enable_sysfs(struct coresight_device *csdev)
 }
 
 static int etm4_enable(struct coresight_device *csdev, struct perf_event *event,
-		       enum cs_mode mode, struct coresight_trace_id_map *id_map)
+		      enum cs_mode mode, struct coresight_path *path)
 {
 	int ret;
 
@@ -849,10 +811,10 @@ static int etm4_enable(struct coresight_device *csdev, struct perf_event *event,
 
 	switch (mode) {
 	case CS_MODE_SYSFS:
-		ret = etm4_enable_sysfs(csdev);
+		ret = etm4_enable_sysfs(csdev, path);
 		break;
 	case CS_MODE_PERF:
-		ret = etm4_enable_perf(csdev, event, id_map);
+		ret = etm4_enable_perf(csdev, event, path);
 		break;
 	default:
 		ret = -EINVAL;
@@ -1025,38 +987,11 @@ static void etm4_disable(struct coresight_device *csdev,
 		coresight_set_mode(csdev, CS_MODE_DISABLED);
 }
 
-static int etm4_trace_id(struct coresight_device *csdev, enum cs_mode mode,
-			 struct coresight_trace_id_map *id_map)
-{
-	struct etmv4_drvdata *drvdata;
-	int trace_id;
-
-	if (csdev == NULL)
-		return -EINVAL;
-
-	drvdata = dev_get_drvdata(csdev->dev.parent);
-	switch (mode) {
-	case CS_MODE_SYSFS:
-		trace_id = etm4_read_alloc_trace_id(drvdata);
-		break;
-	case CS_MODE_PERF:
-		trace_id = coresight_trace_id_read_cpu_id_map(drvdata->cpu, id_map);
-		if (IS_VALID_CS_TRACE_ID(trace_id))
-			drvdata->trcid = (u8)trace_id;
-		break;
-	default:
-		trace_id = -EINVAL;
-		break;
-	}
-
-	return trace_id;
-}
-
 static const struct coresight_ops_source etm4_source_ops = {
 	.cpu_id		= etm4_cpu_id,
 	.enable		= etm4_enable,
 	.disable	= etm4_disable,
-	.trace_id	= etm4_trace_id,
+	.trace_id	= coresight_etm_get_trace_id,
 };
 
 static const struct coresight_ops etm4_cs_ops = {
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index a9f19629f3f8..922c63477db1 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -4,6 +4,7 @@
  * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
  */
 
+#include <linux/coresight.h>
 #include <linux/pid_namespace.h>
 #include <linux/pm_runtime.h>
 #include <linux/sysfs.h>
@@ -2402,10 +2403,9 @@ static ssize_t trctraceid_show(struct device *dev,
 			       struct device_attribute *attr,
 			       char *buf)
 {
-	int trace_id;
 	struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	int trace_id = coresight_etm_get_trace_id(drvdata->csdev, CS_MODE_SYSFS, NULL);
 
-	trace_id = etm4_read_alloc_trace_id(drvdata);
 	if (trace_id < 0)
 		return trace_id;
 
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
index 9e9165f62e81..d70f52ff4606 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -1066,6 +1066,5 @@ static inline bool etm4x_is_ete(struct etmv4_drvdata *drvdata)
 	return drvdata->arch >= ETM_ARCH_ETE;
 }
 
-int etm4_read_alloc_trace_id(struct etmv4_drvdata *drvdata);
 void etm4_release_trace_id(struct etmv4_drvdata *drvdata);
 #endif
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index 7bd43304f461..979b1ae18b55 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -105,17 +105,6 @@ struct cs_buffers {
 	void			**data_pages;
 };
 
-/**
- * struct coresight_path - data needed by enable/disable path
- * @handle:		perf aux handle for ETM.
- * @path:		path from source to sink.
- * @trace_id:		trace_id of the whole path.
- */
-struct coresight_path {
-	struct list_head		*path;
-	u8				trace_id;
-};
-
 static inline void coresight_insert_barrier_packet(void *buf)
 {
 	if (buf)
@@ -160,6 +149,8 @@ int coresight_make_links(struct coresight_device *orig,
 void coresight_remove_links(struct coresight_device *orig,
 			    struct coresight_connection *conn);
 u32 coresight_get_sink_id(struct coresight_device *csdev);
+int coresight_path_assign_trace_id(struct coresight_path *path,
+				  enum cs_mode mode);
 
 #if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM3X)
 extern int etm_readl_cp14(u32 off, unsigned int *val);
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index 13efd5c2e0c4..3dc85c1a2f7e 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -194,8 +194,7 @@ static void stm_enable_hw(struct stm_drvdata *drvdata)
 }
 
 static int stm_enable(struct coresight_device *csdev, struct perf_event *event,
-		      enum cs_mode mode,
-		      __maybe_unused struct coresight_trace_id_map *trace_id)
+		      enum cs_mode mode, struct coresight_path *path)
 {
 	struct stm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
@@ -282,7 +281,7 @@ static void stm_disable(struct coresight_device *csdev,
 }
 
 static int stm_trace_id(struct coresight_device *csdev, enum cs_mode mode,
-			struct coresight_trace_id_map *id_map)
+			struct coresight_device *sink)
 {
 	struct stm_drvdata *drvdata;
 
diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/hwtracing/coresight/coresight-sysfs.c
index f9a6b838726c..09506ca5207e 100644
--- a/drivers/hwtracing/coresight/coresight-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-sysfs.c
@@ -209,6 +209,10 @@ int coresight_enable_sysfs(struct coresight_device *csdev)
 		goto out;
 	}
 
+	ret = coresight_path_assign_trace_id(cs_path, CS_MODE_SYSFS);
+	if (ret < 0)
+		goto err_path;
+
 	ret = coresight_enable_path(cs_path, CS_MODE_SYSFS, NULL);
 	if (ret)
 		goto err_path;
diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
index 3632c1791c96..829dc804d573 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.c
+++ b/drivers/hwtracing/coresight/coresight-tpda.c
@@ -241,7 +241,8 @@ static void tpda_disable(struct coresight_device *csdev,
 	dev_dbg(drvdata->dev, "TPDA inport %d disabled\n", in->dest_port);
 }
 
-static int tpda_trace_id(struct coresight_device *csdev)
+static int tpda_trace_id(struct coresight_device *csdev, enum cs_mode mode,
+			 struct coresight_device *sink)
 {
 	struct tpda_drvdata *drvdata;
 
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index c38f9701665e..f0880a62028f 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -439,8 +439,7 @@ static void __tpdm_enable(struct tpdm_drvdata *drvdata)
 }
 
 static int tpdm_enable(struct coresight_device *csdev, struct perf_event *event,
-		       enum cs_mode mode,
-		       __maybe_unused struct coresight_trace_id_map *id_map)
+		      enum cs_mode mode, struct coresight_path *path)
 {
 	struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index a859fc00eef9..e4d32a239ae5 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -330,6 +330,16 @@ static struct coresight_dev_list (var) = {				\
 
 #define to_coresight_device(d) container_of(d, struct coresight_device, dev)
 
+/**
+ * struct coresight_path - data needed by enable/disable path
+ * @path:		path from source to sink.
+ * @trace_id:		trace_id of the whole path.
+ */
+struct coresight_path {
+	struct list_head		*path;
+	u8				trace_id;
+};
+
 enum cs_mode {
 	CS_MODE_DISABLED,
 	CS_MODE_SYSFS,
@@ -369,7 +379,7 @@ struct coresight_ops_sink {
  * Operations available for links.
  * @enable:	enables flow between iport and oport.
  * @disable:	disables flow between iport and oport.
- * @trace_id:	Collect the traceid.
+ * @trace_id:	alloc or read the traceid.
  */
 struct coresight_ops_link {
 	int (*enable)(struct coresight_device *csdev,
@@ -378,7 +388,8 @@ struct coresight_ops_link {
 	void (*disable)(struct coresight_device *csdev,
 			struct coresight_connection *in,
 			struct coresight_connection *out);
-	int (*trace_id)(struct coresight_device *csdev);
+	int (*trace_id)(struct coresight_device *csdev, enum cs_mode mode,
+			struct coresight_device *sink);
 };
 
 /**
@@ -388,16 +399,16 @@ struct coresight_ops_link {
  *		is associated to.
  * @enable:	enables tracing for a source.
  * @disable:	disables tracing for a source.
- * @trace_id:	collect the traceid.
+ * @trace_id:	alloc or read the traceid.
  */
 struct coresight_ops_source {
 	int (*cpu_id)(struct coresight_device *csdev);
 	int (*enable)(struct coresight_device *csdev, struct perf_event *event,
-		      enum cs_mode mode, struct coresight_trace_id_map *id_map);
+		      enum cs_mode mode, struct coresight_path *path);
 	void (*disable)(struct coresight_device *csdev,
 			struct perf_event *event);
 	int (*trace_id)(struct coresight_device *csdev, enum cs_mode mode,
-			struct coresight_trace_id_map *id_map);
+			struct coresight_device *sink);
 };
 
 /**
@@ -703,4 +714,6 @@ int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
 
 void coresight_remove_driver(struct amba_driver *amba_drv,
 			     struct platform_driver *pdev_drv);
+int coresight_etm_get_trace_id(struct coresight_device *csdev, enum cs_mode mode,
+			       struct coresight_device *sink);
 #endif		/* _LINUX_COREISGHT_H */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH v9 3/6] Coresight: Introduce a new struct coresight_path
  2025-01-24  7:25 ` [PATCH v9 3/6] Coresight: Introduce a new struct coresight_path Jie Gan
  2025-01-28 11:54   ` James Clark
@ 2025-01-31 16:43   ` James Clark
  2025-02-05  4:09     ` Jie Gan
  1 sibling, 1 reply; 24+ messages in thread
From: James Clark @ 2025-01-31 16:43 UTC (permalink / raw)
  To: Jie Gan
  Cc: Tingwei Zhang, Jinlong Mao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32,
	Suzuki K Poulose, Mike Leach, Alexander Shishkin, Maxime Coquelin,
	Alexandre Torgue, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Konrad Dybcio



On 24/01/2025 7:25 am, Jie Gan wrote:
> Add 'struct coresight_path' to store the data that is needed by
> coresight_enable_path/coresight_disable_path. The structure
> will be transmitted to the helper and sink device to enable
> related funcationalities.
> 
> Signed-off-by: Jie Gan <quic_jiegan@quicinc.com>
> ---
[...]
>   	/*
>   	 * If we still have access to the event_data via handle,
> @@ -595,11 +599,11 @@ static void etm_event_stop(struct perf_event *event, int mode)
>   	if (!csdev)
>   		return;
>   
> -	path = etm_event_cpu_path(event_data, cpu);
> -	if (!path)
> +	cs_path = etm_event_cpu_path(event_data, cpu);
> +	if (!cs_path)

I don't think renaming 'path' to 'cs_path' is worth the churn. It's in a 
lot of places in this change, but I think path is already good enough.

>   		return;
>   
> -	sink = coresight_get_sink(path);
> +	sink = coresight_get_sink(cs_path->path);

coresight_get_sink() is always called with cs_path->path, so we might as 
well make it take a whole path struct. The same with any of the other 
functions that operate on path like coresight_get_source().


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v9 3/6] Coresight: Introduce a new struct coresight_path
  2025-01-31 16:43   ` [PATCH v9 3/6] Coresight: Introduce a new struct coresight_path James Clark
@ 2025-02-05  4:09     ` Jie Gan
  0 siblings, 0 replies; 24+ messages in thread
From: Jie Gan @ 2025-02-05  4:09 UTC (permalink / raw)
  To: James Clark
  Cc: Tingwei Zhang, Jinlong Mao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32,
	Suzuki K Poulose, Mike Leach, Alexander Shishkin, Maxime Coquelin,
	Alexandre Torgue, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Konrad Dybcio



On 2/1/2025 12:43 AM, James Clark wrote:
> 
> 
> On 24/01/2025 7:25 am, Jie Gan wrote:
>> Add 'struct coresight_path' to store the data that is needed by
>> coresight_enable_path/coresight_disable_path. The structure
>> will be transmitted to the helper and sink device to enable
>> related funcationalities.
>>
>> Signed-off-by: Jie Gan <quic_jiegan@quicinc.com>
>> ---
> [...]
>>       /*
>>        * If we still have access to the event_data via handle,
>> @@ -595,11 +599,11 @@ static void etm_event_stop(struct perf_event 
>> *event, int mode)
>>       if (!csdev)
>>           return;
>> -    path = etm_event_cpu_path(event_data, cpu);
>> -    if (!path)
>> +    cs_path = etm_event_cpu_path(event_data, cpu);
>> +    if (!cs_path)
> 
> I don't think renaming 'path' to 'cs_path' is worth the churn. It's in a 
> lot of places in this change, but I think path is already good enough.
> 
Yes, agree with you. It seems unnecessary. Will update it.

>>           return;
>> -    sink = coresight_get_sink(path);
>> +    sink = coresight_get_sink(cs_path->path);
> 
> coresight_get_sink() is always called with cs_path->path, so we might as 
> well make it take a whole path struct. The same with any of the other 
> functions that operate on path like coresight_get_source().
It's make sense for me and make codes easy to read. I will update it.

> 

Thanks,
Jie

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 0/3] coresight: Alloc trace ID after building the path
  2025-01-31 16:36       ` [PATCH 0/3] coresight: Alloc trace ID after building the path James Clark
                           ` (2 preceding siblings ...)
  2025-01-31 16:36         ` [PATCH 3/3] coresight: Alloc trace ID after building the path James Clark
@ 2025-02-05  4:13         ` Jie Gan
  2025-02-05  7:44           ` Jie Gan
  3 siblings, 1 reply; 24+ messages in thread
From: Jie Gan @ 2025-02-05  4:13 UTC (permalink / raw)
  To: James Clark
  Cc: quic_tingweiz, quic_jinlmao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32,
	suzuki.poulose, mike.leach, alexander.shishkin, mcoquelin.stm32,
	alexandre.torgue, robh, krzk+dt, conor+dt, andersson, konradybcio



On 2/1/2025 12:36 AM, James Clark wrote:
> Proof of concept to support CTCU device. Applies to Jie's patchset in
> the parent email. I think this would be a good simplification, it
> removes some code and makes things a bit clearer, and works for both the
> old and new CTCU requirements. It will require merging into the parent
> patchset somehow as it undoes some of those changes.
Hi, James

I tested the patch series and it works well.

Can I combine these patchsets with mine with co-developed tag?
Or are you prefer to submit them independently?

I believe it would be easier to read if we combined the codes together.

Thanks,
Jie

> 
> James Clark (3):
>    coresight: Don't save handle in path
>    coresight: Export coresight_get_sink()
>    coresight: Alloc trace ID after building the path
> 
>   drivers/hwtracing/coresight/coresight-core.c  | 107 +++++++++++++-----
>   drivers/hwtracing/coresight/coresight-dummy.c |   9 +-
>   drivers/hwtracing/coresight/coresight-etb10.c |   8 +-
>   .../hwtracing/coresight/coresight-etm-perf.c  |  20 ++--
>   drivers/hwtracing/coresight/coresight-etm.h   |   1 -
>   .../coresight/coresight-etm3x-core.c          |  84 ++------------
>   .../coresight/coresight-etm3x-sysfs.c         |   3 +-
>   .../coresight/coresight-etm4x-core.c          |  83 ++------------
>   .../coresight/coresight-etm4x-sysfs.c         |   4 +-
>   drivers/hwtracing/coresight/coresight-etm4x.h |   1 -
>   drivers/hwtracing/coresight/coresight-priv.h  |  17 +--
>   drivers/hwtracing/coresight/coresight-stm.c   |   5 +-
>   drivers/hwtracing/coresight/coresight-sysfs.c |   6 +-
>   .../hwtracing/coresight/coresight-tmc-etf.c   |   9 +-
>   .../hwtracing/coresight/coresight-tmc-etr.c   |  13 +--
>   drivers/hwtracing/coresight/coresight-tmc.h   |   2 +-
>   drivers/hwtracing/coresight/coresight-tpda.c  |   3 +-
>   drivers/hwtracing/coresight/coresight-tpdm.c  |   3 +-
>   drivers/hwtracing/coresight/coresight-tpiu.c  |   2 +-
>   drivers/hwtracing/coresight/coresight-trbe.c  |   4 +-
>   drivers/hwtracing/coresight/ultrasoc-smb.c    |   8 +-
>   include/linux/coresight.h                     |  25 +++-
>   22 files changed, 159 insertions(+), 258 deletions(-)
> 


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 0/3] coresight: Alloc trace ID after building the path
  2025-02-05  4:13         ` [PATCH 0/3] " Jie Gan
@ 2025-02-05  7:44           ` Jie Gan
  0 siblings, 0 replies; 24+ messages in thread
From: Jie Gan @ 2025-02-05  7:44 UTC (permalink / raw)
  To: James Clark
  Cc: quic_tingweiz, quic_jinlmao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32,
	suzuki.poulose, mike.leach, alexander.shishkin, mcoquelin.stm32,
	alexandre.torgue, robh, krzk+dt, conor+dt, andersson, konradybcio



On 2/5/2025 12:13 PM, Jie Gan wrote:
> 
> 
> On 2/1/2025 12:36 AM, James Clark wrote:
>> Proof of concept to support CTCU device. Applies to Jie's patchset in
>> the parent email. I think this would be a good simplification, it
>> removes some code and makes things a bit clearer, and works for both the
>> old and new CTCU requirements. It will require merging into the parent
>> patchset somehow as it undoes some of those changes.
> Hi, James
> 
> I tested the patch series and it works well.
> 
> Can I combine these patchsets with mine with co-developed tag?
> Or are you prefer to submit them independently?
> 
> I believe it would be easier to read if we combined the codes together.

Hi, James

Please ignore my questions here. I missed the last paragraph of the 
description.

I merged your codes with mine and added co-developed and SOB tag.

Sorry for the mistake.

Thanks,
Jie

> 
>>
>> James Clark (3):
>>    coresight: Don't save handle in path
>>    coresight: Export coresight_get_sink()
>>    coresight: Alloc trace ID after building the path
>>
>>   drivers/hwtracing/coresight/coresight-core.c  | 107 +++++++++++++-----
>>   drivers/hwtracing/coresight/coresight-dummy.c |   9 +-
>>   drivers/hwtracing/coresight/coresight-etb10.c |   8 +-
>>   .../hwtracing/coresight/coresight-etm-perf.c  |  20 ++--
>>   drivers/hwtracing/coresight/coresight-etm.h   |   1 -
>>   .../coresight/coresight-etm3x-core.c          |  84 ++------------
>>   .../coresight/coresight-etm3x-sysfs.c         |   3 +-
>>   .../coresight/coresight-etm4x-core.c          |  83 ++------------
>>   .../coresight/coresight-etm4x-sysfs.c         |   4 +-
>>   drivers/hwtracing/coresight/coresight-etm4x.h |   1 -
>>   drivers/hwtracing/coresight/coresight-priv.h  |  17 +--
>>   drivers/hwtracing/coresight/coresight-stm.c   |   5 +-
>>   drivers/hwtracing/coresight/coresight-sysfs.c |   6 +-
>>   .../hwtracing/coresight/coresight-tmc-etf.c   |   9 +-
>>   .../hwtracing/coresight/coresight-tmc-etr.c   |  13 +--
>>   drivers/hwtracing/coresight/coresight-tmc.h   |   2 +-
>>   drivers/hwtracing/coresight/coresight-tpda.c  |   3 +-
>>   drivers/hwtracing/coresight/coresight-tpdm.c  |   3 +-
>>   drivers/hwtracing/coresight/coresight-tpiu.c  |   2 +-
>>   drivers/hwtracing/coresight/coresight-trbe.c  |   4 +-
>>   drivers/hwtracing/coresight/ultrasoc-smb.c    |   8 +-
>>   include/linux/coresight.h                     |  25 +++-
>>   22 files changed, 159 insertions(+), 258 deletions(-)
>>
> 
> 


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 1/3] coresight: Don't save handle in path
  2025-01-31 16:36         ` [PATCH 1/3] coresight: Don't save handle in path James Clark
@ 2025-02-06  3:02           ` Jie Gan
  2025-02-06 14:34             ` James Clark
  0 siblings, 1 reply; 24+ messages in thread
From: Jie Gan @ 2025-02-06  3:02 UTC (permalink / raw)
  To: James Clark
  Cc: quic_tingweiz, quic_jinlmao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32,
	suzuki.poulose, mike.leach, alexander.shishkin, mcoquelin.stm32,
	alexandre.torgue, robh, krzk+dt, conor+dt, andersson, konradybcio



On 2/1/2025 12:36 AM, James Clark wrote:
> Signed-off-by: James Clark <james.clark@linaro.org>
> ---
>   drivers/hwtracing/coresight/coresight-core.c     | 10 +++++-----
>   drivers/hwtracing/coresight/coresight-dummy.c    |  2 +-
>   drivers/hwtracing/coresight/coresight-etb10.c    |  8 +++-----
>   drivers/hwtracing/coresight/coresight-etm-perf.c |  3 +--
>   drivers/hwtracing/coresight/coresight-priv.h     |  4 ++--
>   drivers/hwtracing/coresight/coresight-sysfs.c    |  2 +-
>   drivers/hwtracing/coresight/coresight-tmc-etf.c  |  9 ++++-----
>   drivers/hwtracing/coresight/coresight-tmc-etr.c  | 13 +++++--------
>   drivers/hwtracing/coresight/coresight-tmc.h      |  2 +-
>   drivers/hwtracing/coresight/coresight-tpiu.c     |  2 +-
>   drivers/hwtracing/coresight/coresight-trbe.c     |  4 +---
>   drivers/hwtracing/coresight/ultrasoc-smb.c       |  8 +++-----
>   include/linux/coresight.h                        |  2 +-
>   13 files changed, 29 insertions(+), 40 deletions(-)
> 

Hi James

I removed the handle from coresight_path and placed these codes in a 
separate patch. However, I believe this change is not related to the 
CTCU driver or coresight_path. Therefore, I suggest we submit it 
independently.

Thanks,
Jie


> diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
> index 11d5d5320b1a..253ef02fde12 100644
> --- a/drivers/hwtracing/coresight/coresight-core.c
> +++ b/drivers/hwtracing/coresight/coresight-core.c
> @@ -272,9 +272,9 @@ void coresight_add_helper(struct coresight_device *csdev,
>   EXPORT_SYMBOL_GPL(coresight_add_helper);
>   
>   static int coresight_enable_sink(struct coresight_device *csdev,
> -				 enum cs_mode mode, void *data)
> +				 enum cs_mode mode, struct perf_output_handle *handle)
>   {
> -	return sink_ops(csdev)->enable(csdev, mode, data);
> +	return sink_ops(csdev)->enable(csdev, mode, handle);
>   }
>   
>   static void coresight_disable_sink(struct coresight_device *csdev)
> @@ -448,7 +448,8 @@ static int coresight_enable_helpers(struct coresight_device *csdev,
>   	return 0;
>   }
>   
> -int coresight_enable_path(struct coresight_path *cs_path, enum cs_mode mode)
> +int coresight_enable_path(struct coresight_path *cs_path, enum cs_mode mode,
> +			  struct perf_output_handle *handle)
>   {
>   	int ret = 0;
>   	u32 type;
> @@ -479,7 +480,7 @@ int coresight_enable_path(struct coresight_path *cs_path, enum cs_mode mode)
>   
>   		switch (type) {
>   		case CORESIGHT_DEV_TYPE_SINK:
> -			ret = coresight_enable_sink(csdev, mode, cs_path);
> +			ret = coresight_enable_sink(csdev, mode, handle);
>   			/*
>   			 * Sink is the first component turned on. If we
>   			 * failed to enable the sink, there are no components
> @@ -807,7 +808,6 @@ void coresight_release_path(struct coresight_path *cs_path)
>   		kfree(nd);
>   	}
>   
> -	cs_path->handle = NULL;
>   	kfree(cs_path->path);
>   	kfree(cs_path);
>   }
> diff --git a/drivers/hwtracing/coresight/coresight-dummy.c b/drivers/hwtracing/coresight/coresight-dummy.c
> index dfcf24e9c49a..6f86d33efef4 100644
> --- a/drivers/hwtracing/coresight/coresight-dummy.c
> +++ b/drivers/hwtracing/coresight/coresight-dummy.c
> @@ -54,7 +54,7 @@ static int dummy_source_trace_id(struct coresight_device *csdev, enum cs_mode mo
>   }
>   
>   static int dummy_sink_enable(struct coresight_device *csdev, enum cs_mode mode,
> -				void *data)
> +				struct perf_output_handle *handle)
>   {
>   	dev_dbg(csdev->dev.parent, "Dummy sink enabled\n");
>   
> diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
> index 05430d8931d1..e373b0f590bf 100644
> --- a/drivers/hwtracing/coresight/coresight-etb10.c
> +++ b/drivers/hwtracing/coresight/coresight-etb10.c
> @@ -167,14 +167,12 @@ static int etb_enable_sysfs(struct coresight_device *csdev)
>   	return ret;
>   }
>   
> -static int etb_enable_perf(struct coresight_device *csdev, void *data)
> +static int etb_enable_perf(struct coresight_device *csdev, struct perf_output_handle *handle)
>   {
>   	int ret = 0;
>   	pid_t pid;
>   	unsigned long flags;
>   	struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> -	struct coresight_path *cs_path = (struct coresight_path *)data;
> -	struct perf_output_handle *handle = cs_path->handle;
>   	struct cs_buffers *buf = etm_perf_sink_config(handle);
>   
>   	spin_lock_irqsave(&drvdata->spinlock, flags);
> @@ -225,7 +223,7 @@ static int etb_enable_perf(struct coresight_device *csdev, void *data)
>   }
>   
>   static int etb_enable(struct coresight_device *csdev, enum cs_mode mode,
> -		      void *data)
> +		      struct perf_output_handle *handle)
>   {
>   	int ret;
>   
> @@ -234,7 +232,7 @@ static int etb_enable(struct coresight_device *csdev, enum cs_mode mode,
>   		ret = etb_enable_sysfs(csdev);
>   		break;
>   	case CS_MODE_PERF:
> -		ret = etb_enable_perf(csdev, data);
> +		ret = etb_enable_perf(csdev, handle);
>   		break;
>   	default:
>   		ret = -EINVAL;
> diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
> index b6765abb0a26..0fad9968c2c0 100644
> --- a/drivers/hwtracing/coresight/coresight-etm-perf.c
> +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
> @@ -501,9 +501,8 @@ static void etm_event_start(struct perf_event *event, int flags)
>   	if (WARN_ON_ONCE(!sink))
>   		goto fail_end_stop;
>   
> -	cs_path->handle = handle;
>   	/* Nothing will happen without a path */
> -	if (coresight_enable_path(cs_path, CS_MODE_PERF))
> +	if (coresight_enable_path(cs_path, CS_MODE_PERF, handle))
>   		goto fail_end_stop;
>   
>   	/* Finally enable the tracer */
> diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
> index 8e02a222b9f8..7bd43304f461 100644
> --- a/drivers/hwtracing/coresight/coresight-priv.h
> +++ b/drivers/hwtracing/coresight/coresight-priv.h
> @@ -112,7 +112,6 @@ struct cs_buffers {
>    * @trace_id:		trace_id of the whole path.
>    */
>   struct coresight_path {
> -	struct perf_output_handle	*handle;
>   	struct list_head		*path;
>   	u8				trace_id;
>   };
> @@ -142,7 +141,8 @@ static inline void CS_UNLOCK(void __iomem *addr)
>   }
>   
>   void coresight_disable_path(struct coresight_path *cs_path);
> -int coresight_enable_path(struct coresight_path *cs_path, enum cs_mode mode);
> +int coresight_enable_path(struct coresight_path *cs_path, enum cs_mode mode,
> +			  struct perf_output_handle *handle);
>   struct coresight_device *coresight_get_sink(struct list_head *path);
>   struct coresight_device *coresight_get_sink_by_id(u32 id);
>   struct coresight_device *
> diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/hwtracing/coresight/coresight-sysfs.c
> index 04e76cc1bfdf..f9a6b838726c 100644
> --- a/drivers/hwtracing/coresight/coresight-sysfs.c
> +++ b/drivers/hwtracing/coresight/coresight-sysfs.c
> @@ -209,7 +209,7 @@ int coresight_enable_sysfs(struct coresight_device *csdev)
>   		goto out;
>   	}
>   
> -	ret = coresight_enable_path(cs_path, CS_MODE_SYSFS);
> +	ret = coresight_enable_path(cs_path, CS_MODE_SYSFS, NULL);
>   	if (ret)
>   		goto err_path;
>   
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
> index e6b07f917556..fdf1c2511d67 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
> @@ -244,14 +244,13 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
>   	return ret;
>   }
>   
> -static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
> +static int tmc_enable_etf_sink_perf(struct coresight_device *csdev,
> +				    struct perf_output_handle *handle)
>   {
>   	int ret = 0;
>   	pid_t pid;
>   	unsigned long flags;
>   	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> -	struct coresight_path *cs_path= (struct coresight_path *)data;
> -	struct perf_output_handle *handle = cs_path->handle;
>   	struct cs_buffers *buf = etm_perf_sink_config(handle);
>   
>   	spin_lock_irqsave(&drvdata->spinlock, flags);
> @@ -303,7 +302,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
>   }
>   
>   static int tmc_enable_etf_sink(struct coresight_device *csdev,
> -			       enum cs_mode mode, void *data)
> +			       enum cs_mode mode, struct perf_output_handle *handle)
>   {
>   	int ret;
>   
> @@ -312,7 +311,7 @@ static int tmc_enable_etf_sink(struct coresight_device *csdev,
>   		ret = tmc_enable_etf_sink_sysfs(csdev);
>   		break;
>   	case CS_MODE_PERF:
> -		ret = tmc_enable_etf_sink_perf(csdev, data);
> +		ret = tmc_enable_etf_sink_perf(csdev, handle);
>   		break;
>   	/* We shouldn't be here */
>   	default:
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> index 82a872882e24..2d0bd06bab2a 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> @@ -1252,10 +1252,8 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
>   }
>   
>   struct etr_buf *tmc_etr_get_buffer(struct coresight_device *csdev,
> -				   enum cs_mode mode, void *data)
> +				   enum cs_mode mode, struct perf_output_handle *handle)
>   {
> -	struct coresight_path *cs_path = (struct coresight_path *)data;
> -	struct perf_output_handle *handle = cs_path->handle;
>   	struct etr_perf_buffer *etr_perf;
>   
>   	switch (mode) {
> @@ -1643,14 +1641,13 @@ tmc_update_etr_buffer(struct coresight_device *csdev,
>   	return size;
>   }
>   
> -static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
> +static int tmc_enable_etr_sink_perf(struct coresight_device *csdev,
> +				    struct perf_output_handle *handle)
>   {
>   	int rc = 0;
>   	pid_t pid;
>   	unsigned long flags;
>   	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> -	struct coresight_path *cs_path = (struct coresight_path *)data;
> -	struct perf_output_handle *handle = cs_path->handle;
>   	struct etr_perf_buffer *etr_perf = etm_perf_sink_config(handle);
>   
>   	spin_lock_irqsave(&drvdata->spinlock, flags);
> @@ -1698,13 +1695,13 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
>   }
>   
>   static int tmc_enable_etr_sink(struct coresight_device *csdev,
> -			       enum cs_mode mode, void *data)
> +			       enum cs_mode mode, struct perf_output_handle *handle)
>   {
>   	switch (mode) {
>   	case CS_MODE_SYSFS:
>   		return tmc_enable_etr_sink_sysfs(csdev);
>   	case CS_MODE_PERF:
> -		return tmc_enable_etr_sink_perf(csdev, data);
> +		return tmc_enable_etr_sink_perf(csdev, handle);
>   	default:
>   		return -EINVAL;
>   	}
> diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
> index 2671926be62a..e991afd43742 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc.h
> +++ b/drivers/hwtracing/coresight/coresight-tmc.h
> @@ -336,7 +336,7 @@ struct coresight_device *tmc_etr_get_catu_device(struct tmc_drvdata *drvdata);
>   void tmc_etr_set_catu_ops(const struct etr_buf_operations *catu);
>   void tmc_etr_remove_catu_ops(void);
>   struct etr_buf *tmc_etr_get_buffer(struct coresight_device *csdev,
> -				   enum cs_mode mode, void *data);
> +				   enum cs_mode mode, struct perf_output_handle *handle);
>   extern const struct attribute_group coresight_etr_group;
>   
>   #endif
> diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
> index 97ef36f03ec2..ccf463ac7bf5 100644
> --- a/drivers/hwtracing/coresight/coresight-tpiu.c
> +++ b/drivers/hwtracing/coresight/coresight-tpiu.c
> @@ -75,7 +75,7 @@ static void tpiu_enable_hw(struct csdev_access *csa)
>   }
>   
>   static int tpiu_enable(struct coresight_device *csdev, enum cs_mode mode,
> -		       void *__unused)
> +		       struct perf_output_handle *__unused)
>   {
>   	struct tpiu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>   
> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
> index 5005efd88a66..997d5976d2d2 100644
> --- a/drivers/hwtracing/coresight/coresight-trbe.c
> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
> @@ -1009,12 +1009,10 @@ static int __arm_trbe_enable(struct trbe_buf *buf,
>   }
>   
>   static int arm_trbe_enable(struct coresight_device *csdev, enum cs_mode mode,
> -			   void *data)
> +			   struct perf_output_handle *handle)
>   {
>   	struct trbe_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>   	struct trbe_cpudata *cpudata = dev_get_drvdata(&csdev->dev);
> -	struct coresight_path *cs_path = (struct coresight_path *)data;
> -	struct perf_output_handle *handle = cs_path->handle;
>   	struct trbe_buf *buf = etm_perf_sink_config(handle);
>   
>   	WARN_ON(cpudata->cpu != smp_processor_id());
> diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/hwtracing/coresight/ultrasoc-smb.c
> index 9be88394b3bb..1574b5067206 100644
> --- a/drivers/hwtracing/coresight/ultrasoc-smb.c
> +++ b/drivers/hwtracing/coresight/ultrasoc-smb.c
> @@ -213,11 +213,9 @@ static void smb_enable_sysfs(struct coresight_device *csdev)
>   	coresight_set_mode(csdev, CS_MODE_SYSFS);
>   }
>   
> -static int smb_enable_perf(struct coresight_device *csdev, void *data)
> +static int smb_enable_perf(struct coresight_device *csdev, struct perf_output_handle *handle)
>   {
>   	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
> -	struct coresight_path *cs_path = (struct coresight_path *)data;
> -	struct perf_output_handle *handle = cs_path->handle;
>   	struct cs_buffers *buf = etm_perf_sink_config(handle);
>   	pid_t pid;
>   
> @@ -241,7 +239,7 @@ static int smb_enable_perf(struct coresight_device *csdev, void *data)
>   }
>   
>   static int smb_enable(struct coresight_device *csdev, enum cs_mode mode,
> -		      void *data)
> +		      struct perf_output_handle *handle)
>   {
>   	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
>   	int ret = 0;
> @@ -262,7 +260,7 @@ static int smb_enable(struct coresight_device *csdev, enum cs_mode mode,
>   		smb_enable_sysfs(csdev);
>   		break;
>   	case CS_MODE_PERF:
> -		ret = smb_enable_perf(csdev, data);
> +		ret = smb_enable_perf(csdev, handle);
>   		break;
>   	default:
>   		ret = -EINVAL;
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index 87f9baa7fefe..a859fc00eef9 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -353,7 +353,7 @@ enum cs_mode {
>    */
>   struct coresight_ops_sink {
>   	int (*enable)(struct coresight_device *csdev, enum cs_mode mode,
> -		      void *data);
> +		      struct perf_output_handle *handle);
>   	int (*disable)(struct coresight_device *csdev);
>   	void *(*alloc_buffer)(struct coresight_device *csdev,
>   			      struct perf_event *event, void **pages,


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 1/3] coresight: Don't save handle in path
  2025-02-06  3:02           ` Jie Gan
@ 2025-02-06 14:34             ` James Clark
  0 siblings, 0 replies; 24+ messages in thread
From: James Clark @ 2025-02-06 14:34 UTC (permalink / raw)
  To: Jie Gan
  Cc: quic_tingweiz, quic_jinlmao, coresight, linux-arm-kernel,
	linux-kernel, devicetree, linux-arm-msm, linux-stm32,
	suzuki.poulose, mike.leach, alexander.shishkin, mcoquelin.stm32,
	alexandre.torgue, robh, krzk+dt, conor+dt, andersson, konradybcio



On 06/02/2025 3:02 am, Jie Gan wrote:
> 
> 
> On 2/1/2025 12:36 AM, James Clark wrote:
>> Signed-off-by: James Clark <james.clark@linaro.org>
>> ---
>>   drivers/hwtracing/coresight/coresight-core.c     | 10 +++++-----
>>   drivers/hwtracing/coresight/coresight-dummy.c    |  2 +-
>>   drivers/hwtracing/coresight/coresight-etb10.c    |  8 +++-----
>>   drivers/hwtracing/coresight/coresight-etm-perf.c |  3 +--
>>   drivers/hwtracing/coresight/coresight-priv.h     |  4 ++--
>>   drivers/hwtracing/coresight/coresight-sysfs.c    |  2 +-
>>   drivers/hwtracing/coresight/coresight-tmc-etf.c  |  9 ++++-----
>>   drivers/hwtracing/coresight/coresight-tmc-etr.c  | 13 +++++--------
>>   drivers/hwtracing/coresight/coresight-tmc.h      |  2 +-
>>   drivers/hwtracing/coresight/coresight-tpiu.c     |  2 +-
>>   drivers/hwtracing/coresight/coresight-trbe.c     |  4 +---
>>   drivers/hwtracing/coresight/ultrasoc-smb.c       |  8 +++-----
>>   include/linux/coresight.h                        |  2 +-
>>   13 files changed, 29 insertions(+), 40 deletions(-)
>>
> 
> Hi James
> 
> I removed the handle from coresight_path and placed these codes in a 
> separate patch. However, I believe this change is not related to the 
> CTCU driver or coresight_path. Therefore, I suggest we submit it 
> independently.
> 
> Thanks,
> Jie
> 
> 

Yeah if you've removed the handle from the path then we can do the other 
void* changes separately. Makes sense.

>> diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/ 
>> hwtracing/coresight/coresight-core.c
>> index 11d5d5320b1a..253ef02fde12 100644
>> --- a/drivers/hwtracing/coresight/coresight-core.c
>> +++ b/drivers/hwtracing/coresight/coresight-core.c
>> @@ -272,9 +272,9 @@ void coresight_add_helper(struct coresight_device 
>> *csdev,
>>   EXPORT_SYMBOL_GPL(coresight_add_helper);
>>   static int coresight_enable_sink(struct coresight_device *csdev,
>> -                 enum cs_mode mode, void *data)
>> +                 enum cs_mode mode, struct perf_output_handle *handle)
>>   {
>> -    return sink_ops(csdev)->enable(csdev, mode, data);
>> +    return sink_ops(csdev)->enable(csdev, mode, handle);
>>   }
>>   static void coresight_disable_sink(struct coresight_device *csdev)
>> @@ -448,7 +448,8 @@ static int coresight_enable_helpers(struct 
>> coresight_device *csdev,
>>       return 0;
>>   }
>> -int coresight_enable_path(struct coresight_path *cs_path, enum 
>> cs_mode mode)
>> +int coresight_enable_path(struct coresight_path *cs_path, enum 
>> cs_mode mode,
>> +              struct perf_output_handle *handle)
>>   {
>>       int ret = 0;
>>       u32 type;
>> @@ -479,7 +480,7 @@ int coresight_enable_path(struct coresight_path 
>> *cs_path, enum cs_mode mode)
>>           switch (type) {
>>           case CORESIGHT_DEV_TYPE_SINK:
>> -            ret = coresight_enable_sink(csdev, mode, cs_path);
>> +            ret = coresight_enable_sink(csdev, mode, handle);
>>               /*
>>                * Sink is the first component turned on. If we
>>                * failed to enable the sink, there are no components
>> @@ -807,7 +808,6 @@ void coresight_release_path(struct coresight_path 
>> *cs_path)
>>           kfree(nd);
>>       }
>> -    cs_path->handle = NULL;
>>       kfree(cs_path->path);
>>       kfree(cs_path);
>>   }
>> diff --git a/drivers/hwtracing/coresight/coresight-dummy.c b/drivers/ 
>> hwtracing/coresight/coresight-dummy.c
>> index dfcf24e9c49a..6f86d33efef4 100644
>> --- a/drivers/hwtracing/coresight/coresight-dummy.c
>> +++ b/drivers/hwtracing/coresight/coresight-dummy.c
>> @@ -54,7 +54,7 @@ static int dummy_source_trace_id(struct 
>> coresight_device *csdev, enum cs_mode mo
>>   }
>>   static int dummy_sink_enable(struct coresight_device *csdev, enum 
>> cs_mode mode,
>> -                void *data)
>> +                struct perf_output_handle *handle)
>>   {
>>       dev_dbg(csdev->dev.parent, "Dummy sink enabled\n");
>> diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/ 
>> hwtracing/coresight/coresight-etb10.c
>> index 05430d8931d1..e373b0f590bf 100644
>> --- a/drivers/hwtracing/coresight/coresight-etb10.c
>> +++ b/drivers/hwtracing/coresight/coresight-etb10.c
>> @@ -167,14 +167,12 @@ static int etb_enable_sysfs(struct 
>> coresight_device *csdev)
>>       return ret;
>>   }
>> -static int etb_enable_perf(struct coresight_device *csdev, void *data)
>> +static int etb_enable_perf(struct coresight_device *csdev, struct 
>> perf_output_handle *handle)
>>   {
>>       int ret = 0;
>>       pid_t pid;
>>       unsigned long flags;
>>       struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>> -    struct coresight_path *cs_path = (struct coresight_path *)data;
>> -    struct perf_output_handle *handle = cs_path->handle;
>>       struct cs_buffers *buf = etm_perf_sink_config(handle);
>>       spin_lock_irqsave(&drvdata->spinlock, flags);
>> @@ -225,7 +223,7 @@ static int etb_enable_perf(struct coresight_device 
>> *csdev, void *data)
>>   }
>>   static int etb_enable(struct coresight_device *csdev, enum cs_mode 
>> mode,
>> -              void *data)
>> +              struct perf_output_handle *handle)
>>   {
>>       int ret;
>> @@ -234,7 +232,7 @@ static int etb_enable(struct coresight_device 
>> *csdev, enum cs_mode mode,
>>           ret = etb_enable_sysfs(csdev);
>>           break;
>>       case CS_MODE_PERF:
>> -        ret = etb_enable_perf(csdev, data);
>> +        ret = etb_enable_perf(csdev, handle);
>>           break;
>>       default:
>>           ret = -EINVAL;
>> diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/ 
>> drivers/hwtracing/coresight/coresight-etm-perf.c
>> index b6765abb0a26..0fad9968c2c0 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm-perf.c
>> +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
>> @@ -501,9 +501,8 @@ static void etm_event_start(struct perf_event 
>> *event, int flags)
>>       if (WARN_ON_ONCE(!sink))
>>           goto fail_end_stop;
>> -    cs_path->handle = handle;
>>       /* Nothing will happen without a path */
>> -    if (coresight_enable_path(cs_path, CS_MODE_PERF))
>> +    if (coresight_enable_path(cs_path, CS_MODE_PERF, handle))
>>           goto fail_end_stop;
>>       /* Finally enable the tracer */
>> diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/ 
>> hwtracing/coresight/coresight-priv.h
>> index 8e02a222b9f8..7bd43304f461 100644
>> --- a/drivers/hwtracing/coresight/coresight-priv.h
>> +++ b/drivers/hwtracing/coresight/coresight-priv.h
>> @@ -112,7 +112,6 @@ struct cs_buffers {
>>    * @trace_id:        trace_id of the whole path.
>>    */
>>   struct coresight_path {
>> -    struct perf_output_handle    *handle;
>>       struct list_head        *path;
>>       u8                trace_id;
>>   };
>> @@ -142,7 +141,8 @@ static inline void CS_UNLOCK(void __iomem *addr)
>>   }
>>   void coresight_disable_path(struct coresight_path *cs_path);
>> -int coresight_enable_path(struct coresight_path *cs_path, enum 
>> cs_mode mode);
>> +int coresight_enable_path(struct coresight_path *cs_path, enum 
>> cs_mode mode,
>> +              struct perf_output_handle *handle);
>>   struct coresight_device *coresight_get_sink(struct list_head *path);
>>   struct coresight_device *coresight_get_sink_by_id(u32 id);
>>   struct coresight_device *
>> diff --git a/drivers/hwtracing/coresight/coresight-sysfs.c b/drivers/ 
>> hwtracing/coresight/coresight-sysfs.c
>> index 04e76cc1bfdf..f9a6b838726c 100644
>> --- a/drivers/hwtracing/coresight/coresight-sysfs.c
>> +++ b/drivers/hwtracing/coresight/coresight-sysfs.c
>> @@ -209,7 +209,7 @@ int coresight_enable_sysfs(struct coresight_device 
>> *csdev)
>>           goto out;
>>       }
>> -    ret = coresight_enable_path(cs_path, CS_MODE_SYSFS);
>> +    ret = coresight_enable_path(cs_path, CS_MODE_SYSFS, NULL);
>>       if (ret)
>>           goto err_path;
>> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/ 
>> drivers/hwtracing/coresight/coresight-tmc-etf.c
>> index e6b07f917556..fdf1c2511d67 100644
>> --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
>> +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
>> @@ -244,14 +244,13 @@ static int tmc_enable_etf_sink_sysfs(struct 
>> coresight_device *csdev)
>>       return ret;
>>   }
>> -static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, 
>> void *data)
>> +static int tmc_enable_etf_sink_perf(struct coresight_device *csdev,
>> +                    struct perf_output_handle *handle)
>>   {
>>       int ret = 0;
>>       pid_t pid;
>>       unsigned long flags;
>>       struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>> -    struct coresight_path *cs_path= (struct coresight_path *)data;
>> -    struct perf_output_handle *handle = cs_path->handle;
>>       struct cs_buffers *buf = etm_perf_sink_config(handle);
>>       spin_lock_irqsave(&drvdata->spinlock, flags);
>> @@ -303,7 +302,7 @@ static int tmc_enable_etf_sink_perf(struct 
>> coresight_device *csdev, void *data)
>>   }
>>   static int tmc_enable_etf_sink(struct coresight_device *csdev,
>> -                   enum cs_mode mode, void *data)
>> +                   enum cs_mode mode, struct perf_output_handle *handle)
>>   {
>>       int ret;
>> @@ -312,7 +311,7 @@ static int tmc_enable_etf_sink(struct 
>> coresight_device *csdev,
>>           ret = tmc_enable_etf_sink_sysfs(csdev);
>>           break;
>>       case CS_MODE_PERF:
>> -        ret = tmc_enable_etf_sink_perf(csdev, data);
>> +        ret = tmc_enable_etf_sink_perf(csdev, handle);
>>           break;
>>       /* We shouldn't be here */
>>       default:
>> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/ 
>> drivers/hwtracing/coresight/coresight-tmc-etr.c
>> index 82a872882e24..2d0bd06bab2a 100644
>> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
>> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
>> @@ -1252,10 +1252,8 @@ static int tmc_enable_etr_sink_sysfs(struct 
>> coresight_device *csdev)
>>   }
>>   struct etr_buf *tmc_etr_get_buffer(struct coresight_device *csdev,
>> -                   enum cs_mode mode, void *data)
>> +                   enum cs_mode mode, struct perf_output_handle *handle)
>>   {
>> -    struct coresight_path *cs_path = (struct coresight_path *)data;
>> -    struct perf_output_handle *handle = cs_path->handle;
>>       struct etr_perf_buffer *etr_perf;
>>       switch (mode) {
>> @@ -1643,14 +1641,13 @@ tmc_update_etr_buffer(struct coresight_device 
>> *csdev,
>>       return size;
>>   }
>> -static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, 
>> void *data)
>> +static int tmc_enable_etr_sink_perf(struct coresight_device *csdev,
>> +                    struct perf_output_handle *handle)
>>   {
>>       int rc = 0;
>>       pid_t pid;
>>       unsigned long flags;
>>       struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>> -    struct coresight_path *cs_path = (struct coresight_path *)data;
>> -    struct perf_output_handle *handle = cs_path->handle;
>>       struct etr_perf_buffer *etr_perf = etm_perf_sink_config(handle);
>>       spin_lock_irqsave(&drvdata->spinlock, flags);
>> @@ -1698,13 +1695,13 @@ static int tmc_enable_etr_sink_perf(struct 
>> coresight_device *csdev, void *data)
>>   }
>>   static int tmc_enable_etr_sink(struct coresight_device *csdev,
>> -                   enum cs_mode mode, void *data)
>> +                   enum cs_mode mode, struct perf_output_handle *handle)
>>   {
>>       switch (mode) {
>>       case CS_MODE_SYSFS:
>>           return tmc_enable_etr_sink_sysfs(csdev);
>>       case CS_MODE_PERF:
>> -        return tmc_enable_etr_sink_perf(csdev, data);
>> +        return tmc_enable_etr_sink_perf(csdev, handle);
>>       default:
>>           return -EINVAL;
>>       }
>> diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/ 
>> hwtracing/coresight/coresight-tmc.h
>> index 2671926be62a..e991afd43742 100644
>> --- a/drivers/hwtracing/coresight/coresight-tmc.h
>> +++ b/drivers/hwtracing/coresight/coresight-tmc.h
>> @@ -336,7 +336,7 @@ struct coresight_device 
>> *tmc_etr_get_catu_device(struct tmc_drvdata *drvdata);
>>   void tmc_etr_set_catu_ops(const struct etr_buf_operations *catu);
>>   void tmc_etr_remove_catu_ops(void);
>>   struct etr_buf *tmc_etr_get_buffer(struct coresight_device *csdev,
>> -                   enum cs_mode mode, void *data);
>> +                   enum cs_mode mode, struct perf_output_handle 
>> *handle);
>>   extern const struct attribute_group coresight_etr_group;
>>   #endif
>> diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/ 
>> hwtracing/coresight/coresight-tpiu.c
>> index 97ef36f03ec2..ccf463ac7bf5 100644
>> --- a/drivers/hwtracing/coresight/coresight-tpiu.c
>> +++ b/drivers/hwtracing/coresight/coresight-tpiu.c
>> @@ -75,7 +75,7 @@ static void tpiu_enable_hw(struct csdev_access *csa)
>>   }
>>   static int tpiu_enable(struct coresight_device *csdev, enum cs_mode 
>> mode,
>> -               void *__unused)
>> +               struct perf_output_handle *__unused)
>>   {
>>       struct tpiu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/ 
>> hwtracing/coresight/coresight-trbe.c
>> index 5005efd88a66..997d5976d2d2 100644
>> --- a/drivers/hwtracing/coresight/coresight-trbe.c
>> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
>> @@ -1009,12 +1009,10 @@ static int __arm_trbe_enable(struct trbe_buf 
>> *buf,
>>   }
>>   static int arm_trbe_enable(struct coresight_device *csdev, enum 
>> cs_mode mode,
>> -               void *data)
>> +               struct perf_output_handle *handle)
>>   {
>>       struct trbe_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>>       struct trbe_cpudata *cpudata = dev_get_drvdata(&csdev->dev);
>> -    struct coresight_path *cs_path = (struct coresight_path *)data;
>> -    struct perf_output_handle *handle = cs_path->handle;
>>       struct trbe_buf *buf = etm_perf_sink_config(handle);
>>       WARN_ON(cpudata->cpu != smp_processor_id());
>> diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/ 
>> hwtracing/coresight/ultrasoc-smb.c
>> index 9be88394b3bb..1574b5067206 100644
>> --- a/drivers/hwtracing/coresight/ultrasoc-smb.c
>> +++ b/drivers/hwtracing/coresight/ultrasoc-smb.c
>> @@ -213,11 +213,9 @@ static void smb_enable_sysfs(struct 
>> coresight_device *csdev)
>>       coresight_set_mode(csdev, CS_MODE_SYSFS);
>>   }
>> -static int smb_enable_perf(struct coresight_device *csdev, void *data)
>> +static int smb_enable_perf(struct coresight_device *csdev, struct 
>> perf_output_handle *handle)
>>   {
>>       struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
>> -    struct coresight_path *cs_path = (struct coresight_path *)data;
>> -    struct perf_output_handle *handle = cs_path->handle;
>>       struct cs_buffers *buf = etm_perf_sink_config(handle);
>>       pid_t pid;
>> @@ -241,7 +239,7 @@ static int smb_enable_perf(struct coresight_device 
>> *csdev, void *data)
>>   }
>>   static int smb_enable(struct coresight_device *csdev, enum cs_mode 
>> mode,
>> -              void *data)
>> +              struct perf_output_handle *handle)
>>   {
>>       struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
>>       int ret = 0;
>> @@ -262,7 +260,7 @@ static int smb_enable(struct coresight_device 
>> *csdev, enum cs_mode mode,
>>           smb_enable_sysfs(csdev);
>>           break;
>>       case CS_MODE_PERF:
>> -        ret = smb_enable_perf(csdev, data);
>> +        ret = smb_enable_perf(csdev, handle);
>>           break;
>>       default:
>>           ret = -EINVAL;
>> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
>> index 87f9baa7fefe..a859fc00eef9 100644
>> --- a/include/linux/coresight.h
>> +++ b/include/linux/coresight.h
>> @@ -353,7 +353,7 @@ enum cs_mode {
>>    */
>>   struct coresight_ops_sink {
>>       int (*enable)(struct coresight_device *csdev, enum cs_mode mode,
>> -              void *data);
>> +              struct perf_output_handle *handle);
>>       int (*disable)(struct coresight_device *csdev);
>>       void *(*alloc_buffer)(struct coresight_device *csdev,
>>                     struct perf_event *event, void **pages,
> 


^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2025-02-06 14:34 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-24  7:25 [PATCH v9 0/6] Coresight: Add Coresight TMC Control Unit driver Jie Gan
2025-01-24  7:25 ` [PATCH v9 1/6] Coresight: Add support for new APB clock name Jie Gan
2025-01-24  7:25 ` [PATCH v9 2/6] Coresight: Add trace_id function to retrieving the trace ID Jie Gan
2025-01-24  7:25 ` [PATCH v9 3/6] Coresight: Introduce a new struct coresight_path Jie Gan
2025-01-28 11:54   ` James Clark
2025-01-29  0:57     ` Jie Gan
2025-01-31 16:36       ` [PATCH 0/3] coresight: Alloc trace ID after building the path James Clark
2025-01-31 16:36         ` [PATCH 1/3] coresight: Don't save handle in path James Clark
2025-02-06  3:02           ` Jie Gan
2025-02-06 14:34             ` James Clark
2025-01-31 16:36         ` [PATCH 2/3] coresight: Export coresight_get_sink() James Clark
2025-01-31 16:36         ` [PATCH 3/3] coresight: Alloc trace ID after building the path James Clark
2025-02-05  4:13         ` [PATCH 0/3] " Jie Gan
2025-02-05  7:44           ` Jie Gan
2025-01-31 16:43   ` [PATCH v9 3/6] Coresight: Introduce a new struct coresight_path James Clark
2025-02-05  4:09     ` Jie Gan
2025-01-24  7:25 ` [PATCH v9 4/6] dt-bindings: arm: Add Coresight TMC Control Unit hardware Jie Gan
2025-01-24  7:25 ` [PATCH v9 5/6] Coresight: Add Coresight TMC Control Unit driver Jie Gan
2025-01-28 11:55   ` James Clark
2025-01-29  0:46     ` Jie Gan
2025-01-29 10:35       ` James Clark
2025-01-29 13:02         ` Jie Gan
2025-01-29 14:07           ` James Clark
2025-01-24  7:25 ` [PATCH v9 6/6] arm64: dts: qcom: sa8775p: Add CTCU and ETR nodes Jie Gan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).