[PATCH v3 27/31] coresight: Add PM callbacks for percpu sink
Mike Leach
mike.leach at linaro.org
Fri Oct 3 04:42:30 PDT 2025
Hi Leo,
Since we are now passing in_idle to enable/disable path would if not
be easier to choose the correct callback in there?
e,g,
in enable path something like
case CORESIGHT_DEV_TYPE_SINK:
if (in_idle && cs_ops(csdev)->pm_restore_enable)
cs_ops->pm_restore_enable(csdev)
else
sink_ops(csdev)->enable(csdev, mode,data)
This would remove the need for new functions and replicating the
enable / disable helpers logic
Regards
Mike
On Mon, 15 Sept 2025 at 11:34, Leo Yan <leo.yan at arm.com> wrote:
>
> 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.
>
> There are no changes to the coresight_enable_helpers() function; the
> code movement is solely for compilation purposes.
>
> Signed-off-by: Leo Yan <leo.yan at arm.com>
> ---
> drivers/hwtracing/coresight/coresight-core.c | 101 +++++++++++++++++++++------
> include/linux/coresight.h | 4 ++
> 2 files changed, 82 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
> index 04e8c3b862494abb2a5a46d385f0ff4cad93b71f..ef9dbba285710fe508580ee2726e22bcc654014e 100644
> --- a/drivers/hwtracing/coresight/coresight-core.c
> +++ b/drivers/hwtracing/coresight/coresight-core.c
> @@ -393,6 +393,25 @@ static void coresight_disable_helper(struct coresight_device *csdev, void *data)
> helper_ops(csdev)->disable(csdev, data);
> }
>
> +static int coresight_enable_helpers(struct coresight_device *csdev,
> + enum cs_mode mode, void *data)
> +{
> + int i, ret = 0;
> + struct coresight_device *helper;
> +
> + for (i = 0; i < csdev->pdata->nr_outconns; ++i) {
> + helper = csdev->pdata->out_conns[i]->dest_dev;
> + if (!helper || !coresight_is_helper(helper))
> + continue;
> +
> + ret = coresight_enable_helper(helper, mode, data);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> static void coresight_disable_helpers(struct coresight_device *csdev, void *data)
> {
> int i;
> @@ -480,6 +499,43 @@ static void coresight_restore_source(struct coresight_device *csdev)
> source_ops(csdev)->restore(csdev);
> }
>
> +static int coresight_save_percpu_sink(struct coresight_device *csdev)
> +{
> + int ret;
> +
> + if (csdev && sink_ops(csdev)->save) {
> + ret = sink_ops(csdev)->save(csdev);
> + if (ret)
> + return ret;
> +
> + coresight_disable_helpers(csdev, NULL);
> + }
> +
> + /* Return success if callback is not supported */
> + return 0;
> +}
> +
> +static int coresight_restore_percpu_sink(struct coresight_device *csdev,
> + struct coresight_path *path,
> + enum cs_mode mode)
> +{
> + int ret = 0;
> +
> + if (csdev && sink_ops(csdev)->restore) {
> + ret = coresight_enable_helpers(csdev, mode, path);
> + if (ret)
> + return ret;
> +
> + ret = sink_ops(csdev)->restore(csdev);
> + if (ret) {
> + coresight_disable_helpers(csdev, path);
> + return ret;
> + }
> + }
> +
> + return ret;
> +}
> +
> /*
> * 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
> @@ -553,25 +609,6 @@ void coresight_disable_path(struct coresight_path *path)
> }
> EXPORT_SYMBOL_GPL(coresight_disable_path);
>
> -static int coresight_enable_helpers(struct coresight_device *csdev,
> - enum cs_mode mode, void *data)
> -{
> - int i, ret = 0;
> - struct coresight_device *helper;
> -
> - for (i = 0; i < csdev->pdata->nr_outconns; ++i) {
> - helper = csdev->pdata->out_conns[i]->dest_dev;
> - if (!helper || !coresight_is_helper(helper))
> - continue;
> -
> - ret = coresight_enable_helper(helper, mode, data);
> - if (ret)
> - return ret;
> - }
> -
> - return 0;
> -}
> -
> static int _coresight_enable_path(struct coresight_path *path,
> enum cs_mode mode, void *sink_data,
> bool in_idle)
> @@ -1670,9 +1707,12 @@ EXPORT_SYMBOL_GPL(coresight_alloc_device_name);
> static int coresight_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd,
> void *v)
> {
> + int ret;
> unsigned int cpu = smp_processor_id();
> struct coresight_device *source = per_cpu(csdev_source, cpu);
> struct coresight_path *path;
> + struct coresight_device *sink;
> + enum cs_mode mode;
>
> if (!coresight_need_save_restore_source(source))
> return NOTIFY_OK;
> @@ -1685,18 +1725,33 @@ static int coresight_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd,
> if (WARN_ON(!path))
> return NOTIFY_BAD;
>
> + sink = coresight_get_sink(path);
> + mode = coresight_get_mode(source);
> +
> switch (cmd) {
> case CPU_PM_ENTER:
> if (coresight_save_source(source))
> return NOTIFY_BAD;
>
> - coresight_disable_path_from(path, NULL, true);
> + ret = 0;
> + if (coresight_is_percpu_sink(sink))
> + ret = coresight_save_percpu_sink(sink);
> + else
> + coresight_disable_path_from(path, NULL, true);
> +
> + if (ret) {
> + coresight_restore_source(source);
> + return NOTIFY_BAD;
> + }
> break;
> case CPU_PM_EXIT:
> case CPU_PM_ENTER_FAILED:
> - if (_coresight_enable_path(path,
> - coresight_get_mode(source),
> - NULL, true))
> + if (coresight_is_percpu_sink(sink))
> + ret = coresight_restore_percpu_sink(sink, path, mode);
> + else
> + ret = _coresight_enable_path(path, mode, NULL, true);
> +
> + if (ret)
> return NOTIFY_BAD;
>
> coresight_restore_source(source);
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index 462876b5a870f3e93ad2a1807a9045d5eb115ccd..21bb99f9684747d7a610aa7185e1ba5f987248d9 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -363,6 +363,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,
> @@ -375,6 +377,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
>
--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK
More information about the linux-arm-kernel
mailing list