[PATCH v4 12/15] coresight: Add PM callbacks for percpu sink

Leo Yan leo.yan at arm.com
Tue Nov 4 07:21:56 PST 2025


Unlike a system level's sink, the per-CPU sink may lose power during CPU
idle states. Currently, this refers specifically to TRBE as the sink.
This commit registers save and restore callbacks for the per-CPU sink
via the PM notifier.

Signed-off-by: Leo Yan <leo.yan at arm.com>
---
 drivers/hwtracing/coresight/coresight-core.c | 53 +++++++++++++++++++++++-----
 include/linux/coresight.h                    |  4 +++
 2 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index 73be22c8f315525111f2dafd692e61bc6db85c25..7095f9befa98c7d638f857466351ef7cd960fde7 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -1659,8 +1659,25 @@ static bool coresight_pm_is_needed(struct coresight_device *csdev)
 	return coresight_ops(csdev)->pm_is_needed(csdev);
 }
 
+static int coresight_pm_percpu_sink_save(struct coresight_device *sink)
+{
+	if (!sink || !coresight_ops(sink)->pm_save_disable)
+		return 0;
+
+	return coresight_ops(sink)->pm_save_disable(sink);
+}
+
+static void coresight_pm_percpu_sink_restore(struct coresight_device *sink)
+{
+	if (!sink || !coresight_ops(sink)->pm_restore_enable)
+		return;
+
+	coresight_ops(sink)->pm_restore_enable(sink);
+}
+
 static int coresight_pm_save(struct coresight_device *csdev)
 {
+	struct coresight_device *sink;
 	int ret;
 
 	if (WARN_ON(!csdev->path))
@@ -1670,22 +1687,42 @@ static int coresight_pm_save(struct coresight_device *csdev)
 	if (ret)
 		return ret;
 
-	coresight_disable_helpers(csdev, NULL);
-	coresight_disable_path_from(csdev->path, NULL, true);
+	sink = coresight_get_sink(csdev->path);
+
+	if (coresight_is_percpu_sink(sink)) {
+		ret = coresight_pm_percpu_sink_save(sink);
+		if (ret) {
+			coresight_ops(csdev)->pm_restore_enable(csdev);
+			return ret;
+		}
+	} else {
+		coresight_disable_helpers(csdev, NULL);
+		coresight_disable_path_from(csdev->path, NULL, true);
+	}
+
 	return 0;
 }
 
 static void coresight_pm_restore(struct coresight_device *csdev)
 {
+	struct coresight_device *sink;
+
 	if (WARN_ON(!csdev->path))
 		return;
 
-	/*
-	 * During CPU idle, the sink device is not accessed, so it is okay to
-	 * pass a NULL pointer for the 'sink_data' parameter.
-	 */
-	coresight_enable_path_internal(csdev->path, coresight_get_mode(csdev),
-				       NULL, true);
+	sink = coresight_get_sink(csdev->path);
+
+	if (coresight_is_percpu_sink(sink))
+		coresight_pm_percpu_sink_restore(sink);
+	else
+		/*
+		 * During CPU idle, the sink device is not accessed, so it is
+		 * okay to pass a NULL pointer for the 'sink_data' parameter.
+		 */
+		coresight_enable_path_internal(csdev->path,
+					       coresight_get_mode(csdev),
+					       NULL, true);
+
 	coresight_ops(csdev)->pm_restore_enable(csdev);
 }
 
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 58484c225e58a68dd74739a48c08a409ce9ddd73..d2f02f6322e69bfbda82f5df5d90cb8afeb7d21d 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -364,6 +364,8 @@ enum cs_mode {
  * @alloc_buffer:	initialises perf's ring buffer for trace collection.
  * @free_buffer:	release memory allocated in @get_config.
  * @update_buffer:	update buffer pointers after a trace session.
+ * @save:		save context for a sink.
+ * @restore:		restore context for a sink.
  */
 struct coresight_ops_sink {
 	int (*enable)(struct coresight_device *csdev, enum cs_mode mode,
@@ -376,6 +378,8 @@ struct coresight_ops_sink {
 	unsigned long (*update_buffer)(struct coresight_device *csdev,
 			      struct perf_output_handle *handle,
 			      void *sink_config);
+	int (*save)(struct coresight_device *csdev);
+	int (*restore)(struct coresight_device *csdev);
 };
 
 /**

-- 
2.34.1




More information about the linux-arm-kernel mailing list