Unlike a system level's sink, the per-CPU sink may lose power during CPU idle states. So far, this refers to the TRBE as a sink. This commit adds save and restore callbacks for the sink, and these callbacks are via the PM notifier.
For not per-CPU sinks (e.g., ETR, ETB, etc), which are system level components and should not be affected by CPU low power states. The PM notifier does not interact with them to avoid additional latency.
Signed-off-by: Leo Yan leo.yan@arm.com --- drivers/hwtracing/coresight/coresight-core.c | 23 +++++++++++++++++++++++ include/linux/coresight.h | 4 ++++ 2 files changed, 27 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index 075d485dcea5..02b80db1da3d 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -437,6 +437,21 @@ static void coresight_restore_source(struct coresight_device *csdev) source_ops(csdev)->restore(csdev); }
+static int coresight_save_sink(struct coresight_device *csdev) +{ + if (csdev && sink_ops(csdev)->save) + return sink_ops(csdev)->save(csdev); + + /* Return success if callback is not supported */ + return 0; +} + +static void coresight_restore_sink(struct coresight_device *csdev) +{ + if (csdev && sink_ops(csdev)->restore) + sink_ops(csdev)->restore(csdev); +} + /* * coresight_disable_path_from : Disable components in the given path beyond * @nd in the list. If @nd is NULL, all the components, except the SOURCE are @@ -616,6 +631,10 @@ static int coresight_save_path(struct coresight_path *path)
sink = coresight_get_sink(path);
+ /* Save per CPU sink and directly bail out */ + if (coresight_is_percpu_sink(sink)) + return coresight_save_sink(sink); + /* * Disable links. Deliberately to skip disabling the sink to avoid * latency. @@ -659,6 +678,10 @@ static void coresight_restore_path(struct coresight_path *path)
sink = coresight_get_sink(path);
+ /* Restore per CPU sink and directly bail out */ + if (coresight_is_percpu_sink(sink)) + return coresight_restore_sink(sink); + list_for_each_entry_reverse(nd, &path->path_list, link) { struct coresight_device *csdev, *parent, *child;
diff --git a/include/linux/coresight.h b/include/linux/coresight.h index cd9709a36b9c..bffcb2238102 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -365,6 +365,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, @@ -377,6 +379,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); + void (*restore)(struct coresight_device *csdev); };
/**