This series focuses on CoreSight path power management. The changes can
be divided into four parts for review:
Patches 01 - 04: Refactor the CPU ID storing in csdev, later patches
consume csdev->cpu. Move CPU lock to sysfs layer so
it is safe for later changes.
Patches 05 - 09: Refactor the CPU idle flow with moving common code into
the CoreSight core layer.
Patches 10 - 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 CPU hotplug into the core layer, and fix sysfs
mode for hotplug.
This series is rebased on the coresight-next branch and has been verified
on Juno-r2 (ETM + ETR) and FVP RevC (ETE + TRBE). Built successfully
for armv7 (ARCH=arm).
---
Changes in v10:
- Removed redundant checks in ETMv4 PM callbacks (sashiko).
- Added a new const structure etm4_cs_pm_ops (sashiko).
- Used fine-grained spinlock on sysfs_active_config (sashiko).
- Blocked notification after failures in save / restore to avoid lockups.
- Changed Change CPUHP_AP_ARM_CORESIGHT_STARTING to
CPUHP_AP_ARM_CORESIGHT_ONLINE so that the CPU hotplug callback runs in
the thread context (sashiko).
- Link to v9: https://lore.kernel.org/r/20260401-arm_coresight_path_power_management_impr…
Changes in v9:
- Changed to use per-CPU path pointer with lockless access.
- Removed the change for adding csdev->path, the related refactoring
will be sent separately.
- Re-orged patches to avoid intermediate breakage (sashiko).
- Link to v8: https://lore.kernel.org/r/20260325-arm_coresight_path_power_management_impr…
Changes in v8:
- Moved the "cpu" field in coresight_device for better pack with new
patch 01 (Suzuki).
- Added check if not set CPU for per_cpu_source/per_cpu_sink (Suzuki).
- Renamed spinlock name in syscfg (Suzuki).
- Refactored paired enable and disable path with new patches
10 and 12 (Suzuki).
- Link to v7: https://lore.kernel.org/r/20260320-arm_coresight_path_power_management_impr…
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…
Signed-off-by: Leo Yan <leo.yan(a)arm.com>
---
Leo Yan (19):
coresight: Extract device init into coresight_init_device()
coresight: Populate CPU ID into coresight_device
coresight: Remove .cpu_id() callback from source ops
coresight: Take hotplug lock in enable_source_store() for Sysfs mode
coresight: etm4x: Set per-CPU path on local CPU
coresight: etm3x: Set per-CPU path on local CPU
coresight: Register CPU PM notifier in core layer
coresight: etm4x: Hook CPU PM callbacks
coresight: etm4x: Remove redundant checks in PM save and restore
coresight: syscfg: Use IRQ-safe spinlock to protect active variables
coresight: Move source helper disabling to coresight_disable_path()
coresight: Control path with range
coresight: Use helpers to fetch first and last nodes
coresight: Introduce coresight_enable_source() helper
coresight: Control path during CPU idle
coresight: Add PM callbacks for sink device
coresight: sysfs: Increment refcount only for system tracers
coresight: Move CPU hotplug callbacks to core layer
coresight: sysfs: Validate CPU online status for per-CPU sources
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 | 419 ++++++++++++++++++---
drivers/hwtracing/coresight/coresight-cti-core.c | 9 +-
drivers/hwtracing/coresight/coresight-etm-perf.c | 4 +-
drivers/hwtracing/coresight/coresight-etm3x-core.c | 73 +---
drivers/hwtracing/coresight/coresight-etm4x-core.c | 168 ++-------
drivers/hwtracing/coresight/coresight-priv.h | 4 +
drivers/hwtracing/coresight/coresight-syscfg.c | 35 +-
drivers/hwtracing/coresight/coresight-syscfg.h | 2 +
drivers/hwtracing/coresight/coresight-sysfs.c | 50 ++-
drivers/hwtracing/coresight/coresight-trbe.c | 61 ++-
include/linux/coresight.h | 13 +-
include/linux/cpuhotplug.h | 2 +-
13 files changed, 566 insertions(+), 276 deletions(-)
---
base-commit: ec687ba84000d7d50cf243558041f6729d1d8119
change-id: 20251104-arm_coresight_path_power_management_improvement-dab4966f8280
Best regards,
--
Leo Yan <leo.yan(a)arm.com>
On Tue, Mar 17, 2026 at 06:17:04PM +0000, Yeoreum Yun wrote:
> The current ETM4x configuration via sysfs can lead to the following
> inconsistencies:
>
> - If a configuration is modified via sysfs while a perf session is
> active, the running configuration may differ between before
> a sched-out and after a subsequent sched-in.
>
> - Once a perf session is enabled, some read-only register fields
> (e.g., TRCSSCSR<n>) may not be reported correctly,
> because drvdata->config is cleared while enabling with perf mode,
> even though the information was previously read via etm4_init_arch_data().
>
> To resolve these inconsistencies, the configuration should be separated into:
>
> - active_config, which represents the currently applied configuration
> - config, which stores the settings configured via sysfs.
>
> Signed-off-by: Yeoreum Yun <yeoreum.yun(a)arm.com>
> ---
> .../hwtracing/coresight/coresight-etm4x-cfg.c | 2 +-
> .../coresight/coresight-etm4x-core.c | 45 +++++++++++--------
> drivers/hwtracing/coresight/coresight-etm4x.h | 2 +
> 3 files changed, 30 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
> index c302072b293a..84213d40d1ae 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
> @@ -47,7 +47,7 @@ static int etm4_cfg_map_reg_offset(struct etmv4_drvdata *drvdata,
> struct cscfg_regval_csdev *reg_csdev, u32 offset)
> {
> int err = -EINVAL, idx;
> - struct etmv4_config *drvcfg = &drvdata->config;
> + struct etmv4_config *drvcfg = &drvdata->active_config;
I'd suggest we leave out complex cfg things, we can refactor it
later.
In this series, let us first separate active_config and config, and
keep using drvdata->config to save complex cfg ?
> u32 off_mask;
>
> if (((offset >= TRCEVENTCTL0R) && (offset <= TRCVIPCSSCTLR)) ||
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index d565a73f0042..c552129c4a0c 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -88,9 +88,11 @@ static int etm4_probe_cpu(unsigned int cpu);
> */
> static bool etm4x_sspcicrn_present(struct etmv4_drvdata *drvdata, int n)
> {
> + struct etmv4_config *config = &drvdata->active_config;
> +
> return (n < drvdata->nr_ss_cmp) &&
> drvdata->nr_pe &&
> - (drvdata->config.ss_status[n] & TRCSSCSRn_PC);
> + (config->ss_status[n] & TRCSSCSRn_PC);
As Suzuki suggested in another reply, we need to extract capabilities
into a separate structure. I'd also extract status related registers
into a new structure:
struct etm4_cap {
int nr_ss_cmp;
bool pe_comparator; // TRCSSCSRn.PC
bool dv_comparator; // TRCSSCSRn.DV
bool da_comparator; // TRCSSCSRn.DA
bool inst_comparator; // TRCSSCSRn.INST
int ns_ex_level;
int nr_pe;
int nr_pe_cmp;
int nr_resource;
...
}
struct etm4_status_reg {
u32 ss_status[ETM_MAX_SS_CMP];
u32 cntr_val[ETMv4_MAX_CNTR];
}
[...]
> @@ -911,14 +915,17 @@ static int etm4_enable_sysfs(struct coresight_device *csdev, struct coresight_pa
>
> /* enable any config activated by configfs */
> cscfg_config_sysfs_get_active_cfg(&cfg_hash, &preset);
> +
> + raw_spin_lock(&drvdata->spinlock);
> +
> + drvdata->active_config = drvdata->config;
This is not an issue introduced by this patch, but we might need to
consider to copy active config until it has acquired SYSFS mode.
Otherwise, it might update config here but will disturb a perf session
has been running.
> @@ -2246,7 +2254,8 @@ static int etm4_add_coresight_dev(struct etm4_init_arg *init_arg)
> if (!desc.name)
> return -ENOMEM;
>
> - etm4_set_default(&drvdata->config);
> + etm4_set_default(&drvdata->active_config);
Should we set default values to drvdata->config ?
My understanding is drvdata->active_config would be always set at the
runtime, but "drvdata->config" should be initialized properly so it
can be consumed by sysfs knobs.
Thanks,
Leo
On Tue, 07 Apr 2026 19:09:05 +0800, Jie Gan wrote:
> Create the csdev_access struct only when a valid MMIO resource is
> available. In tpdm_probe(), base is uninitialized for static TPDM
> instances that lack an MMIO resource, causing csdev_access to be
> created with a garbage address.
>
> So far there has no register access for static instance, but this
> change helps mitigate potential risks in the future.
>
> [...]
Applied, thanks!
[1/1] coresight: tpdm: fix invalid MMIO access issue
https://git.kernel.org/coresight/c/971f3474f889
Best regards,
--
Suzuki K Poulose <suzuki.poulose(a)arm.com>
Hi Jie,
On Tue, Apr 07, 2026 at 04:33:22PM +0800, Jie Gan wrote:
> On 4/7/2026 4:10 PM, Leo Yan wrote:
> > On Tue, Apr 07, 2026 at 12:47:11PM +0800, Jie Gan wrote:
> > > Create the csdev_access struct only when a valid MMIO resource is
> > > available. In tpdm_probe(), base is uninitialized for static TPDM
> > > instances that lack an MMIO resource, causing csdev_access to be
> > > created with a garbage address and potentially leading to
> > > unexpected issues.
> >
> > This patch itself is fine for me. However, I am wandering if this
> > is sufficient.
> >
> > As mentioned "potentially leading to unexpected issues", can I
> > understand some code pieces access register with uninitialized base?
> > If so, you would also explictly add coresight_is_static_tpdm() to
> > prevent register access.
> >
>
> Actually, we havent MMIO access for the static TPDM device, So no issues are
> observed. The commit message here may be misleading. do I need rephrase the
> commit message?
Yes, good to clarify a bit in commit log:
"So far there has no register access for static instance, but this
change helps mitigate potential risks in the future."
With this:
Reviewed-by: Leo Yan <leo.yan(a)arm.com>
On Tue, Apr 07, 2026 at 12:47:11PM +0800, Jie Gan wrote:
> Create the csdev_access struct only when a valid MMIO resource is
> available. In tpdm_probe(), base is uninitialized for static TPDM
> instances that lack an MMIO resource, causing csdev_access to be
> created with a garbage address and potentially leading to
> unexpected issues.
This patch itself is fine for me. However, I am wandering if this
is sufficient.
As mentioned "potentially leading to unexpected issues", can I
understand some code pieces access register with uninitialized base?
If so, you would also explictly add coresight_is_static_tpdm() to
prevent register access.
Thanks,
Leo
> Fixes: 14ae052f7947 ("coresight: tpdm: add static tpdm support")
> Signed-off-by: Jie Gan <jie.gan(a)oss.qualcomm.com>
> ---
> drivers/hwtracing/coresight/coresight-tpdm.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
> index 9b16f368a58b..eaf7210af648 100644
> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
> @@ -1430,6 +1430,7 @@ static int tpdm_probe(struct device *dev, struct resource *res)
> if (ret)
> return ret;
>
> + desc.access = CSDEV_ACCESS_IOMEM(base);
> if (tpdm_has_dsb_dataset(drvdata))
> of_property_read_u32(drvdata->dev->of_node,
> "qcom,dsb-msrs-num", &drvdata->dsb_msr_num);
> @@ -1452,7 +1453,6 @@ static int tpdm_probe(struct device *dev, struct resource *res)
> desc.ops = &tpdm_cs_ops;
> desc.pdata = dev->platform_data;
> desc.dev = dev;
> - desc.access = CSDEV_ACCESS_IOMEM(base);
> if (res)
> desc.groups = tpdm_attr_grps;
> else
>
> ---
> base-commit: 816f193dd0d95246f208590924dd962b192def78
> change-id: 20260407-fix-potential-issue-in-tpdm-b07b44416051
>
> Best regards,
> --
> Jie Gan <jie.gan(a)oss.qualcomm.com>
>
This series focuses on CoreSight path power management. The changes can
be divided into four parts for review:
Patches 01 - 04: Refactor the CPU ID storing in csdev, later patches
consume csdev->cpu. Move CPU lock to sysfs layer so
it is safe for later changes.
Patches 05 - 09: Refactor the CPU idle flow with moving common code into
the CoreSight core layer.
Patches 10 - 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 CPU hotplug into the core layer, and fix sysfs
mode for hotplug.
This series is rebased on the coresight-next branch and has been verified
on Juno-r2 (ETM + ETR) and FVP RevC (ETE + TRBE). Built successfully
for armv7 (ARCH=arm).
---
Changes in v9:
- Changed to use per-CPU path pointer with lockless access.
- Removed the change for adding csdev->path, the related refactoring
will be sent separately.
- Re-orged patches to avoid intermediate breakage (sashiko).
- Link to v8: https://lore.kernel.org/r/20260325-arm_coresight_path_power_management_impr…
Changes in v8:
- Moved the "cpu" field in coresight_device for better pack with new
patch 01 (Suzuki).
- Added check if not set CPU for per_cpu_source/per_cpu_sink (Suzuki).
- Renamed spinlock name in syscfg (Suzuki).
- Refactored paired enable and disable path with new patches
10 and 12 (Suzuki).
- Link to v7: https://lore.kernel.org/r/20260320-arm_coresight_path_power_management_impr…
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…
Signed-off-by: Leo Yan <leo.yan(a)arm.com>
---
Leo Yan (19):
coresight: Extract device init into coresight_init_device()
coresight: Populate CPU ID into coresight_device
coresight: Remove .cpu_id() callback from source ops
coresight: Take hotplug lock in enable_source_store() for Sysfs mode
coresight: etm4x: Set per-CPU path on local CPU
coresight: etm3x: Set per-CPU path on local CPU
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: Move source helper disabling to coresight_disable_path()
coresight: Control path with range
coresight: Use helpers to fetch first and last nodes
coresight: Introduce coresight_enable_source() helper
coresight: Control path during CPU idle
coresight: Add PM callbacks for sink device
coresight: sysfs: Increment refcount only for system tracers
coresight: Move CPU hotplug callbacks to core layer
coresight: sysfs: Validate CPU online status for per-CPU sources
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 | 371 ++++++++++++++++++---
drivers/hwtracing/coresight/coresight-cti-core.c | 9 +-
drivers/hwtracing/coresight/coresight-etm-perf.c | 4 +-
drivers/hwtracing/coresight/coresight-etm3x-core.c | 73 +---
drivers/hwtracing/coresight/coresight-etm4x-core.c | 156 ++-------
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 | 50 ++-
drivers/hwtracing/coresight/coresight-trbe.c | 61 +++-
include/linux/coresight.h | 13 +-
12 files changed, 503 insertions(+), 263 deletions(-)
---
base-commit: ec687ba84000d7d50cf243558041f6729d1d8119
change-id: 20251104-arm_coresight_path_power_management_improvement-dab4966f8280
Best regards,
--
Leo Yan <leo.yan(a)arm.com>
On Tue, 31 Mar 2026 18:05:22 +0800, 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.
>
>
> [...]
Applied, thanks!
[1/1] coresight: tpdm: add traceid_show for checking traceid
commit: ec687ba84000d7d50cf243558041f6729d1d8119
Best regards,
--
Suzuki K Poulose <suzuki.poulose(a)arm.com>