This series focuses on CoreSight path power management. The changes can
be divided into four parts for review:
Patches 01~07: Refactor the CPU idle flow with moving common code into
the CoreSight core layer.
Patches 08~15: Refactor path enabling and disabling with range, add
path control during CPU idle.
Patches 16~17: Support the sink (TRBE) control during CPU idle.
Patches 18~20: Move the CPU hotplug flow into the coresight core layer
and simplify the code.
This series is rebased on the coresight-next branch and has been verified
on Juno-r2 (ETM + ETR) and FVP RevC (ETE + TRBE).
---
Changes in v7:
- Added a flag in coresight_desc to indicate CPU bound device (Suzuki).
- Used coresight_mutex to protect per-CPU source pointer (Suzuki).
- Added a spinlock for exclusive access per-CPU source pointer (Suzuki).
- Dropped .pm_is_needed() callback (Suzuki).
- Supported range in path enabling / disabling (Suzuki).
- Gathered test and review tags (Levi / James).
- Link to v6: https://lore.kernel.org/r/20260305-arm_coresight_path_power_management_impr…
Changes in v6:
- Rebase on the latest coresight-next branch.
- Always save and restore TRBE context during idle (Will).
- Use get_cpu() / put_cpu() when set the per CPU source pointer.
- Link to v5: https://lore.kernel.org/r/20251119-arm_coresight_path_power_management_impr…
Changes in v5:
- Set the per-CPU source pointer on target CPU (Suzuki).
- Reused existed enable/disable buffer functions in TRBE callbacks
(James).
- Refactored refcount for source devices in SysFS mode.
- Released path in cpu-hotplug off flow to avoid memory leak.
- Updated ETMv3 driver when move common code into core layer.
- Rebased on the latest coresight-next branch.
- Link to v4: https://lore.kernel.org/r/20251104-arm_coresight_path_power_management_impr…
Signed-off-by: Leo Yan <leo.yan(a)arm.com>
---
Leo Yan (19):
coresight: Populate CPU ID into coresight_device
coresight: Remove .cpu_id() callback from source ops
coresight: sysfs: Validate CPU online status for per-CPU sources
coresight: Move per-CPU source pointer to core layer
coresight: Register CPU PM notifier in core layer
coresight: etm4x: Hook CPU PM callbacks
coresight: etm4x: Remove redundant condition checks in save and restore
coresight: syscfg: Use spinlock to protect active variables
coresight: Introduce coresight_enable_source() helper
coresight: Save active path for system tracers
coresight: etm4x: Set active path on target CPU
coresight: etm3x: Set active path on target CPU
coresight: sysfs: Use source's path pointer for path control
coresight: Control path with range
coresight: Control path during CPU idle
coresight: Add PM callbacks for sink device
coresight: sysfs: Increment refcount only for system tracers
coresight: Take hotplug lock in enable_source_store() for Sysfs mode
coresight: Move CPU hotplug callbacks to core layer
Yabin Cui (1):
coresight: trbe: Save and restore state across CPU low power state
drivers/hwtracing/coresight/coresight-catu.c | 2 +-
drivers/hwtracing/coresight/coresight-core.c | 377 +++++++++++++++++++--
drivers/hwtracing/coresight/coresight-cti-core.c | 9 +-
drivers/hwtracing/coresight/coresight-etm-perf.c | 25 +-
drivers/hwtracing/coresight/coresight-etm3x-core.c | 73 +---
drivers/hwtracing/coresight/coresight-etm4x-core.c | 154 ++-------
drivers/hwtracing/coresight/coresight-priv.h | 4 +
drivers/hwtracing/coresight/coresight-syscfg.c | 21 +-
drivers/hwtracing/coresight/coresight-syscfg.h | 2 +
drivers/hwtracing/coresight/coresight-sysfs.c | 126 +++----
drivers/hwtracing/coresight/coresight-trbe.c | 61 +++-
include/linux/coresight.h | 15 +-
12 files changed, 546 insertions(+), 323 deletions(-)
---
base-commit: a90863095f84f6d17c49716e4e2212d28a6b25b5
change-id: 20251104-arm_coresight_path_power_management_improvement-dab4966f8280
Best regards,
--
Leo Yan <leo.yan(a)arm.com>
Hi Jie,
On Fri, Mar 20, 2026 at 04:44:54PM +0800, Jie Gan wrote:
[...]
> It's about the coresight_find_device_by_fwnode() returns NULL, resulting in
> -EPROBE_DEFER. So the probe process will re-start after several seconds, but
> always failed because we have a "disabled" device node in DT(we can see this
> device in DT, but it never becomes available). It's ok if the device only
> has one remote device, but has issue with more than one remote devices.
>
> Consider below situation:
>
> device0
> | |
> device1 device2(status = "disabled")
>
> The probe of device0 succeeds only when device1 and device2 are available at
> probe time. But I think it's ok to probe the device0 only with device1
> available.
Thanks a lot for details. We might need to report warning or error if
all remote endpoints fail (e.g., device1/device2 both are disabled),
this is a rare case so would be low priority.
For this patch:
Reviewed-by: Leo Yan <leo.yan(a)arm.com>
On Fri, Mar 20, 2026 at 03:31:12PM +0800, Jie Gan wrote:
> Check endpoint availability before parsing it. If parsing a connected
> endpoint fails, the probe is deferred until the endpoint becomes
> available, or eventually fails.
I want to clarify a bit the failure flow.
Does this mean coresight_find_device_by_fwnode() returns NULL when the
remote device is not found, resulting in -EPROBE_DEFER, but the probe
never waits for the remote device to become available?
> In some legacy cases, a replicator
> has two output ports where one is disabled and the other is available.
> The replicator probe always fails because the disabled endpoint never
> becomes available for parsing. In addition, there is no need to defer
> probing a device that is connected to a disabled device, which improves
> probe performance.
>
> Signed-off-by: Jie Gan <jie.gan(a)oss.qualcomm.com>
> ---
> drivers/hwtracing/coresight/coresight-platform.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/hwtracing/coresight/coresight-platform.c b/drivers/hwtracing/coresight/coresight-platform.c
> index 0ca3bd762454..e337b6e2bf32 100644
> --- a/drivers/hwtracing/coresight/coresight-platform.c
> +++ b/drivers/hwtracing/coresight/coresight-platform.c
> @@ -220,6 +220,8 @@ static int of_coresight_parse_endpoint(struct device *dev,
> rparent = of_coresight_get_port_parent(rep);
> if (!rparent)
> break;
> + if (!of_device_is_available(rparent))
> + break;
> if (of_graph_parse_endpoint(rep, &rendpoint))
> break;
>
>
> ---
> base-commit: b5d083a3ed1e2798396d5e491432e887da8d4a06
> change-id: 20260320-add-availability-check-4cb2ee6e520b
>
> Best regards,
> --
> Jie Gan <jie.gan(a)oss.qualcomm.com>
>
perf will output additional CoreSight debug information, from the
'perf report --dump' command, when the build option CSTRACE_RAW=1
is added to the usual CORESIGHT=1 at build time.
This additional information consists of raw trace data in the form of
CoreSight formatted trace frames. This is intended to be used to
investigate possible issues relating to trace data corruption,
trace hardware issues or problems with decode.
The CoreSight formatted trace frames are used when multiple ETMs trace
into an ETR, and not present when a single ETE traces into the TRBE.
When the build option is used and perf is used to dump an ETE/TRBE
generated buffer a segfault will occur in the OpenCSD library.
Patch 1 of this set removes the unnecessary call to print the raw trace
frames when not needed, and fixes the segfault where older versions
of OpenCSD are in use.
Patch 2 enhances the debug output to associate raw data with individual
packets, which means that raw data is now present for ETE and extended
for ETM.
OpenCSD is being fixed independently.
Mike Leach (2):
perf: tools: cs-etm: Fix print issue for Coresight debug in ETE/TRBE
trace
perf: tools: cs-etm: Enhance raw Coresight trace debug display
tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
--
2.43.0
Building perf with CORESIGHT=1 and the optional CSTRACE_RAW=1 enables
additional debug printing of raw trace data when using command:-
perf report --dump.
This raw trace prints the CoreSight formatted trace frames, which may be
used to investigate suspected issues with trace quality / corruption /
decode.
These frames are not present in ETE + TRBE trace.
This fix removes the unnecessary call to print these frames.
This fix also rationalises implementation - original code had helper
function that unnecessarily repeated initialisation calls that had
already been made.
Due to an addtional fault with the OpenCSD library, this call when ETE/TRBE
are being decoded will cause a segfault in perf. This fix also prevents
that problem for perf using older (<= 1.8.0 version) OpenCSD libraries.
Fixes: 68ffe3902898 ("perf tools: Add decoder mechanic to support dumping trace data")
Reported-by: Leo Yan <leo.yan(a)arm.com>
Signed-off-by: Mike Leach <mike.leach(a)arm.com>
---
Changes in v2: Rationalise implementation
---
.../perf/util/cs-etm-decoder/cs-etm-decoder.c | 51 +++++--------------
1 file changed, 13 insertions(+), 38 deletions(-)
diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
index 3050fe212666..8592a778b26a 100644
--- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
+++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
@@ -237,46 +237,24 @@ cs_etm_decoder__init_def_logger_printing(struct cs_etm_decoder_params *d_params,
(void *)decoder,
cs_etm_decoder__print_str_cb);
if (ret != 0)
- ret = -1;
-
- return 0;
-}
+ return -1;
#ifdef CS_LOG_RAW_FRAMES
-static void
-cs_etm_decoder__init_raw_frame_logging(struct cs_etm_decoder_params *d_params,
- struct cs_etm_decoder *decoder)
-{
- /* Only log these during a --dump operation */
- if (d_params->operation == CS_ETM_OPERATION_PRINT) {
- /* set up a library default logger to process the
- * raw frame printer we add later
- */
- ocsd_def_errlog_init(OCSD_ERR_SEV_ERROR, 1);
-
- /* no stdout / err / file output */
- ocsd_def_errlog_config_output(C_API_MSGLOGOUT_FLG_NONE, NULL);
-
- /* set the string CB for the default logger,
- * passes strings to perf print logger.
- */
- ocsd_def_errlog_set_strprint_cb(decoder->dcd_tree,
- (void *)decoder,
- cs_etm_decoder__print_str_cb);
-
+ /*
+ * Only log raw frames if --dump operation and hardware is actually
+ * generating formatted CoreSight trace frames
+ */
+ if ((d_params->operation == CS_ETM_OPERATION_PRINT) &&
+ (d_params->formatted == true)) {
/* use the built in library printer for the raw frames */
- ocsd_dt_set_raw_frame_printer(decoder->dcd_tree,
- CS_RAW_DEBUG_FLAGS);
+ ret = ocsd_dt_set_raw_frame_printer(decoder->dcd_tree,
+ CS_RAW_DEBUG_FLAGS);
+ if (ret != 0)
+ return -1;
}
-}
-#else
-static void
-cs_etm_decoder__init_raw_frame_logging(
- struct cs_etm_decoder_params *d_params __maybe_unused,
- struct cs_etm_decoder *decoder __maybe_unused)
-{
-}
#endif
+ return 0;
+}
static ocsd_datapath_resp_t
cs_etm_decoder__do_soft_timestamp(struct cs_etm_queue *etmq,
@@ -738,9 +716,6 @@ cs_etm_decoder__new(int decoders, struct cs_etm_decoder_params *d_params,
if (ret != 0)
goto err_free_decoder;
- /* init raw frame logging if required */
- cs_etm_decoder__init_raw_frame_logging(d_params, decoder);
-
for (i = 0; i < decoders; i++) {
ret = cs_etm_decoder__create_etm_decoder(d_params,
&t_params[i],
--
2.43.0
This series focuses on CoreSight path power management. The changes can
be divided into four parts for review:
Patches 01~06: Refactor the CPU idle flow with moving common code into
the CoreSight core layer.
Patches 07~14: Add link control during CPU idle.
Patches 15~16: Support the sink (TRBE) control during CPU idle.
Patches 17~19: Move the CPU hotplug flow into the coresight core layer
and simplify the code.
This series is rebased on the coresight-next branch and has been verified
on Juno-r2 and FVP RevC.
---
Changes in v6:
- Rebase on the latest coresight-next branch.
- Always save and restore TRBE context during idle (Will).
- Use get_cpu() / put_cpu() when set the per CPU source pointer.
- Link to v5: https://lore.kernel.org/r/20251119-arm_coresight_path_power_management_impr…
Changes in v5:
- Set the per-CPU source pointer on target CPU (Suzuki).
- Reused existed enable/disable buffer functions in TRBE callbacks
(James).
- Refactored refcount for source devices in SysFS mode.
- Released path in cpu-hotplug off flow to avoid memory leak.
- Updated ETMv3 driver when move common code into core layer.
- Rebased on the latest coresight-next branch.
- Link to v4: https://lore.kernel.org/r/20251104-arm_coresight_path_power_management_impr…
Changes in v4:
- Changed to store path pointer in coresight_device, this is easier for
fetching path pointer based on source device (Mike).
- Dropped changes in CTI driver.
- Only disabled path for CPU hot-plugged off but not enable path for
hot-plugged in.
- Removed James' test tags for modified patches.
- Link to v3: https://lore.kernel.org/r/20250915-arm_coresight_power_management_fix-v3-0-…
Signed-off-by: Leo Yan <leo.yan(a)arm.com>
---
Leo Yan (18):
coresight: sysfs: Validate CPU online status for per-CPU sources
coresight: Set per-CPU source pointer
coresight: Register CPU PM notifier in core layer
coresight: etm4x: Hook CPU PM callbacks
coresight: Add callback to determine if PM is needed
coresight: etm4x: Remove redundant condition checks in save and restore
coresight: syscfg: Use spinlock to protect active variables
coresight: Introduce coresight_enable_source() helper
coresight: Save active path for system tracers
coresight: etm4x: Set active path on target CPU
coresight: etm3x: Set active path on target CPU
coresight: sysfs: Use source's path pointer for path control
coresight: Add 'in_idle' argument to path
coresight: Control path during CPU idle
coresight: Add PM callbacks for sink device
coresight: sysfs: Increment refcount only for system tracers
coresight: Take hotplug lock in enable_source_store() for Sysfs mode
coresight: Move CPU hotplug callbacks to core layer
Yabin Cui (1):
coresight: trbe: Save and restore state across CPU low power state
drivers/hwtracing/coresight/coresight-catu.c | 1 +
drivers/hwtracing/coresight/coresight-core.c | 273 ++++++++++++++++++++-
drivers/hwtracing/coresight/coresight-ctcu-core.c | 1 +
drivers/hwtracing/coresight/coresight-cti-core.c | 1 +
drivers/hwtracing/coresight/coresight-dummy.c | 1 +
drivers/hwtracing/coresight/coresight-etb10.c | 1 +
drivers/hwtracing/coresight/coresight-etm-perf.c | 2 +-
drivers/hwtracing/coresight/coresight-etm3x-core.c | 65 ++---
drivers/hwtracing/coresight/coresight-etm4x-core.c | 153 +++---------
drivers/hwtracing/coresight/coresight-funnel.c | 1 +
drivers/hwtracing/coresight/coresight-priv.h | 3 +
drivers/hwtracing/coresight/coresight-replicator.c | 1 +
drivers/hwtracing/coresight/coresight-stm.c | 1 +
drivers/hwtracing/coresight/coresight-syscfg.c | 22 +-
drivers/hwtracing/coresight/coresight-syscfg.h | 2 +
drivers/hwtracing/coresight/coresight-sysfs.c | 126 +++-------
drivers/hwtracing/coresight/coresight-tmc-core.c | 1 +
drivers/hwtracing/coresight/coresight-tnoc.c | 2 +
drivers/hwtracing/coresight/coresight-tpda.c | 1 +
drivers/hwtracing/coresight/coresight-tpdm.c | 1 +
drivers/hwtracing/coresight/coresight-tpiu.c | 1 +
drivers/hwtracing/coresight/coresight-trbe.c | 60 ++++-
drivers/hwtracing/coresight/ultrasoc-smb.c | 1 +
include/linux/coresight.h | 11 +
24 files changed, 458 insertions(+), 274 deletions(-)
---
base-commit: 9c5ef7a30d9044f8706bd02bfdc4eff7266f3e25
change-id: 20251104-arm_coresight_path_power_management_improvement-dab4966f8280
Best regards,
--
Leo Yan <leo.yan(a)arm.com>
On 16/03/2026 10:29, Jie Gan wrote:
>
> Hi Suzuki,
>
> On 3/16/2026 5:32 PM, Suzuki K Poulose wrote:
>> On 16/03/2026 07:23, Jie Gan wrote:
>>> Save the trace ID in drvdata during TPDM enablement and expose it
>>> to userspace to support trace data parsing.
>>>
>>> The TPDM device’s trace ID corresponds to the trace ID allocated
>>> to the connected TPDA device.
>>>
>>> Signed-off-by: Jie Gan <jie.gan(a)oss.qualcomm.com>
>>> ---
>>> Changes in V2:
>>> 1. Use sysfs_emit instead of sprintf.
>>> Link to V1 - https://lore.kernel.org/all/20260306-add-traceid-show-
>>> for-tpdm-v1-1-0658a8edb972(a)oss.qualcomm.com/
>>
>> Why is this patch required even ? For each TPDM there is a single
>
> It's taking effort to retrieve the trace ID of the TPDA device because
> it's not a source device. The trace ID is required to identify the
> origin of the trace data and is essential for parsing the received data.
>
>> port in a single TPDA in the system where it can reach and that is
>> fixed for a platform. Can we not get this from there ? Also, there
>> is not TraceID technically for a TPDM, right ? It is all a property
>
> Yes, we dont allocate trace ID for a TPDM device. The TraceID is
> allocated to the TPDA device.
Now if you combine both your responses, don't you think they contradict
each other ?
Also, the TraceID we show is *not valid* if the TPDM was never enabled.
So this is inconsistent, isn't it ? Unless we return an error in this case
Suzuki
>
> Thanks,
> Jie
>
>> of the TPDA ?
>>
>
>
>> Suzuki
>>
>>
>>> ---
>>> drivers/hwtracing/coresight/coresight-tpdm.c | 31 +++++++++++++++++
>>> + +++++++++-
>>> drivers/hwtracing/coresight/coresight-tpdm.h | 2 ++
>>> 2 files changed, 32 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/
>>> hwtracing/coresight/coresight-tpdm.c
>>> index da77bdaad0a4..774a63def817 100644
>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>>> @@ -481,7 +481,7 @@ static void __tpdm_enable(struct tpdm_drvdata
>>> *drvdata)
>>> static int tpdm_enable(struct coresight_device *csdev, struct
>>> perf_event *event,
>>> enum cs_mode mode,
>>> - __maybe_unused struct coresight_path *path)
>>> + struct coresight_path *path)
>>> {
>>> struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>>> @@ -497,6 +497,7 @@ static int tpdm_enable(struct coresight_device
>>> *csdev, struct perf_event *event,
>>> }
>>> __tpdm_enable(drvdata);
>>> + drvdata->traceid = path->trace_id;
>>> drvdata->enable = true;
>>> spin_unlock(&drvdata->spinlock);
>>> @@ -693,6 +694,26 @@ static struct attribute_group tpdm_attr_grp = {
>>> .attrs = tpdm_attrs,
>>> };
>>> +static ssize_t traceid_show(struct device *dev,
>>> + struct device_attribute *attr, char *buf)
>>> +{
>>> + unsigned long val;
>>> + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>> +
>>> + val = drvdata->traceid;
>>> + return sysfs_emit(buf, "%#lx\n", val);
>>> +}
>>> +static DEVICE_ATTR_RO(traceid);
>>> +
>>> +static struct attribute *traceid_attrs[] = {
>>> + &dev_attr_traceid.attr,
>>> + NULL,
>>> +};
>>> +
>>> +static struct attribute_group traceid_attr_grp = {
>>> + .attrs = traceid_attrs,
>>> +};
>>> +
>>> static ssize_t dsb_mode_show(struct device *dev,
>>> struct device_attribute *attr,
>>> char *buf)
>>> @@ -1367,6 +1388,12 @@ static const struct attribute_group
>>> *tpdm_attr_grps[] = {
>>> &tpdm_cmb_patt_grp,
>>> &tpdm_cmb_msr_grp,
>>> &tpdm_mcmb_attr_grp,
>>> + &traceid_attr_grp,
>>> + NULL,
>>> +};
>>> +
>>> +static const struct attribute_group *static_tpdm_attr_grps[] = {
>>> + &traceid_attr_grp,
>>> NULL,
>>> };
>>> @@ -1425,6 +1452,8 @@ static int tpdm_probe(struct device *dev,
>>> struct resource *res)
>>> desc.access = CSDEV_ACCESS_IOMEM(base);
>>> if (res)
>>> desc.groups = tpdm_attr_grps;
>>> + else
>>> + desc.groups = static_tpdm_attr_grps;
>>
>> > drvdata->csdev = coresight_register(&desc);> if
>> (IS_ERR(drvdata->csdev))
>>> return PTR_ERR(drvdata->csdev);
>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/
>>> hwtracing/coresight/coresight-tpdm.h
>>> index 2867f3ab8186..befecbb896f4 100644
>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.h
>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
>>> @@ -300,6 +300,7 @@ struct cmb_dataset {
>>> * @cmb Specifics associated to TPDM CMB.
>>> * @dsb_msr_num Number of MSR supported by DSB TPDM
>>> * @cmb_msr_num Number of MSR supported by CMB TPDM
>>> + * @traceid trace ID of the path.
>>> */
>>> struct tpdm_drvdata {
>>> @@ -313,6 +314,7 @@ struct tpdm_drvdata {
>>> struct cmb_dataset *cmb;
>>> u32 dsb_msr_num;
>>> u32 cmb_msr_num;
>>> + u8 traceid;
>>> };
>>> /* Enumerate members of various datasets */
>>>
>>> ---
>>> base-commit: b84a0ebe421ca56995ff78b66307667b62b3a900
>>> change-id: 20260316-add-traceid-show-for-tpdm-88d040651f00
>>>
>>> Best regards,
>>
>>
>
Leo has been an active contributor and reviewer for CoreSight subsystem for
years. Add him as a Reviewer for CORESIGHT.
Cc: Leo Yan <leo.yan(a)arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose(a)arm.com>
---
MAINTAINERS | 1 +
1 file changed, 1 insertion(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 9c5491001908..eaf928246aaf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2710,6 +2710,7 @@ ARM/CORESIGHT FRAMEWORK AND DRIVERS
M: Suzuki K Poulose <suzuki.poulose(a)arm.com>
R: Mike Leach <mike.leach(a)arm.com>
R: James Clark <james.clark(a)linaro.org>
+R: Leo Yan <leo.yan(a)arm.com>
L: coresight(a)lists.linaro.org (moderated for non-subscribers)
L: linux-arm-kernel(a)lists.infradead.org (moderated for non-subscribers)
S: Maintained
--
2.43.0