public inbox for devicetree@vger.kernel.org
 help / color / mirror / Atom feed
From: Yuanfang Zhang <yuanfang.zhang@oss.qualcomm.com>
To: Suzuki K Poulose <suzuki.poulose@arm.com>,
	Mike Leach <mike.leach@linaro.org>,
	James Clark <james.clark@linaro.org>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Mathieu Poirier <mathieu.poirier@linaro.org>,
	Leo Yan <leo.yan@linux.dev>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Bjorn Andersson <andersson@kernel.org>,
	Konrad Dybcio <konradybcio@kernel.org>
Cc: kernel@oss.qualcomm.com, coresight@lists.linaro.org,
	linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
	Yuanfang Zhang <yuanfang.zhang@oss.qualcomm.com>,
	maulik.shah@oss.qualcomm.com
Subject: [PATCH v2 08/12] coresight-tmc-etf: Refactor enable function for CPU cluster ETF support
Date: Thu, 18 Dec 2025 00:09:48 -0800	[thread overview]
Message-ID: <20251218-cpu_cluster_component_pm-v2-8-2335a6ae62a0@oss.qualcomm.com> (raw)
In-Reply-To: <20251218-cpu_cluster_component_pm-v2-0-2335a6ae62a0@oss.qualcomm.com>

TMC-ETF devices associated with specific CPU clusters share the cluster's
power domain. Accessing their registers requires the cluster to be powered
on, which can only be guaranteed by running code on a CPU within that
cluster.

Refactor the enablement logic to support this requirement:
1. Split `tmc_etf_enable_hw` and `tmc_etb_enable_hw` into local and
   SMP-aware variants:
   - `*_local`: Performs the actual register access.
   - `*_smp_call`: Wrapper for `smp_call_function_single`.
   - The main entry point now detects if the device is CPU-bound and uses
     `smp_call_function_single` to execute the local variant on an
     appropriate CPU if necessary.

2. Adjust locking in `tmc_enable_etf_sink_sysfs` and `tmc_enable_etf_link`:
   - Drop the spinlock before calling `tmc_etf_enable_hw`. This is
     necessary because `smp_call_function_single` (used for cross-CPU
     calls) may require interrupts enabled or might sleep/wait, which is
     unsafe under a spinlock.
   - Re-acquire the lock afterwards to update driver state.

Signed-off-by: Yuanfang Zhang <yuanfang.zhang@oss.qualcomm.com>
---
 drivers/hwtracing/coresight/coresight-tmc-etf.c | 87 ++++++++++++++++++++++---
 1 file changed, 77 insertions(+), 10 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index 8882b1c4cdc05353fb2efd6a9ba862943048f0ff..11357788e9d93c53980e99e0ef78450e393f4059 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -47,7 +47,7 @@ static int __tmc_etb_enable_hw(struct tmc_drvdata *drvdata)
 	return rc;
 }
 
-static int tmc_etb_enable_hw(struct tmc_drvdata *drvdata)
+static int tmc_etb_enable_hw_local(struct tmc_drvdata *drvdata)
 {
 	int rc = coresight_claim_device(drvdata->csdev);
 
@@ -60,6 +60,36 @@ static int tmc_etb_enable_hw(struct tmc_drvdata *drvdata)
 	return rc;
 }
 
+struct tmc_smp_arg {
+	struct tmc_drvdata *drvdata;
+	int rc;
+};
+
+static void tmc_etb_enable_hw_smp_call(void *info)
+{
+	struct tmc_smp_arg *arg = info;
+
+	arg->rc = tmc_etb_enable_hw_local(arg->drvdata);
+}
+
+static int tmc_etb_enable_hw(struct tmc_drvdata *drvdata)
+{
+	int cpu, ret;
+	struct tmc_smp_arg arg = { 0 };
+
+	if (!drvdata->supported_cpus)
+		return tmc_etb_enable_hw_local(drvdata);
+
+	arg.drvdata = drvdata;
+	for_each_cpu(cpu, drvdata->supported_cpus) {
+		ret = smp_call_function_single(cpu,
+					       tmc_etb_enable_hw_smp_call, &arg, 1);
+		if (!ret)
+			return arg.rc;
+	}
+	return ret;
+}
+
 static void tmc_etb_dump_hw(struct tmc_drvdata *drvdata)
 {
 	char *bufp;
@@ -130,7 +160,7 @@ static int __tmc_etf_enable_hw(struct tmc_drvdata *drvdata)
 	return rc;
 }
 
-static int tmc_etf_enable_hw(struct tmc_drvdata *drvdata)
+static int tmc_etf_enable_hw_local(struct tmc_drvdata *drvdata)
 {
 	int rc = coresight_claim_device(drvdata->csdev);
 
@@ -143,6 +173,32 @@ static int tmc_etf_enable_hw(struct tmc_drvdata *drvdata)
 	return rc;
 }
 
+static void tmc_etf_enable_hw_smp_call(void *info)
+{
+	struct tmc_smp_arg *arg = info;
+
+	arg->rc = tmc_etf_enable_hw_local(arg->drvdata);
+}
+
+static int tmc_etf_enable_hw(struct tmc_drvdata *drvdata)
+{
+	int cpu, ret;
+	struct tmc_smp_arg arg = { 0 };
+
+	if (!drvdata->supported_cpus)
+		return tmc_etf_enable_hw_local(drvdata);
+
+	arg.drvdata = drvdata;
+
+	for_each_cpu(cpu, drvdata->supported_cpus) {
+		ret = smp_call_function_single(cpu,
+					       tmc_etf_enable_hw_smp_call, &arg, 1);
+		if (!ret)
+			return arg.rc;
+	}
+	return ret;
+}
+
 static void tmc_etf_disable_hw(struct tmc_drvdata *drvdata)
 {
 	struct coresight_device *csdev = drvdata->csdev;
@@ -228,7 +284,11 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
 		used = true;
 		drvdata->buf = buf;
 	}
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
 	ret = tmc_etb_enable_hw(drvdata);
+
+	raw_spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (!ret) {
 		coresight_set_mode(csdev, CS_MODE_SYSFS);
 		csdev->refcnt++;
@@ -291,7 +351,11 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev,
 			break;
 		}
 
-		ret  = tmc_etb_enable_hw(drvdata);
+		if (drvdata->supported_cpus &&
+		    !cpumask_test_cpu(smp_processor_id(), drvdata->supported_cpus))
+			break;
+
+		ret  = tmc_etb_enable_hw_local(drvdata);
 		if (!ret) {
 			/* Associate with monitored process. */
 			drvdata->pid = pid;
@@ -376,19 +440,22 @@ static int tmc_enable_etf_link(struct coresight_device *csdev,
 		return -EBUSY;
 	}
 
-	if (csdev->refcnt == 0) {
+	if (csdev->refcnt == 0)
+		first_enable = true;
+
+	if (!first_enable)
+		csdev->refcnt++;
+
+	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	if (first_enable) {
 		ret = tmc_etf_enable_hw(drvdata);
 		if (!ret) {
 			coresight_set_mode(csdev, CS_MODE_SYSFS);
-			first_enable = true;
+			csdev->refcnt++;
+			dev_dbg(&csdev->dev, "TMC-ETF enabled\n");
 		}
 	}
-	if (!ret)
-		csdev->refcnt++;
-	raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
-	if (first_enable)
-		dev_dbg(&csdev->dev, "TMC-ETF enabled\n");
 	return ret;
 }
 

-- 
2.34.1


  parent reply	other threads:[~2025-12-18  8:10 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-18  8:09 [PATCH v2 00/12] coresight: Add CPU cluster funnel/replicator/tmc support Yuanfang Zhang
2025-12-18  8:09 ` [PATCH v2 01/12] dt-bindings: arm: coresight: Add 'qcom,cpu-bound-components' property Yuanfang Zhang
2025-12-18 11:37   ` Sudeep Holla
2025-12-18  8:09 ` [PATCH v2 02/12] coresight-funnel: Support CPU cluster funnel initialization Yuanfang Zhang
2025-12-18  8:09 ` [PATCH v2 03/12] coresight-funnel: Defer probe when associated CPUs are offline Yuanfang Zhang
2025-12-18  8:09 ` [PATCH v2 04/12] coresight-replicator: Support CPU cluster replicator initialization Yuanfang Zhang
2025-12-18  8:09 ` [PATCH v2 05/12] coresight-replicator: Defer probe when associated CPUs are offline Yuanfang Zhang
2025-12-18  8:09 ` [PATCH v2 06/12] coresight-replicator: Update management interface for CPU-bound devices Yuanfang Zhang
2025-12-18  8:09 ` [PATCH v2 07/12] coresight-tmc: Support probe and initialization for CPU cluster TMCs Yuanfang Zhang
2025-12-18  8:09 ` Yuanfang Zhang [this message]
2025-12-18  8:09 ` [PATCH v2 09/12] coresight-tmc: Update management interface for CPU-bound TMCs Yuanfang Zhang
2025-12-18  8:09 ` [PATCH v2 10/12] coresight-tmc: Defer probe when associated CPUs are offline Yuanfang Zhang
2025-12-18  8:09 ` [PATCH v2 11/12] coresight: Pass trace mode to link enable callback Yuanfang Zhang
2025-12-18  8:09 ` [PATCH v2 12/12] arm64: dts: qcom: hamoa: Add CoreSight nodes for APSS debug block yuanfang Zhang
2025-12-18  9:32 ` [PATCH v2 00/12] coresight: Add CPU cluster funnel/replicator/tmc support Suzuki K Poulose
2025-12-18 16:18   ` yuanfang zhang
2025-12-18 17:04     ` Suzuki K Poulose
2025-12-19 10:06       ` Sudeep Holla
2025-12-18 10:40 ` Leo Yan
2025-12-19  1:50   ` yuanfang zhang
2025-12-19 10:42     ` Leo Yan
2025-12-18 11:33 ` Sudeep Holla
2025-12-19  2:13   ` yuanfang zhang
2025-12-19 10:21     ` Sudeep Holla
2025-12-19 10:28       ` Suzuki K Poulose

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251218-cpu_cluster_component_pm-v2-8-2335a6ae62a0@oss.qualcomm.com \
    --to=yuanfang.zhang@oss.qualcomm.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=andersson@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=coresight@lists.linaro.org \
    --cc=devicetree@vger.kernel.org \
    --cc=james.clark@linaro.org \
    --cc=kernel@oss.qualcomm.com \
    --cc=konradybcio@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=leo.yan@linux.dev \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mathieu.poirier@linaro.org \
    --cc=maulik.shah@oss.qualcomm.com \
    --cc=mike.leach@linaro.org \
    --cc=robh@kernel.org \
    --cc=suzuki.poulose@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox