[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