* [PATCH v12 00/14] fix several inconsistencies with sysfs configuration in etmX
@ 2026-09-24 17:33 Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 01/14] coresight: etm4x: read-back TRCSEQSTR at disabling and prohibit modifying seq_state while enabling Yeoreum Yun
` (13 more replies)
0 siblings, 14 replies; 19+ messages in thread
From: Yeoreum Yun @ 2026-09-24 17:33 UTC (permalink / raw)
To: Mike Leach, James Clark, Leo Yan, Greg Kroah-Hartman,
Mathieu Poirier, coresight, linux-arm-kernel, linux-kernel,
linux-rt-devel
Cc: Suzuki K Poulose, Alexander Shishkin, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, Yeoreum Yun
The current ETMx 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.
- If a perf session and sysfs session tries to enable concurrently,
configuration from configfs could be corrupted (etm4).
- There is chance to corrupt drvdata->config if perf session tries
to enabled among handling cscfg_csdev_disable_active_config()
in etm4_disable_sysfs() (etm4).
To resolve these inconsistencies, the configuration should be separated into:
- curr_config, which is applied configuration for the current session
- config, which stores the settings configured via sysfs.
and apply configuration from configfs after taking a mode.
Patch History
=============
from v11 to v12:
- rename active_config to curr_config.
- rename config to sysfs_config.
- remove redundant config argument in etmX_args.
- add read-back and copy from curr_config to sysfs_config TRCSEQSTR
(seq_state).
- add r-b and t-b tags.
- Link to v11: https://lore.kernel.org/r/20260915-separate_etm_cfg_v2-v11-0-d2b258d51747@arm.com
from v10 to v11:
- replace direct register read from etm3 sysfs with IPI.
- fix issue cntr_val and others field which required to be shown after
sysfs session disable.
- prohibit the write for some etm3 sysfs while sysfs session is
enabled.
- drop locktype change in etm3
- Link to v10: https://lore.kernel.org/r/20260911-separate_etm_cfg_v2-v10-0-1b715d95927a@arm.com
from v9 to v10:
- rebase to coresight/next
- https://lore.kernel.org/all/20260725113645.57519-1-yeoreum.yun@arm.com/
from v8 to v9:
- add feat_csdev_lock guard interface.
- set feat_csdev->drv_spinlock as NULL for etmv4_drvdata.
- https://lore.kernel.org/all/20260629090007.1718746-1-yeoreum.yun@arm.com/
from v7 to v8:
- accept @Leo Yan' suggestion to handle error.
- small minor fixes following @Suzuki' suggestion.
- https://lore.kernel.org/all/20260519154812.254884-1-yeoreum.yun@arm.com/
from v6 to v7:
- rebase on coresight/next
- add ETM_MAX_SEQ_TRANSITIONS define
- remove redundant patch relavent cpu-hotplug as coresight-pm patch
merged.
- https://lore.kernel.org/all/20260422132203.977549-1-yeoreum.yun@arm.com/
from v5 to v6:
- fix missing of calling cscfg_csdev_disable_active_config()
- add rb & fixes tags.
- add ss_status field in etm4x_drvdata to expose STATUS and PENDING bits.
- https://lore.kernel.org/all/20260415165528.3369607-1-yeoreum.yun@arm.com/
from v4 to v5:
- add rb-tag.
- fix underflow issue for nrseqstate.
- fix wrong check in etm4_sspcicrn_present().
- remove redundant fields on etmv4_save_state.
- rename caps->ss_status to ss_cmp.
- fix wrong location of etm4_release_trace_id.
- https://lore.kernel.org/all/20260413142003.3549310-1-yeoreum.yun@arm.com/
from v3 to v4:
- change etm_drvdata->spinlock type to raw_spin_lock_t
- remove redundant call etmX_enable_hw() with starting_cpu() callsback.
- fix missing trace id release.
- add missing docs.
- https://lore.kernel.org/all/20260412175506.412301-1-yeoreum.yun@arm.com/
from v2 to v3:
- fix build error for etm3x.
- fix checkpatch warning.
- https://lore.kernel.org/all/20260410074310.2693385-1-yeoreum.yun@arm.com/
from v1 to v2
- rebased to v7.0-rc7.
- introduce etmX_caps structure to save etmX's capabilities.
- remove ss_status from etmv4_config.
- modify active_config after taking a mode (perf/sysfs).
- https://lore.kernel.org/all/20260317181705.2456271-1-yeoreum.yun@arm.com/
---
Yeoreum Yun (14):
coresight: etm4x: read-back TRCSEQSTR at disabling and prohibit modifying seq_state while enabling.
coresight: etm4x: prohibit modifying cntr_val while session is enabled
coresight: etm3x: prohibit modifying cntr_val and reset while session is enabled
coresight: etm4x: fix inconsistencies with sysfs configuration
coresight: etm3x: fix inconsistencies with sysfs configuration
coresight: etm3x: remove redundant cpu online check on etm_enable_sysfs()
coresight: etm4x: introduce struct etm4_caps
coresight: etm4x: exclude ss_status from drvdata->config
coresight: etm4x: remove s_ex_level from config
coresight: etm4x: rename local config as curr_config referring drvdata->curr_config
coresight: etm4x: rename drvdata->config to sysfs_config
coresight: etm3x: introduce struct etm_caps
coresight: etm3x: rename local config as curr_config referring drvdata->curr_config
coresight: etm3x: rename drvdata->config to sysfs_config
drivers/hwtracing/coresight/coresight-config.c | 18 +-
drivers/hwtracing/coresight/coresight-config.h | 22 +
drivers/hwtracing/coresight/coresight-etm.h | 48 +-
drivers/hwtracing/coresight/coresight-etm3x-core.c | 196 +++--
.../hwtracing/coresight/coresight-etm3x-sysfs.c | 461 +++++-----
drivers/hwtracing/coresight/coresight-etm4x-cfg.c | 14 +-
drivers/hwtracing/coresight/coresight-etm4x-core.c | 567 ++++++------
.../hwtracing/coresight/coresight-etm4x-sysfs.c | 961 +++++++++++----------
drivers/hwtracing/coresight/coresight-etm4x.h | 199 +++--
9 files changed, 1340 insertions(+), 1146 deletions(-)
---
base-commit: 9e3604d7369cfc0110100eb1a0acab1865ee2d18
change-id: 20260911-separate_etm_cfg_v2-3518a168cbff
Best regards,
--
Sincerely,
Yeoreum Yun
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v12 01/14] coresight: etm4x: read-back TRCSEQSTR at disabling and prohibit modifying seq_state while enabling.
2026-09-24 17:33 [PATCH v12 00/14] fix several inconsistencies with sysfs configuration in etmX Yeoreum Yun
@ 2026-09-24 17:33 ` Yeoreum Yun
2026-09-24 17:46 ` sashiko-bot
2026-09-24 17:33 ` [PATCH v12 02/14] coresight: etm4x: prohibit modifying cntr_val while session is enabled Yeoreum Yun
` (12 subsequent siblings)
13 siblings, 1 reply; 19+ messages in thread
From: Yeoreum Yun @ 2026-09-24 17:33 UTC (permalink / raw)
To: Mike Leach, James Clark, Leo Yan, Greg Kroah-Hartman,
Mathieu Poirier, coresight, linux-arm-kernel, linux-kernel,
linux-rt-devel
Cc: Suzuki K Poulose, Alexander Shishkin, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, Yeoreum Yun
TRCSEQSTR can be changed by the ETM while a session is active. Its value
therefore needs to be preserved when a sysfs session is disabled so that
users can read the current sequence state after the session ends.
This means that any changes made to TRCSEQSTR while the sysfs-session is active
would be lost when the session is disabled.
Copy the TRCSEQSTR value when disabling a sysfs session, and prohibit
modifying seq_state while the session is active.
Suggested-by: Mike Leach <mike.leach@arm.com>
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
drivers/hwtracing/coresight/coresight-etm4x-core.c | 4 ++++
drivers/hwtracing/coresight/coresight-etm4x-sysfs.c | 2 ++
2 files changed, 6 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 2247ad55d444..9ca03a5913a3 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -1073,6 +1073,10 @@ static void etm4_disable_hw(struct etmv4_drvdata *drvdata)
etm4x_relaxed_read32(csa, TRCCNTVRn(i));
}
+ /* read back the sequence state */
+ if (drvdata->nrseqstate)
+ config->seq_state = etm4x_relaxed_read32(csa, TRCSEQSTR);
+
coresight_disclaim_device_unlocked(csdev);
etm4_cs_lock(drvdata, csa);
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index cc6cdd3ae29d..db3cf4ad6806 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -1437,6 +1437,8 @@ static ssize_t seq_state_store(struct device *dev,
return -EINVAL;
if (val >= drvdata->nrseqstate)
return -EINVAL;
+ if (IS_ERR_OR_NULL(drvdata) || coresight_get_mode(drvdata->csdev))
+ return -EBUSY;
config->seq_state = val;
return size;
--
2.43.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v12 02/14] coresight: etm4x: prohibit modifying cntr_val while session is enabled
2026-09-24 17:33 [PATCH v12 00/14] fix several inconsistencies with sysfs configuration in etmX Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 01/14] coresight: etm4x: read-back TRCSEQSTR at disabling and prohibit modifying seq_state while enabling Yeoreum Yun
@ 2026-09-24 17:33 ` Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 03/14] coresight: etm3x: prohibit modifying cntr_val and reset " Yeoreum Yun
` (11 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Yeoreum Yun @ 2026-09-24 17:33 UTC (permalink / raw)
To: Mike Leach, James Clark, Leo Yan, Greg Kroah-Hartman,
Mathieu Poirier, coresight, linux-arm-kernel, linux-kernel,
linux-rt-devel
Cc: Suzuki K Poulose, Alexander Shishkin, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, Yeoreum Yun
cntr_val is overwritten with the values read from the corresponding
registers by etm4_disable_hw() when the session is disabled.
This means that any changes to these values made while the session is
enabled would be lost when the session is disabled.
Therefore, prohibit modifying cntr_val while the session is enabled.
Tested-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
drivers/hwtracing/coresight/coresight-etm4x-sysfs.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index db3cf4ad6806..a547de5a3f9c 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -1615,6 +1615,9 @@ static ssize_t cntr_val_store(struct device *dev,
return -EINVAL;
if (val > ETM_CNTR_MAX_VAL)
return -EINVAL;
+ if (IS_ERR_OR_NULL(drvdata->csdev) ||
+ coresight_get_mode(drvdata->csdev))
+ return -EBUSY;
raw_spin_lock(&drvdata->spinlock);
idx = config->cntr_idx;
--
2.43.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v12 03/14] coresight: etm3x: prohibit modifying cntr_val and reset while session is enabled
2026-09-24 17:33 [PATCH v12 00/14] fix several inconsistencies with sysfs configuration in etmX Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 01/14] coresight: etm4x: read-back TRCSEQSTR at disabling and prohibit modifying seq_state while enabling Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 02/14] coresight: etm4x: prohibit modifying cntr_val while session is enabled Yeoreum Yun
@ 2026-09-24 17:33 ` Yeoreum Yun
2026-09-24 17:58 ` sashiko-bot
2026-09-24 17:33 ` [PATCH v12 04/14] coresight: etm4x: fix inconsistencies with sysfs configuration Yeoreum Yun
` (10 subsequent siblings)
13 siblings, 1 reply; 19+ messages in thread
From: Yeoreum Yun @ 2026-09-24 17:33 UTC (permalink / raw)
To: Mike Leach, James Clark, Leo Yan, Greg Kroah-Hartman,
Mathieu Poirier, coresight, linux-arm-kernel, linux-kernel,
linux-rt-devel
Cc: Suzuki K Poulose, Alexander Shishkin, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, Yeoreum Yun
cntr_val are overwritten with the values read from the corresponding
registers by etm_disable_hw() when the session is disabled.
This means that any changes to this value made while the session is
enabled would be lost when the session is disabled.
Also, reset shouldn't be called while session is enabled.
Therefore, prohibit modifying cntr_val and reset while the session is enabled.
Reviewed-by: Mike Leach <mike.leach@arm.com>
Tested-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
drivers/hwtracing/coresight/coresight-etm3x-sysfs.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
index b3c67e96a82a..cdb70a4382eb 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
@@ -75,6 +75,10 @@ static ssize_t reset_store(struct device *dev,
if (ret)
return ret;
+ if (IS_ERR_OR_NULL(drvdata->csdev) ||
+ coresight_get_mode(drvdata->csdev))
+ return -EBUSY;
+
if (val) {
spin_lock(&drvdata->spinlock);
memset(config, 0, sizeof(struct etm_config));
@@ -744,6 +748,9 @@ static ssize_t cntr_val_store(struct device *dev,
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
+ if (IS_ERR_OR_NULL(drvdata->csdev) ||
+ coresight_get_mode(drvdata->csdev))
+ return -EBUSY;
spin_lock(&drvdata->spinlock);
config->cntr_val[config->cntr_idx] = val;
--
2.43.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v12 04/14] coresight: etm4x: fix inconsistencies with sysfs configuration
2026-09-24 17:33 [PATCH v12 00/14] fix several inconsistencies with sysfs configuration in etmX Yeoreum Yun
` (2 preceding siblings ...)
2026-09-24 17:33 ` [PATCH v12 03/14] coresight: etm3x: prohibit modifying cntr_val and reset " Yeoreum Yun
@ 2026-09-24 17:33 ` Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 05/14] coresight: etm3x: " Yeoreum Yun
` (9 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Yeoreum Yun @ 2026-09-24 17:33 UTC (permalink / raw)
To: Mike Leach, James Clark, Leo Yan, Greg Kroah-Hartman,
Mathieu Poirier, coresight, linux-arm-kernel, linux-kernel,
linux-rt-devel
Cc: Suzuki K Poulose, Alexander Shishkin, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, Yeoreum Yun
The current ETM4x configuration via sysfs can lead to
several inconsistencies:
- If the configuration is modified via sysfs while a perf session is
active, the running configuration may differ before a sched-out and
after a subsequent sched-in.
- If a perf session and a sysfs session enable tracing concurrently,
the configuration from configfs may become corrupted.
- There is a risk of corrupting drvdata->config if a perf session enables
tracing while cscfg_csdev_disable_active_config() is being handled in
etm4_disable_sysfs().
To resolve these issues, separate the configuration into:
- curr_config: the configuration applied to the current session
- config: the configuration set via sysfs
Additionally:
- Apply the configuration from configfs after taking the appropriate mode.
- Since curr_config and related fields are accessed only by the local CPU
in etm4_enable/disable_sysfs_smp_call() (similar to perf enable/disable),
remove the lock/unlock from the sysfs enable/disable path and
startup/dying_cpu except when to access config fields.
As the curr_config is used for cfg-configfs, etmv4 doesn't need to set
its lock for the cfg-configfs since the curr_config is proceted by cs_mode
otherwise it would make a possible cpu-stall when it get interrupt while
setting the sysfs configuration.
Therefore, set the drv_spinlock for cfg-configfs as NULL and
let the cfg-configfs disable irq without grap drv_spinlock when it is NULL.
Fixes: 54ff892b76c6 ("coresight: etm4x: splitting struct etmv4_drvdata")
Tested-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
drivers/hwtracing/coresight/coresight-config.c | 18 ++--
drivers/hwtracing/coresight/coresight-config.h | 22 ++++
drivers/hwtracing/coresight/coresight-etm4x-cfg.c | 13 ++-
drivers/hwtracing/coresight/coresight-etm4x-core.c | 117 ++++++++++++---------
.../hwtracing/coresight/coresight-etm4x-sysfs.c | 5 +-
drivers/hwtracing/coresight/coresight-etm4x.h | 4 +-
6 files changed, 112 insertions(+), 67 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-config.c b/drivers/hwtracing/coresight/coresight-config.c
index 4f72ae71b696..0e296289f286 100644
--- a/drivers/hwtracing/coresight/coresight-config.c
+++ b/drivers/hwtracing/coresight/coresight-config.c
@@ -73,13 +73,12 @@ static void cscfg_init_reg_param(struct cscfg_feature_csdev *feat_csdev,
/* set values into the driver locations referenced in cscfg_reg_csdev */
static int cscfg_set_on_enable(struct cscfg_feature_csdev *feat_csdev)
{
- unsigned long flags;
int i;
- raw_spin_lock_irqsave(feat_csdev->drv_spinlock, flags);
- for (i = 0; i < feat_csdev->nr_regs; i++)
- cscfg_set_reg(&feat_csdev->regs_csdev[i]);
- raw_spin_unlock_irqrestore(feat_csdev->drv_spinlock, flags);
+ scoped_guard(feat_csdev_lock, feat_csdev) {
+ for (i = 0; i < feat_csdev->nr_regs; i++)
+ cscfg_set_reg(&feat_csdev->regs_csdev[i]);
+ }
dev_dbg(&feat_csdev->csdev->dev, "Feature %s: %s",
feat_csdev->feat_desc->name, "set on enable");
return 0;
@@ -88,13 +87,12 @@ static int cscfg_set_on_enable(struct cscfg_feature_csdev *feat_csdev)
/* copy back values from the driver locations referenced in cscfg_reg_csdev */
static void cscfg_save_on_disable(struct cscfg_feature_csdev *feat_csdev)
{
- unsigned long flags;
int i;
- raw_spin_lock_irqsave(feat_csdev->drv_spinlock, flags);
- for (i = 0; i < feat_csdev->nr_regs; i++)
- cscfg_save_reg(&feat_csdev->regs_csdev[i]);
- raw_spin_unlock_irqrestore(feat_csdev->drv_spinlock, flags);
+ scoped_guard(feat_csdev_lock, feat_csdev) {
+ for (i = 0; i < feat_csdev->nr_regs; i++)
+ cscfg_save_reg(&feat_csdev->regs_csdev[i]);
+ }
dev_dbg(&feat_csdev->csdev->dev, "Feature %s: %s",
feat_csdev->feat_desc->name, "save on disable");
}
diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
index 90fd937d3bd8..ae6295e30813 100644
--- a/drivers/hwtracing/coresight/coresight-config.h
+++ b/drivers/hwtracing/coresight/coresight-config.h
@@ -7,6 +7,7 @@
#ifndef _CORESIGHT_CORESIGHT_CONFIG_H
#define _CORESIGHT_CORESIGHT_CONFIG_H
+#include <linux/cleanup.h>
#include <linux/coresight.h>
#include <linux/types.h>
@@ -259,4 +260,25 @@ void cscfg_csdev_disable_config(struct cscfg_config_csdev *config_csdev);
/* reset a feature to default values */
void cscfg_reset_feat(struct cscfg_feature_csdev *feat_csdev);
+#define feat_csdev_lock(feat_csdev, flags) \
+ do { \
+ raw_spinlock_t *__lock = feat_csdev->drv_spinlock; \
+ typecheck(unsigned long, flags); \
+ if (__lock) \
+ raw_spin_lock_irqsave(__lock, flags); \
+ } while (0)
+
+#define feat_csdev_unlock(feat_csdev, flags) \
+ do { \
+ raw_spinlock_t *__lock = feat_csdev->drv_spinlock; \
+ typecheck(unsigned long, flags); \
+ if (__lock) \
+ raw_spin_unlock_irqrestore(__lock, flags); \
+ } while (0)
+
+DEFINE_LOCK_GUARD_1(feat_csdev_lock, struct cscfg_feature_csdev,
+ feat_csdev_lock(_T->lock, _T->flags),
+ feat_csdev_unlock(_T->lock, _T->flags),
+ unsigned long flags)
+
#endif /* _CORESIGHT_CORESIGHT_CONFIG_H */
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
index e1a59b434505..a9f6ed47a2f5 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->curr_config;
u32 off_mask;
if (((offset >= TRCEVENTCTL0R) && (offset <= TRCVIPCSSCTLR)) ||
@@ -154,11 +154,14 @@ static int etm4_cfg_load_feature(struct coresight_device *csdev,
int i = 0, err = 0;
/*
- * essential we set the device spinlock - this is used in the generic
- * programming routines when copying values into the drvdata structures
- * via the pointers setup in etm4_cfg_map_reg_offset().
+ * drvdata structure of etm4 for configfs is curr_config and
+ * this curr_config is protected with csdev->mode by restricting
+ * access to curr_config after mode changed to PERF or SYSFS.
+ *
+ * Therefore, it doesn't need to protected with etmv4_drvdata->spinlock
+ * to feature applying and set the NULL.
*/
- feat_csdev->drv_spinlock = &drvdata->spinlock;
+ feat_csdev->drv_spinlock = NULL;
/* process the register descriptions */
for (i = 0; i < feat_csdev->nr_regs && !err; i++) {
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 9ca03a5913a3..61e9971bdc6b 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -264,10 +264,11 @@ static void etm4x_prohibit_trace(struct etmv4_drvdata *drvdata)
static u64 etm4x_get_kern_user_filter(struct etmv4_drvdata *drvdata)
{
u64 trfcr = drvdata->trfcr;
+ struct etmv4_config *config = &drvdata->curr_config;
- if (drvdata->config.mode & ETM_MODE_EXCL_KERN)
+ if (config->mode & ETM_MODE_EXCL_KERN)
trfcr &= ~TRFCR_EL1_ExTRE;
- if (drvdata->config.mode & ETM_MODE_EXCL_USER)
+ if (config->mode & ETM_MODE_EXCL_USER)
trfcr &= ~TRFCR_EL1_E0TRE;
return trfcr;
@@ -275,7 +276,7 @@ static u64 etm4x_get_kern_user_filter(struct etmv4_drvdata *drvdata)
/*
* etm4x_allow_trace - Allow CPU tracing in the respective ELs,
- * as configured by the drvdata->config.mode for the current
+ * as configured by the drvdata->curr_config.mode for the current
* session. Even though we have TRCVICTLR bits to filter the
* trace in the ELs, it doesn't prevent the ETM from generating
* a packet (e.g, TraceInfo) that might contain the addresses from
@@ -286,12 +287,13 @@ static u64 etm4x_get_kern_user_filter(struct etmv4_drvdata *drvdata)
static void etm4x_allow_trace(struct etmv4_drvdata *drvdata)
{
u64 trfcr, guest_trfcr;
+ struct etmv4_config *config = &drvdata->curr_config;
/* If the CPU doesn't support FEAT_TRF, nothing to do */
if (!drvdata->trfcr)
return;
- if (drvdata->config.mode & ETM_MODE_EXCL_HOST)
+ if (config->mode & ETM_MODE_EXCL_HOST)
trfcr = drvdata->trfcr & ~(TRFCR_EL1_ExTRE | TRFCR_EL1_E0TRE);
else
trfcr = etm4x_get_kern_user_filter(drvdata);
@@ -299,7 +301,7 @@ static void etm4x_allow_trace(struct etmv4_drvdata *drvdata)
write_trfcr(trfcr);
/* Set filters for guests and pass to KVM */
- if (drvdata->config.mode & ETM_MODE_EXCL_GUEST)
+ if (config->mode & ETM_MODE_EXCL_GUEST)
guest_trfcr = drvdata->trfcr & ~(TRFCR_EL1_ExTRE | TRFCR_EL1_E0TRE);
else
guest_trfcr = etm4x_get_kern_user_filter(drvdata);
@@ -492,7 +494,7 @@ static int etm4_enable_trace_unit(struct etmv4_drvdata *drvdata)
static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
{
int i, rc;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *config = &drvdata->curr_config;
struct coresight_device *csdev = drvdata->csdev;
struct device *etm_dev = &csdev->dev;
struct csdev_access *csa = &csdev->access;
@@ -612,27 +614,42 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
static void etm4_enable_sysfs_smp_call(void *info)
{
struct etm4_enable_arg *arg = info;
+ struct etmv4_drvdata *drvdata;
struct coresight_device *csdev;
+ unsigned long cfg_hash;
+ int preset;
if (WARN_ON(!arg))
return;
- csdev = arg->drvdata->csdev;
- if (!coresight_take_mode(csdev, CS_MODE_SYSFS)) {
- /* Someone is already using the tracer */
- arg->rc = -EBUSY;
- return;
+ drvdata = arg->drvdata;
+ csdev = drvdata->csdev;
+
+ /* enable any config activated by configfs */
+ cscfg_config_sysfs_get_active_cfg(&cfg_hash, &preset);
+ if (cfg_hash) {
+ arg->rc = cscfg_csdev_enable_active_config(csdev,
+ cfg_hash,
+ preset);
+ if (arg->rc)
+ return;
}
- arg->rc = etm4_enable_hw(arg->drvdata);
+ drvdata->trcid = arg->path->trace_id;
+
+ /* Tracer will never be paused in sysfs mode */
+ drvdata->paused = false;
- /* The tracer didn't start */
+ arg->rc = etm4_enable_hw(drvdata);
if (arg->rc) {
- coresight_set_mode(csdev, CS_MODE_DISABLED);
+ cscfg_csdev_disable_active_config(csdev);
return;
}
+ drvdata->sticky_enable = true;
csdev->path = arg->path;
+
+ return;
}
/*
@@ -669,7 +686,7 @@ static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata,
{
int ctridx;
int rselector;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *config = &drvdata->curr_config;
/* No point in trying if we don't have at least one counter */
if (!drvdata->nr_cntr)
@@ -752,7 +769,7 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
{
int ret = 0;
struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *config = &drvdata->curr_config;
struct perf_event_attr max_timestamp = {
.ATTR_CFG_FLD_timestamp_CFG = U64_MAX,
};
@@ -919,46 +936,36 @@ static int etm4_enable_sysfs(struct coresight_device *csdev, struct coresight_pa
{
struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
struct etm4_enable_arg arg = { };
- unsigned long cfg_hash;
- int ret, preset;
+ int ret;
- /* enable any config activated by configfs */
- cscfg_config_sysfs_get_active_cfg(&cfg_hash, &preset);
- if (cfg_hash) {
- ret = cscfg_csdev_enable_active_config(csdev, cfg_hash, preset);
- if (ret) {
- etm4_release_trace_id(drvdata);
- return ret;
- }
+ if (!coresight_take_mode(csdev, CS_MODE_SYSFS)) {
+ /* Someone is already using the tracer */
+ return -EBUSY;
}
- raw_spin_lock(&drvdata->spinlock);
-
- drvdata->trcid = path->trace_id;
-
- /* Tracer will never be paused in sysfs mode */
- drvdata->paused = false;
-
/*
* Executing etm4_enable_hw on the cpu whose ETM is being enabled
* ensures that register writes occur when cpu is powered.
*/
arg.drvdata = drvdata;
arg.path = path;
+
+ scoped_guard(raw_spinlock, &drvdata->spinlock) {
+ drvdata->curr_config = drvdata->config;
+ }
+
ret = smp_call_function_single(drvdata->cpu,
etm4_enable_sysfs_smp_call, &arg, 1);
if (!ret)
ret = arg.rc;
- if (!ret)
- drvdata->sticky_enable = true;
-
- if (ret)
+ if (!ret) {
+ dev_dbg(&csdev->dev, "ETM tracing enabled\n");
+ } else {
etm4_release_trace_id(drvdata);
+ /* The tracer didn't start */
+ coresight_set_mode(csdev, CS_MODE_DISABLED);
+ }
- raw_spin_unlock(&drvdata->spinlock);
-
- if (!ret)
- dev_dbg(&csdev->dev, "ETM tracing enabled\n");
return ret;
}
@@ -1044,7 +1051,7 @@ static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata)
static void etm4_disable_hw(struct etmv4_drvdata *drvdata)
{
u32 control;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *config = &drvdata->curr_config;
struct coresight_device *csdev = drvdata->csdev;
struct csdev_access *csa = &csdev->access;
int i;
@@ -1090,8 +1097,9 @@ static void etm4_disable_sysfs_smp_call(void *info)
etm4_disable_hw(drvdata);
+ cscfg_csdev_disable_active_config(drvdata->csdev);
+
drvdata->csdev->path = NULL;
- coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED);
}
static int etm4_disable_perf(struct coresight_device *csdev,
@@ -1134,8 +1142,9 @@ static int etm4_disable_perf(struct coresight_device *csdev,
static void etm4_disable_sysfs(struct coresight_device *csdev)
{
struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-
- raw_spin_lock(&drvdata->spinlock);
+ struct etmv4_config *config = &drvdata->config;
+ const struct etmv4_config *curr_config = &drvdata->curr_config;
+ int i;
/*
* Executing etm4_disable_hw on the cpu whose ETM is being disabled
@@ -1144,9 +1153,19 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
smp_call_function_single(drvdata->cpu, etm4_disable_sysfs_smp_call,
drvdata, 1);
- raw_spin_unlock(&drvdata->spinlock);
+ /*
+ * Userspace may read ss_status and cntr_val through sysfs after
+ * the sysfs-session has been disabled.
+ */
+ for (i = 0; i < drvdata->nr_ss_cmp; i++)
+ config->ss_status[i] = curr_config->ss_status[i];
- cscfg_csdev_disable_active_config(csdev);
+ for (i = 0; i < drvdata->nr_cntr; i++)
+ config->cntr_val[i] = curr_config->cntr_val[i];
+
+ config->seq_state = curr_config->seq_state;
+
+ coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED);
/*
* we only release trace IDs when resetting sysfs.
@@ -1694,7 +1713,7 @@ static void etm4_set_default(struct etmv4_config *config)
static int etm4_get_next_comparator(struct etmv4_drvdata *drvdata, u32 type)
{
int nr_comparator, index = 0;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *config = &drvdata->curr_config;
/*
* nr_addr_cmp holds the number of comparator _pair_, so time 2
@@ -1735,7 +1754,7 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata,
{
int i, comparator, ret = 0;
u64 address;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *config = &drvdata->curr_config;
struct etm_filters *filters = event->hw.addr_filters;
if (!filters)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index a547de5a3f9c..9c237507ac30 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -1437,7 +1437,8 @@ static ssize_t seq_state_store(struct device *dev,
return -EINVAL;
if (val >= drvdata->nrseqstate)
return -EINVAL;
- if (IS_ERR_OR_NULL(drvdata) || coresight_get_mode(drvdata->csdev))
+ if (IS_ERR_OR_NULL(drvdata) ||
+ coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS)
return -EBUSY;
config->seq_state = val;
@@ -1616,7 +1617,7 @@ static ssize_t cntr_val_store(struct device *dev,
if (val > ETM_CNTR_MAX_VAL)
return -EINVAL;
if (IS_ERR_OR_NULL(drvdata->csdev) ||
- coresight_get_mode(drvdata->csdev))
+ coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS)
return -EBUSY;
raw_spin_lock(&drvdata->spinlock);
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
index df9e0748d71e..52f66e26ceaa 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -1019,7 +1019,8 @@ struct etmv4_save_state {
* allows tracing at all ELs. We don't want to compute this
* at runtime, due to the additional setting of TRFCR_CX when
* in EL2. Otherwise, 0.
- * @config: structure holding configuration parameters.
+ * @curr_config: structure holding current applied configuration.
+ * @config: structure holding sysfs mode configuration.
* @save_state: State to be preserved across power loss
* @skip_power_up: Indicates if an implementation can skip powering up
* the trace unit.
@@ -1077,6 +1078,7 @@ struct etmv4_drvdata {
bool skip_power_up : 1;
bool paused : 1;
u64 trfcr;
+ struct etmv4_config curr_config;
struct etmv4_config config;
struct etmv4_save_state *save_state;
DECLARE_BITMAP(arch_features, ETM4_IMPDEF_FEATURE_MAX);
--
2.43.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v12 05/14] coresight: etm3x: fix inconsistencies with sysfs configuration
2026-09-24 17:33 [PATCH v12 00/14] fix several inconsistencies with sysfs configuration in etmX Yeoreum Yun
` (3 preceding siblings ...)
2026-09-24 17:33 ` [PATCH v12 04/14] coresight: etm4x: fix inconsistencies with sysfs configuration Yeoreum Yun
@ 2026-09-24 17:33 ` Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 06/14] coresight: etm3x: remove redundant cpu online check on etm_enable_sysfs() Yeoreum Yun
` (8 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Yeoreum Yun @ 2026-09-24 17:33 UTC (permalink / raw)
To: Mike Leach, James Clark, Leo Yan, Greg Kroah-Hartman,
Mathieu Poirier, coresight, linux-arm-kernel, linux-kernel,
linux-rt-devel
Cc: Suzuki K Poulose, Alexander Shishkin, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, Yeoreum Yun
The current ETM3x 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.
To resolve these issues, separate the configuration into:
- curr_config: the configuration applied to the current session
- config: the configuration set via sysfs
Additionally:
- Since curr_config and related fields are accessed only by the local CPU
in etm_enable/disable_sysfs_smp_call() (similar to perf enable/disable),
remove the lock/unlock from the sysfs enable/disable path and
starting/dying_cpu path except when to access config fields only.
- Some of sysfs interface read etm register directly. To reduce lock
scope while the etm_enable_hw()/etm_disable_hw(), handle it via
IPI so that registers could be read from on proper CPU.
Fixes: 1925a470ce69 ("coresight: etm3x: splitting struct etm_drvdata")
Tested-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
drivers/hwtracing/coresight/coresight-etm.h | 4 +-
drivers/hwtracing/coresight/coresight-etm3x-core.c | 66 ++++++++++--------
.../hwtracing/coresight/coresight-etm3x-sysfs.c | 80 +++++++++++++++-------
3 files changed, 98 insertions(+), 52 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm.h b/drivers/hwtracing/coresight/coresight-etm.h
index 1d753cca2943..52f23a3c7364 100644
--- a/drivers/hwtracing/coresight/coresight-etm.h
+++ b/drivers/hwtracing/coresight/coresight-etm.h
@@ -226,7 +226,8 @@ struct etm_config {
* @etmccr: value of register ETMCCR.
* @etmccer: value of register ETMCCER.
* @traceid: value of the current ID for this component.
- * @config: structure holding configuration parameters.
+ * @curr_config: structure holding current running configuration.
+ * @config: structure holding sysfs mode configuration.
*/
struct etm_drvdata {
struct csdev_access csa;
@@ -248,6 +249,7 @@ struct etm_drvdata {
u32 etmccr;
u32 etmccer;
u32 traceid;
+ struct etm_config curr_config;
struct etm_config config;
};
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
index 862ad0786699..dcadcc383012 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
@@ -308,7 +308,7 @@ void etm_config_trace_mode(struct etm_config *config)
static int etm_parse_event_config(struct etm_drvdata *drvdata,
struct perf_event *event)
{
- struct etm_config *config = &drvdata->config;
+ struct etm_config *config = &drvdata->curr_config;
struct perf_event_attr *attr = &event->attr;
u8 ts_level;
@@ -367,7 +367,7 @@ static int etm_enable_hw(struct etm_drvdata *drvdata)
{
int i, rc;
u32 etmcr;
- struct etm_config *config = &drvdata->config;
+ struct etm_config *config = &drvdata->curr_config;
struct coresight_device *csdev = drvdata->csdev;
CS_UNLOCK(drvdata->csa.base);
@@ -448,26 +448,22 @@ struct etm_enable_arg {
static void etm_enable_sysfs_smp_call(void *info)
{
struct etm_enable_arg *arg = info;
+ struct etm_drvdata *drvdata;
struct coresight_device *csdev;
if (WARN_ON(!arg))
return;
- csdev = arg->drvdata->csdev;
- if (!coresight_take_mode(csdev, CS_MODE_SYSFS)) {
- /* Someone is already using the tracer */
- arg->rc = -EBUSY;
- return;
- }
+ drvdata = arg->drvdata;
+ csdev = drvdata->csdev;
- arg->rc = etm_enable_hw(arg->drvdata);
+ drvdata->traceid = arg->path->trace_id;
- /* The tracer didn't start */
- if (arg->rc) {
- coresight_set_mode(csdev, CS_MODE_DISABLED);
+ arg->rc = etm_enable_hw(arg->drvdata);
+ if (arg->rc)
return;
- }
+ drvdata->sticky_enable = true;
csdev->path = arg->path;
}
@@ -512,9 +508,10 @@ static int etm_enable_sysfs(struct coresight_device *csdev, struct coresight_pat
struct etm_enable_arg arg = { };
int ret;
- spin_lock(&drvdata->spinlock);
-
- drvdata->traceid = path->trace_id;
+ if (!coresight_take_mode(csdev, CS_MODE_SYSFS)) {
+ /* Someone is already using the tracer */
+ return -EBUSY;
+ }
/*
* Configure the ETM only if the CPU is online. If it isn't online
@@ -523,23 +520,27 @@ static int etm_enable_sysfs(struct coresight_device *csdev, struct coresight_pat
if (cpu_online(drvdata->cpu)) {
arg.drvdata = drvdata;
arg.path = path;
+
+ scoped_guard(spinlock, &drvdata->spinlock) {
+ drvdata->curr_config = drvdata->config;
+ }
+
ret = smp_call_function_single(drvdata->cpu,
etm_enable_sysfs_smp_call, &arg, 1);
if (!ret)
ret = arg.rc;
- if (!ret)
- drvdata->sticky_enable = true;
} else {
ret = -ENODEV;
}
- if (ret)
+ if (!ret) {
+ dev_dbg(&csdev->dev, "ETM tracing enabled\n");
+ } else {
etm_release_trace_id(drvdata);
+ /* The tracer didn't start */
+ coresight_set_mode(csdev, CS_MODE_DISABLED);
+ }
- spin_unlock(&drvdata->spinlock);
-
- if (!ret)
- dev_dbg(&csdev->dev, "ETM tracing enabled\n");
return ret;
}
@@ -565,7 +566,7 @@ static int etm_enable(struct coresight_device *csdev, struct perf_event *event,
static void etm_disable_hw(struct etm_drvdata *drvdata)
{
int i;
- struct etm_config *config = &drvdata->config;
+ struct etm_config *config = &drvdata->curr_config;
struct coresight_device *csdev = drvdata->csdev;
CS_UNLOCK(drvdata->csa.base);
@@ -593,7 +594,6 @@ static void etm_disable_sysfs_smp_call(void *info)
etm_disable_hw(drvdata);
drvdata->csdev->path = NULL;
- coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED);
}
static void etm_disable_perf(struct coresight_device *csdev)
@@ -630,8 +630,9 @@ static void etm_disable_perf(struct coresight_device *csdev)
static void etm_disable_sysfs(struct coresight_device *csdev)
{
struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-
- spin_lock(&drvdata->spinlock);
+ struct etm_config *config = &drvdata->config;
+ const struct etm_config *curr_config = &drvdata->curr_config;
+ int i;
/*
* Executing etm_disable_hw on the cpu whose ETM is being disabled
@@ -640,7 +641,14 @@ static void etm_disable_sysfs(struct coresight_device *csdev)
smp_call_function_single(drvdata->cpu, etm_disable_sysfs_smp_call,
drvdata, 1);
- spin_unlock(&drvdata->spinlock);
+ /*
+ * Userspace may read seq_curr_state and cntr_val through sysfs
+ * after the sysfs-session has been disabled.
+ */
+ for (i = 0; i < drvdata->nr_cntr; i++)
+ config->cntr_val[i] = curr_config->cntr_val[i];
+
+ config->seq_curr_state = curr_config->seq_curr_state;
/*
* we only release trace IDs when resetting sysfs.
@@ -649,6 +657,8 @@ static void etm_disable_sysfs(struct coresight_device *csdev)
* prior trace id allocation method
*/
+ coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED);
+
dev_dbg(&csdev->dev, "ETM tracing disabled\n");
}
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
index cdb70a4382eb..284998f18017 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
@@ -6,10 +6,48 @@
#include <linux/pid_namespace.h>
#include <linux/pm_runtime.h>
+#include <linux/smp.h>
#include <linux/sysfs.h>
#include "coresight-etm.h"
#include "coresight-priv.h"
+struct etm_readl_cslocked_arg {
+ struct etm_drvdata *drvdata;
+ u32 off;
+ unsigned long *val;
+};
+
+static void etm_readl_cslocked_smp_call(void *info)
+{
+ struct etm_readl_cslocked_arg *arg = info;
+
+ CS_UNLOCK(arg->drvdata->csa.base);
+ *arg->val = etm_readl(arg->drvdata, arg->off);
+ CS_LOCK(arg->drvdata->csa.base);
+}
+
+static int etm_readl_cslocked(struct etm_drvdata *drvdata, u32 off,
+ unsigned long *val)
+{
+ int ret;
+ struct etm_readl_cslocked_arg arg;
+
+ ret = pm_runtime_get_sync(drvdata->csdev->dev.parent);
+ if (ret < 0)
+ goto out;
+
+ arg.drvdata = drvdata;
+ arg.off = off;
+ arg.val = val;
+
+ ret = smp_call_function_single(drvdata->cpu,
+ etm_readl_cslocked_smp_call,
+ (void *)&arg, 1);
+out:
+ pm_runtime_put(drvdata->csdev->dev.parent);
+ return ret;
+}
+
static ssize_t nr_addr_cmp_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -45,18 +83,13 @@ static DEVICE_ATTR_RO(nr_ctxid_cmp);
static ssize_t etmsr_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- unsigned long flags, val;
+ int ret;
+ unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- pm_runtime_get_sync(dev->parent);
- spin_lock_irqsave(&drvdata->spinlock, flags);
- CS_UNLOCK(drvdata->csa.base);
-
- val = etm_readl(drvdata, ETMSR);
-
- CS_LOCK(drvdata->csa.base);
- spin_unlock_irqrestore(&drvdata->spinlock, flags);
- pm_runtime_put(dev->parent);
+ ret = etm_readl_cslocked(drvdata, ETMSR, &val);
+ if (ret)
+ return ret;
return sprintf(buf, "%#lx\n", val);
}
@@ -76,7 +109,7 @@ static ssize_t reset_store(struct device *dev,
return ret;
if (IS_ERR_OR_NULL(drvdata->csdev) ||
- coresight_get_mode(drvdata->csdev))
+ coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS)
return -EBUSY;
if (val) {
@@ -721,7 +754,9 @@ static DEVICE_ATTR_RW(cntr_rld_event);
static ssize_t cntr_val_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
+ int ret;
u32 val;
+ unsigned long val2;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
struct etm_config *config = &drvdata->config;
@@ -730,7 +765,10 @@ static ssize_t cntr_val_show(struct device *dev,
val = config->cntr_val[config->cntr_idx];
spin_unlock(&drvdata->spinlock);
} else {
- val = etm_readl(drvdata, ETMCNTVRn(config->cntr_idx));
+ ret = etm_readl_cslocked(drvdata, ETMCNTVRn(config->cntr_idx), &val2);
+ if (ret)
+ return ret;
+ val = val2;
}
return sysfs_emit(buf, "%#x\n", val);
@@ -749,7 +787,7 @@ static ssize_t cntr_val_store(struct device *dev,
if (ret)
return ret;
if (IS_ERR_OR_NULL(drvdata->csdev) ||
- coresight_get_mode(drvdata->csdev))
+ coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS)
return -EBUSY;
spin_lock(&drvdata->spinlock);
@@ -937,7 +975,8 @@ static DEVICE_ATTR_RW(seq_13_event);
static ssize_t seq_curr_state_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- unsigned long val, flags;
+ int ret;
+ unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
struct etm_config *config = &drvdata->config;
@@ -946,15 +985,10 @@ static ssize_t seq_curr_state_show(struct device *dev,
goto out;
}
- pm_runtime_get_sync(dev->parent);
- spin_lock_irqsave(&drvdata->spinlock, flags);
-
- CS_UNLOCK(drvdata->csa.base);
- val = (etm_readl(drvdata, ETMSQR) & ETM_SQR_MASK);
- CS_LOCK(drvdata->csa.base);
-
- spin_unlock_irqrestore(&drvdata->spinlock, flags);
- pm_runtime_put(dev->parent);
+ ret = etm_readl_cslocked(drvdata, ETMSQR, &val);
+ if (ret)
+ return ret;
+ val &= ETM_SQR_MASK;
out:
return sprintf(buf, "%#lx\n", val);
}
--
2.43.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v12 06/14] coresight: etm3x: remove redundant cpu online check on etm_enable_sysfs()
2026-09-24 17:33 [PATCH v12 00/14] fix several inconsistencies with sysfs configuration in etmX Yeoreum Yun
` (4 preceding siblings ...)
2026-09-24 17:33 ` [PATCH v12 05/14] coresight: etm3x: " Yeoreum Yun
@ 2026-09-24 17:33 ` Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 07/14] coresight: etm4x: introduce struct etm4_caps Yeoreum Yun
` (7 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Yeoreum Yun @ 2026-09-24 17:33 UTC (permalink / raw)
To: Mike Leach, James Clark, Leo Yan, Greg Kroah-Hartman,
Mathieu Poirier, coresight, linux-arm-kernel, linux-kernel,
linux-rt-devel
Cc: Suzuki K Poulose, Alexander Shishkin, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, Yeoreum Yun
cpu online() check is done in coresight_validate_source_sysfs() already.
and smp_call_function_single() will fail when cpu is offline.
Therefore, remove redundant check in etm_enable_sysfs().
Reviewed-by: Mike Leach <mike.leach@arm.com>
Tested-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
drivers/hwtracing/coresight/coresight-etm3x-core.c | 26 +++++++++-------------
1 file changed, 10 insertions(+), 16 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
index dcadcc383012..ac7c154720cb 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
@@ -513,25 +513,19 @@ static int etm_enable_sysfs(struct coresight_device *csdev, struct coresight_pat
return -EBUSY;
}
- /*
- * Configure the ETM only if the CPU is online. If it isn't online
- * hw configuration will take place on the local CPU during bring up.
- */
- if (cpu_online(drvdata->cpu)) {
- arg.drvdata = drvdata;
- arg.path = path;
+ arg.drvdata = drvdata;
+ arg.path = path;
- scoped_guard(spinlock, &drvdata->spinlock) {
- drvdata->curr_config = drvdata->config;
- }
+ scoped_guard(spinlock, &drvdata->spinlock) {
+ drvdata->curr_config = drvdata->config;
+ }
- ret = smp_call_function_single(drvdata->cpu,
- etm_enable_sysfs_smp_call, &arg, 1);
- if (!ret)
- ret = arg.rc;
- } else {
+ ret = smp_call_function_single(drvdata->cpu,
+ etm_enable_sysfs_smp_call, &arg, 1);
+ if (!ret)
+ ret = arg.rc;
+ else
ret = -ENODEV;
- }
if (!ret) {
dev_dbg(&csdev->dev, "ETM tracing enabled\n");
--
2.43.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v12 07/14] coresight: etm4x: introduce struct etm4_caps
2026-09-24 17:33 [PATCH v12 00/14] fix several inconsistencies with sysfs configuration in etmX Yeoreum Yun
` (5 preceding siblings ...)
2026-09-24 17:33 ` [PATCH v12 06/14] coresight: etm3x: remove redundant cpu online check on etm_enable_sysfs() Yeoreum Yun
@ 2026-09-24 17:33 ` Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 08/14] coresight: etm4x: exclude ss_status from drvdata->config Yeoreum Yun
` (6 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Yeoreum Yun @ 2026-09-24 17:33 UTC (permalink / raw)
To: Mike Leach, James Clark, Leo Yan, Greg Kroah-Hartman,
Mathieu Poirier, coresight, linux-arm-kernel, linux-kernel,
linux-rt-devel
Cc: Suzuki K Poulose, Alexander Shishkin, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, Yeoreum Yun
Introduce struct etm4_caps to describe ETMv4 capabilities
and move capabilities information into it.
Reviewed-by: Leo Yan <leo.yan@arm.com>
Reviewed-by: Mike LEach <mike.leach@arm.com>
Tested-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
drivers/hwtracing/coresight/coresight-etm4x-core.c | 246 +++++++++++----------
.../hwtracing/coresight/coresight-etm4x-sysfs.c | 192 +++++++++-------
drivers/hwtracing/coresight/coresight-etm4x.h | 180 ++++++++-------
3 files changed, 337 insertions(+), 281 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 61e9971bdc6b..3900b96e9c7c 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -92,8 +92,9 @@ static int etm4_probe_cpu(unsigned int cpu);
*/
static bool etm4x_sspcicrn_present(struct etmv4_drvdata *drvdata, int n)
{
- return (n < drvdata->nr_ss_cmp) &&
- drvdata->nr_pe_cmp &&
+ const struct etmv4_caps *caps = &drvdata->caps;
+
+ return (n < caps->nr_ss_cmp) && caps->nr_pe_cmp &&
(drvdata->config.ss_status[n] & TRCSSCSRn_PC);
}
@@ -164,17 +165,20 @@ static void ete_sysreg_write(u64 val, u32 offset, bool _relaxed, bool _64bit)
static void etm_detect_os_lock(struct etmv4_drvdata *drvdata,
struct csdev_access *csa)
{
+ struct etmv4_caps *caps = &drvdata->caps;
u32 oslsr = etm4x_relaxed_read32(csa, TRCOSLSR);
- drvdata->os_lock_model = ETM_OSLSR_OSLM(oslsr);
+ caps->os_lock_model = ETM_OSLSR_OSLM(oslsr);
}
static void etm_write_os_lock(struct etmv4_drvdata *drvdata,
struct csdev_access *csa, u32 val)
{
+ const struct etmv4_caps *caps = &drvdata->caps;
+
val = !!val;
- switch (drvdata->os_lock_model) {
+ switch (caps->os_lock_model) {
case ETM_OSLOCK_PRESENT:
etm4x_relaxed_write32(csa, val, TRCOSLAR);
break;
@@ -183,7 +187,7 @@ static void etm_write_os_lock(struct etmv4_drvdata *drvdata,
break;
default:
pr_warn_once("CPU%d: Unsupported Trace OSLock model: %x\n",
- smp_processor_id(), drvdata->os_lock_model);
+ smp_processor_id(), caps->os_lock_model);
fallthrough;
case ETM_OSLOCK_NI:
return;
@@ -494,6 +498,7 @@ static int etm4_enable_trace_unit(struct etmv4_drvdata *drvdata)
static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
{
int i, rc;
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->curr_config;
struct coresight_device *csdev = drvdata->csdev;
struct device *etm_dev = &csdev->dev;
@@ -525,14 +530,14 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 1))
dev_err(etm_dev,
"timeout while waiting for Idle Trace Status\n");
- if (drvdata->nr_pe)
+ if (caps->nr_pe)
etm4x_relaxed_write32(csa, config->pe_sel, TRCPROCSELR);
etm4x_relaxed_write32(csa, config->cfg, TRCCONFIGR);
/* nothing specific implemented */
etm4x_relaxed_write32(csa, 0x0, TRCAUXCTLR);
etm4x_relaxed_write32(csa, config->eventctrl0, TRCEVENTCTL0R);
etm4x_relaxed_write32(csa, config->eventctrl1, TRCEVENTCTL1R);
- if (drvdata->stallctl)
+ if (caps->stallctl)
etm4x_relaxed_write32(csa, config->stall_ctrl, TRCSTALLCTLR);
etm4x_relaxed_write32(csa, config->ts_ctrl, TRCTSCTLR);
etm4x_relaxed_write32(csa, config->syncfreq, TRCSYNCPR);
@@ -542,18 +547,18 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
etm4x_relaxed_write32(csa, config->vinst_ctrl, TRCVICTLR);
etm4x_relaxed_write32(csa, config->viiectlr, TRCVIIECTLR);
etm4x_relaxed_write32(csa, config->vissctlr, TRCVISSCTLR);
- if (drvdata->nr_pe_cmp)
+ if (caps->nr_pe_cmp)
etm4x_relaxed_write32(csa, config->vipcssctlr, TRCVIPCSSCTLR);
- for (i = 0; i < drvdata->nr_seq_ctrls; i++)
+ for (i = 0; i < caps->nr_seq_ctrls; i++)
etm4x_relaxed_write32(csa, config->seq_ctrl[i], TRCSEQEVRn(i));
- if (drvdata->nrseqstate) {
+ if (caps->nrseqstate) {
etm4x_relaxed_write32(csa, config->seq_rst, TRCSEQRSTEVR);
etm4x_relaxed_write32(csa, config->seq_state, TRCSEQSTR);
}
- if (drvdata->numextinsel)
+ if (caps->numextinsel)
etm4x_relaxed_write32(csa, config->ext_inp, TRCEXTINSELR);
- for (i = 0; i < drvdata->nr_cntr; i++) {
+ for (i = 0; i < caps->nr_cntr; i++) {
etm4x_relaxed_write32(csa, config->cntrldvr[i], TRCCNTRLDVRn(i));
etm4x_relaxed_write32(csa, config->cntr_ctrl[i], TRCCNTCTLRn(i));
etm4x_relaxed_write32(csa, config->cntr_val[i], TRCCNTVRn(i));
@@ -563,10 +568,10 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
* Resource selector pair 0 is always implemented and reserved. As
* such start at 2.
*/
- for (i = 2; i < drvdata->nr_resource * 2; i++)
+ for (i = 2; i < caps->nr_resource * 2; i++)
etm4x_relaxed_write32(csa, config->res_ctrl[i], TRCRSCTLRn(i));
- for (i = 0; i < drvdata->nr_ss_cmp; i++) {
+ for (i = 0; i < caps->nr_ss_cmp; i++) {
/* always clear status bit on restart if using single-shot */
if (config->ss_ctrl[i] || config->ss_pe_cmp[i])
config->ss_status[i] &= ~TRCSSCSRn_STATUS;
@@ -575,23 +580,23 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
if (etm4x_sspcicrn_present(drvdata, i))
etm4x_relaxed_write32(csa, config->ss_pe_cmp[i], TRCSSPCICRn(i));
}
- for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) {
+ for (i = 0; i < caps->nr_addr_cmp * 2; i++) {
etm4x_relaxed_write64(csa, config->addr_val[i], TRCACVRn(i));
etm4x_relaxed_write64(csa, config->addr_acc[i], TRCACATRn(i));
}
- for (i = 0; i < drvdata->numcidc; i++)
+ for (i = 0; i < caps->numcidc; i++)
etm4x_relaxed_write64(csa, config->ctxid_pid[i], TRCCIDCVRn(i));
etm4x_relaxed_write32(csa, config->ctxid_mask0, TRCCIDCCTLR0);
- if (drvdata->numcidc > 4)
+ if (caps->numcidc > 4)
etm4x_relaxed_write32(csa, config->ctxid_mask1, TRCCIDCCTLR1);
- for (i = 0; i < drvdata->numvmidc; i++)
+ for (i = 0; i < caps->numvmidc; i++)
etm4x_relaxed_write64(csa, config->vmid_val[i], TRCVMIDCVRn(i));
etm4x_relaxed_write32(csa, config->vmid_mask0, TRCVMIDCCTLR0);
- if (drvdata->numvmidc > 4)
+ if (caps->numvmidc > 4)
etm4x_relaxed_write32(csa, config->vmid_mask1, TRCVMIDCCTLR1);
- if (!drvdata->skip_power_up) {
+ if (!caps->skip_power_up) {
u32 trcpdcr = etm4x_relaxed_read32(csa, TRCPDCR);
/*
@@ -686,19 +691,20 @@ static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata,
{
int ctridx;
int rselector;
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->curr_config;
/* No point in trying if we don't have at least one counter */
- if (!drvdata->nr_cntr)
+ if (!caps->nr_cntr)
return -EINVAL;
/* Find a counter that hasn't been initialised */
- for (ctridx = 0; ctridx < drvdata->nr_cntr; ctridx++)
+ for (ctridx = 0; ctridx < caps->nr_cntr; ctridx++)
if (config->cntr_val[ctridx] == 0)
break;
/* All the counters have been configured already, bail out */
- if (ctridx == drvdata->nr_cntr) {
+ if (ctridx == caps->nr_cntr) {
pr_debug("%s: no available counter found\n", __func__);
return -ENOSPC;
}
@@ -714,11 +720,11 @@ static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata,
* ETMIDR4 gives the number of resource selector _pairs_, hence multiply
* by 2.
*/
- for (rselector = 2; rselector < drvdata->nr_resource * 2; rselector++)
+ for (rselector = 2; rselector < caps->nr_resource * 2; rselector++)
if (!config->res_ctrl[rselector])
break;
- if (rselector == drvdata->nr_resource * 2) {
+ if (rselector == caps->nr_resource * 2) {
pr_debug("%s: no available resource selector found\n",
__func__);
return -ENOSPC;
@@ -769,6 +775,7 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
{
int ret = 0;
struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->curr_config;
struct perf_event_attr max_timestamp = {
.ATTR_CFG_FLD_timestamp_CFG = U64_MAX,
@@ -807,8 +814,8 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
cc_threshold = ATTR_CFG_GET_FLD(attr, cc_threshold);
if (!cc_threshold)
cc_threshold = ETM_CYC_THRESHOLD_DEFAULT;
- if (cc_threshold < drvdata->ccitmin)
- cc_threshold = drvdata->ccitmin;
+ if (cc_threshold < caps->ccitmin)
+ cc_threshold = caps->ccitmin;
config->ccctlr = cc_threshold;
}
@@ -856,13 +863,13 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
}
/* return stack - enable if selected and supported */
- if (ATTR_CFG_GET_FLD(attr, retstack) && drvdata->retstack)
+ if (ATTR_CFG_GET_FLD(attr, retstack) && caps->retstack)
/* bit[12], Return stack enable bit */
config->cfg |= TRCCONFIGR_RS;
/* branch broadcast - enable if selected and supported */
if (ATTR_CFG_GET_FLD(attr, branch_broadcast)) {
- if (!drvdata->trcbb) {
+ if (!caps->trcbb) {
/*
* Missing BB support could cause silent decode errors
* so fail to open if it's not supported.
@@ -1051,6 +1058,7 @@ static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata)
static void etm4_disable_hw(struct etmv4_drvdata *drvdata)
{
u32 control;
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->curr_config;
struct coresight_device *csdev = drvdata->csdev;
struct csdev_access *csa = &csdev->access;
@@ -1059,7 +1067,7 @@ static void etm4_disable_hw(struct etmv4_drvdata *drvdata)
etm4_cs_unlock(drvdata, csa);
etm4_disable_arch_specific(drvdata);
- if (!drvdata->skip_power_up) {
+ if (!caps->skip_power_up) {
/* power can be removed from the trace unit now */
control = etm4x_relaxed_read32(csa, TRCPDCR);
control &= ~TRCPDCR_PU;
@@ -1069,19 +1077,19 @@ static void etm4_disable_hw(struct etmv4_drvdata *drvdata)
etm4_disable_trace_unit(drvdata);
/* read the status of the single shot comparators */
- for (i = 0; i < drvdata->nr_ss_cmp; i++) {
+ for (i = 0; i < caps->nr_ss_cmp; i++) {
config->ss_status[i] =
etm4x_relaxed_read32(csa, TRCSSCSRn(i));
}
/* read back the current counter values */
- for (i = 0; i < drvdata->nr_cntr; i++) {
+ for (i = 0; i < caps->nr_cntr; i++) {
config->cntr_val[i] =
etm4x_relaxed_read32(csa, TRCCNTVRn(i));
}
/* read back the sequence state */
- if (drvdata->nrseqstate)
+ if (caps->nrseqstate)
config->seq_state = etm4x_relaxed_read32(csa, TRCSEQSTR);
coresight_disclaim_device_unlocked(csdev);
@@ -1142,6 +1150,7 @@ static int etm4_disable_perf(struct coresight_device *csdev,
static void etm4_disable_sysfs(struct coresight_device *csdev)
{
struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
const struct etmv4_config *curr_config = &drvdata->curr_config;
int i;
@@ -1157,10 +1166,10 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
* Userspace may read ss_status and cntr_val through sysfs after
* the sysfs-session has been disabled.
*/
- for (i = 0; i < drvdata->nr_ss_cmp; i++)
+ for (i = 0; i < caps->nr_ss_cmp; i++)
config->ss_status[i] = curr_config->ss_status[i];
- for (i = 0; i < drvdata->nr_cntr; i++)
+ for (i = 0; i < caps->nr_cntr; i++)
config->cntr_val[i] = curr_config->cntr_val[i];
config->seq_state = curr_config->seq_state;
@@ -1376,7 +1385,7 @@ static struct midr_range etm_wrong_ccitmin_cpus[] = {
{},
};
-static void etm4_fixup_wrong_ccitmin(struct etmv4_drvdata *drvdata)
+static void etm4_fixup_wrong_ccitmin(struct etmv4_caps *caps)
{
/*
* Erratum affected cpus will read 256 as the minimum
@@ -1386,8 +1395,8 @@ static void etm4_fixup_wrong_ccitmin(struct etmv4_drvdata *drvdata)
* this problem.
*/
if (is_midr_in_range_list(etm_wrong_ccitmin_cpus)) {
- if (drvdata->ccitmin == 256)
- drvdata->ccitmin = 4;
+ if (caps->ccitmin == 256)
+ caps->ccitmin = 4;
}
}
@@ -1400,11 +1409,13 @@ static void etm4_init_arch_data(void *info)
u32 etmidr5;
struct etm4_init_arg *init_arg = info;
struct etmv4_drvdata *drvdata;
+ struct etmv4_caps *caps;
struct csdev_access *csa;
struct device *dev = init_arg->dev;
int i;
drvdata = dev_get_drvdata(init_arg->dev);
+ caps = &drvdata->caps;
csa = init_arg->csa;
/*
@@ -1417,7 +1428,7 @@ static void etm4_init_arch_data(void *info)
if (!csa->io_mem ||
fwnode_property_present(dev_fwnode(dev), "qcom,skip-power-up"))
- drvdata->skip_power_up = true;
+ caps->skip_power_up = true;
/* Detect the support for OS Lock before we actually use it */
etm_detect_os_lock(drvdata, csa);
@@ -1432,71 +1443,71 @@ static void etm4_init_arch_data(void *info)
etmidr0 = etm4x_relaxed_read32(csa, TRCIDR0);
/* INSTP0, bits[2:1] P0 tracing support field */
- drvdata->instrp0 = !!(FIELD_GET(TRCIDR0_INSTP0_MASK, etmidr0) == 0b11);
+ caps->instrp0 = !!(FIELD_GET(TRCIDR0_INSTP0_MASK, etmidr0) == 0b11);
/* TRCBB, bit[5] Branch broadcast tracing support bit */
- drvdata->trcbb = !!(etmidr0 & TRCIDR0_TRCBB);
+ caps->trcbb = !!(etmidr0 & TRCIDR0_TRCBB);
/* TRCCOND, bit[6] Conditional instruction tracing support bit */
- drvdata->trccond = !!(etmidr0 & TRCIDR0_TRCCOND);
+ caps->trccond = !!(etmidr0 & TRCIDR0_TRCCOND);
/* TRCCCI, bit[7] Cycle counting instruction bit */
- drvdata->trccci = !!(etmidr0 & TRCIDR0_TRCCCI);
+ caps->trccci = !!(etmidr0 & TRCIDR0_TRCCCI);
/* RETSTACK, bit[9] Return stack bit */
- drvdata->retstack = !!(etmidr0 & TRCIDR0_RETSTACK);
+ caps->retstack = !!(etmidr0 & TRCIDR0_RETSTACK);
/* NUMEVENT, bits[11:10] Number of events field */
- drvdata->nr_event = FIELD_GET(TRCIDR0_NUMEVENT_MASK, etmidr0);
+ caps->nr_event = FIELD_GET(TRCIDR0_NUMEVENT_MASK, etmidr0);
/* QSUPP, bits[16:15] Q element support field */
- drvdata->q_support = FIELD_GET(TRCIDR0_QSUPP_MASK, etmidr0);
- if (drvdata->q_support)
- drvdata->q_filt = !!(etmidr0 & TRCIDR0_QFILT);
+ caps->q_support = FIELD_GET(TRCIDR0_QSUPP_MASK, etmidr0);
+ if (caps->q_support)
+ caps->q_filt = !!(etmidr0 & TRCIDR0_QFILT);
/* TSSIZE, bits[28:24] Global timestamp size field */
- drvdata->ts_size = FIELD_GET(TRCIDR0_TSSIZE_MASK, etmidr0);
+ caps->ts_size = FIELD_GET(TRCIDR0_TSSIZE_MASK, etmidr0);
/* maximum size of resources */
etmidr2 = etm4x_relaxed_read32(csa, TRCIDR2);
/* CIDSIZE, bits[9:5] Indicates the Context ID size */
- drvdata->ctxid_size = FIELD_GET(TRCIDR2_CIDSIZE_MASK, etmidr2);
+ caps->ctxid_size = FIELD_GET(TRCIDR2_CIDSIZE_MASK, etmidr2);
/* VMIDSIZE, bits[14:10] Indicates the VMID size */
- drvdata->vmid_size = FIELD_GET(TRCIDR2_VMIDSIZE_MASK, etmidr2);
+ caps->vmid_size = FIELD_GET(TRCIDR2_VMIDSIZE_MASK, etmidr2);
/* CCSIZE, bits[28:25] size of the cycle counter in bits minus 12 */
- drvdata->ccsize = FIELD_GET(TRCIDR2_CCSIZE_MASK, etmidr2);
+ caps->ccsize = FIELD_GET(TRCIDR2_CCSIZE_MASK, etmidr2);
etmidr3 = etm4x_relaxed_read32(csa, TRCIDR3);
/* CCITMIN, bits[11:0] minimum threshold value that can be programmed */
- drvdata->ccitmin = FIELD_GET(TRCIDR3_CCITMIN_MASK, etmidr3);
- etm4_fixup_wrong_ccitmin(drvdata);
+ caps->ccitmin = FIELD_GET(TRCIDR3_CCITMIN_MASK, etmidr3);
+ etm4_fixup_wrong_ccitmin(caps);
/* EXLEVEL_S, bits[19:16] Secure state instruction tracing */
- drvdata->s_ex_level = FIELD_GET(TRCIDR3_EXLEVEL_S_MASK, etmidr3);
- drvdata->config.s_ex_level = drvdata->s_ex_level;
+ caps->s_ex_level = FIELD_GET(TRCIDR3_EXLEVEL_S_MASK, etmidr3);
+ drvdata->config.s_ex_level = caps->s_ex_level;
/* EXLEVEL_NS, bits[23:20] Non-secure state instruction tracing */
- drvdata->ns_ex_level = FIELD_GET(TRCIDR3_EXLEVEL_NS_MASK, etmidr3);
+ caps->ns_ex_level = FIELD_GET(TRCIDR3_EXLEVEL_NS_MASK, etmidr3);
/*
* TRCERR, bit[24] whether a trace unit can trace a
* system error exception.
*/
- drvdata->trc_error = !!(etmidr3 & TRCIDR3_TRCERR);
+ caps->trc_error = !!(etmidr3 & TRCIDR3_TRCERR);
/* SYNCPR, bit[25] implementation has a fixed synchronization period? */
- drvdata->syncpr = !!(etmidr3 & TRCIDR3_SYNCPR);
+ caps->syncpr = !!(etmidr3 & TRCIDR3_SYNCPR);
/* STALLCTL, bit[26] is stall control implemented? */
- drvdata->stallctl = !!(etmidr3 & TRCIDR3_STALLCTL);
+ caps->stallctl = !!(etmidr3 & TRCIDR3_STALLCTL);
/* SYSSTALL, bit[27] implementation can support stall control? */
- drvdata->sysstall = !!(etmidr3 & TRCIDR3_SYSSTALL);
+ caps->sysstall = !!(etmidr3 & TRCIDR3_SYSSTALL);
/*
* NUMPROC - the number of PEs available for tracing, 5bits
* = TRCIDR3.bits[13:12]bits[30:28]
* bits[4:3] = TRCIDR3.bits[13:12] (since etm-v4.2, otherwise RES0)
* bits[3:0] = TRCIDR3.bits[30:28]
*/
- drvdata->nr_pe = (FIELD_GET(TRCIDR3_NUMPROC_HI_MASK, etmidr3) << 3) |
- FIELD_GET(TRCIDR3_NUMPROC_LO_MASK, etmidr3);
+ caps->nr_pe = (FIELD_GET(TRCIDR3_NUMPROC_HI_MASK, etmidr3) << 3) |
+ FIELD_GET(TRCIDR3_NUMPROC_LO_MASK, etmidr3);
/* NOOVERFLOW, bit[31] is trace overflow prevention supported */
- drvdata->nooverflow = !!(etmidr3 & TRCIDR3_NOOVERFLOW);
+ caps->nooverflow = !!(etmidr3 & TRCIDR3_NOOVERFLOW);
/* number of resources trace unit supports */
etmidr4 = etm4x_relaxed_read32(csa, TRCIDR4);
/* NUMACPAIRS, bits[0:3] number of addr comparator pairs for tracing */
- drvdata->nr_addr_cmp = FIELD_GET(TRCIDR4_NUMACPAIRS_MASK, etmidr4);
+ caps->nr_addr_cmp = FIELD_GET(TRCIDR4_NUMACPAIRS_MASK, etmidr4);
/* NUMPC, bits[15:12] number of PE comparator inputs for tracing */
- drvdata->nr_pe_cmp = FIELD_GET(TRCIDR4_NUMPC_MASK, etmidr4);
+ caps->nr_pe_cmp = FIELD_GET(TRCIDR4_NUMPC_MASK, etmidr4);
/*
* NUMRSPAIR, bits[19:16]
* The number of resource pairs conveyed by the HW starts at 0, i.e a
@@ -1507,43 +1518,43 @@ static void etm4_init_arch_data(void *info)
* the default TRUE and FALSE resource selectors are omitted.
* Otherwise for values 0x1 and above the number is N + 1 as per v4.2.
*/
- drvdata->nr_resource = FIELD_GET(TRCIDR4_NUMRSPAIR_MASK, etmidr4);
- if ((drvdata->arch < ETM_ARCH_V4_3) || (drvdata->nr_resource > 0))
- drvdata->nr_resource += 1;
+ caps->nr_resource = FIELD_GET(TRCIDR4_NUMRSPAIR_MASK, etmidr4);
+ if ((drvdata->arch < ETM_ARCH_V4_3) || (caps->nr_resource > 0))
+ caps->nr_resource += 1;
/*
* NUMSSCC, bits[23:20] the number of single-shot
* comparator control for tracing. Read any status regs as these
* also contain RO capability data.
*/
- drvdata->nr_ss_cmp = FIELD_GET(TRCIDR4_NUMSSCC_MASK, etmidr4);
- for (i = 0; i < drvdata->nr_ss_cmp; i++) {
+ caps->nr_ss_cmp = FIELD_GET(TRCIDR4_NUMSSCC_MASK, etmidr4);
+ for (i = 0; i < caps->nr_ss_cmp; i++) {
drvdata->config.ss_status[i] =
etm4x_relaxed_read32(csa, TRCSSCSRn(i));
}
/* NUMCIDC, bits[27:24] number of Context ID comparators for tracing */
- drvdata->numcidc = FIELD_GET(TRCIDR4_NUMCIDC_MASK, etmidr4);
+ caps->numcidc = FIELD_GET(TRCIDR4_NUMCIDC_MASK, etmidr4);
/* NUMVMIDC, bits[31:28] number of VMID comparators for tracing */
- drvdata->numvmidc = FIELD_GET(TRCIDR4_NUMVMIDC_MASK, etmidr4);
+ caps->numvmidc = FIELD_GET(TRCIDR4_NUMVMIDC_MASK, etmidr4);
etmidr5 = etm4x_relaxed_read32(csa, TRCIDR5);
/* NUMEXTIN, bits[8:0] number of external inputs implemented */
- drvdata->nr_ext_inp = FIELD_GET(TRCIDR5_NUMEXTIN_MASK, etmidr5);
- drvdata->numextinsel = FIELD_GET(TRCIDR5_NUMEXTINSEL_MASK, etmidr5);
+ caps->nr_ext_inp = FIELD_GET(TRCIDR5_NUMEXTIN_MASK, etmidr5);
+ caps->numextinsel = FIELD_GET(TRCIDR5_NUMEXTINSEL_MASK, etmidr5);
/* TRACEIDSIZE, bits[21:16] indicates the trace ID width */
- drvdata->trcid_size = FIELD_GET(TRCIDR5_TRACEIDSIZE_MASK, etmidr5);
+ caps->trcid_size = FIELD_GET(TRCIDR5_TRACEIDSIZE_MASK, etmidr5);
/* ATBTRIG, bit[22] implementation can support ATB triggers? */
- drvdata->atbtrig = !!(etmidr5 & TRCIDR5_ATBTRIG);
+ caps->atbtrig = !!(etmidr5 & TRCIDR5_ATBTRIG);
/*
* LPOVERRIDE, bit[23] implementation supports
* low-power state override
*/
- drvdata->lpoverride = (etmidr5 & TRCIDR5_LPOVERRIDE) && (!drvdata->skip_power_up);
+ caps->lpoverride = (etmidr5 & TRCIDR5_LPOVERRIDE) && (!caps->skip_power_up);
/* NUMSEQSTATE, bits[27:25] number of sequencer states implemented */
- drvdata->nrseqstate = FIELD_GET(TRCIDR5_NUMSEQSTATE_MASK, etmidr5);
- if (drvdata->nrseqstate)
- drvdata->nr_seq_ctrls = ETM_MAX_SEQ_TRANSITIONS;
+ caps->nrseqstate = FIELD_GET(TRCIDR5_NUMSEQSTATE_MASK, etmidr5);
+ if (caps->nrseqstate)
+ caps->nr_seq_ctrls = ETM_MAX_SEQ_TRANSITIONS;
/* NUMCNTR, bits[30:28] number of counters available for tracing */
- drvdata->nr_cntr = FIELD_GET(TRCIDR5_NUMCNTR_MASK, etmidr5);
+ caps->nr_cntr = FIELD_GET(TRCIDR5_NUMCNTR_MASK, etmidr5);
coresight_clear_self_claim_tag_unlocked(csa);
etm4_cs_lock(drvdata, csa);
@@ -1719,7 +1730,7 @@ static int etm4_get_next_comparator(struct etmv4_drvdata *drvdata, u32 type)
* nr_addr_cmp holds the number of comparator _pair_, so time 2
* for the total number of comparators.
*/
- nr_comparator = drvdata->nr_addr_cmp * 2;
+ nr_comparator = drvdata->caps.nr_addr_cmp * 2;
/* Go through the tally of comparators looking for a free one. */
while (index < nr_comparator) {
@@ -1876,6 +1887,7 @@ static int etm4_cpu_save(struct coresight_device *csdev)
{
int i, ret = 0;
struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_save_state *state;
struct csdev_access *csa;
struct device *etm_dev;
@@ -1908,57 +1920,56 @@ static int etm4_cpu_save(struct coresight_device *csdev)
state = drvdata->save_state;
- if (drvdata->nr_pe)
+ if (caps->nr_pe)
state->trcprocselr = etm4x_read32(csa, TRCPROCSELR);
state->trcconfigr = etm4x_read32(csa, TRCCONFIGR);
state->trcauxctlr = etm4x_read32(csa, TRCAUXCTLR);
state->trceventctl0r = etm4x_read32(csa, TRCEVENTCTL0R);
state->trceventctl1r = etm4x_read32(csa, TRCEVENTCTL1R);
- if (drvdata->stallctl)
+ if (caps->stallctl)
state->trcstallctlr = etm4x_read32(csa, TRCSTALLCTLR);
state->trctsctlr = etm4x_read32(csa, TRCTSCTLR);
state->trcsyncpr = etm4x_read32(csa, TRCSYNCPR);
state->trcccctlr = etm4x_read32(csa, TRCCCCTLR);
state->trcbbctlr = etm4x_read32(csa, TRCBBCTLR);
state->trctraceidr = etm4x_read32(csa, TRCTRACEIDR);
- if (drvdata->q_filt)
+ if (caps->q_filt)
state->trcqctlr = etm4x_read32(csa, TRCQCTLR);
state->trcvictlr = etm4x_read32(csa, TRCVICTLR);
state->trcviiectlr = etm4x_read32(csa, TRCVIIECTLR);
state->trcvissctlr = etm4x_read32(csa, TRCVISSCTLR);
- if (drvdata->nr_pe_cmp)
+ if (caps->nr_pe_cmp)
state->trcvipcssctlr = etm4x_read32(csa, TRCVIPCSSCTLR);
- for (i = 0; i < drvdata->nr_seq_ctrls; i++)
+ for (i = 0; i < caps->nr_seq_ctrls; i++)
state->trcseqevr[i] = etm4x_read32(csa, TRCSEQEVRn(i));
-
- if (drvdata->nrseqstate) {
+ if (caps->nrseqstate) {
state->trcseqrstevr = etm4x_read32(csa, TRCSEQRSTEVR);
state->trcseqstr = etm4x_read32(csa, TRCSEQSTR);
}
- if (drvdata->numextinsel)
+ if (caps->numextinsel)
state->trcextinselr = etm4x_read32(csa, TRCEXTINSELR);
- for (i = 0; i < drvdata->nr_cntr; i++) {
+ for (i = 0; i < caps->nr_cntr; i++) {
state->trccntrldvr[i] = etm4x_read32(csa, TRCCNTRLDVRn(i));
state->trccntctlr[i] = etm4x_read32(csa, TRCCNTCTLRn(i));
state->trccntvr[i] = etm4x_read32(csa, TRCCNTVRn(i));
}
/* Resource selector pair 0 is reserved */
- for (i = 2; i < drvdata->nr_resource * 2; i++)
+ for (i = 2; i < caps->nr_resource * 2; i++)
state->trcrsctlr[i] = etm4x_read32(csa, TRCRSCTLRn(i));
- for (i = 0; i < drvdata->nr_ss_cmp; i++) {
+ for (i = 0; i < caps->nr_ss_cmp; i++) {
state->trcssccr[i] = etm4x_read32(csa, TRCSSCCRn(i));
state->trcsscsr[i] = etm4x_read32(csa, TRCSSCSRn(i));
if (etm4x_sspcicrn_present(drvdata, i))
state->trcsspcicr[i] = etm4x_read32(csa, TRCSSPCICRn(i));
}
- for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) {
+ for (i = 0; i < caps->nr_addr_cmp * 2; i++) {
state->trcacvr[i] = etm4x_read64(csa, TRCACVRn(i));
state->trcacatr[i] = etm4x_read64(csa, TRCACATRn(i));
}
@@ -1970,23 +1981,23 @@ static int etm4_cpu_save(struct coresight_device *csdev)
* unit") of ARM IHI 0064D.
*/
- for (i = 0; i < drvdata->numcidc; i++)
+ for (i = 0; i < caps->numcidc; i++)
state->trccidcvr[i] = etm4x_read64(csa, TRCCIDCVRn(i));
- for (i = 0; i < drvdata->numvmidc; i++)
+ for (i = 0; i < caps->numvmidc; i++)
state->trcvmidcvr[i] = etm4x_read64(csa, TRCVMIDCVRn(i));
state->trccidcctlr0 = etm4x_read32(csa, TRCCIDCCTLR0);
- if (drvdata->numcidc > 4)
+ if (caps->numcidc > 4)
state->trccidcctlr1 = etm4x_read32(csa, TRCCIDCCTLR1);
state->trcvmidcctlr0 = etm4x_read32(csa, TRCVMIDCCTLR0);
- if (drvdata->numvmidc > 4)
+ if (caps->numvmidc > 4)
state->trcvmidcctlr1 = etm4x_read32(csa, TRCVMIDCCTLR1);
state->trcclaimset = etm4x_read32(csa, TRCCLAIMCLR);
- if (!drvdata->skip_power_up)
+ if (!caps->skip_power_up)
state->trcpdcr = etm4x_read32(csa, TRCPDCR);
/* wait for TRCSTATR.IDLE to go up */
@@ -2003,7 +2014,7 @@ static int etm4_cpu_save(struct coresight_device *csdev)
* potentially save power on systems that respect the TRCPDCR_PU
* despite requesting software to save/restore state.
*/
- if (!drvdata->skip_power_up)
+ if (!caps->skip_power_up)
etm4x_relaxed_write32(csa, (state->trcpdcr & ~TRCPDCR_PU),
TRCPDCR);
out:
@@ -2015,83 +2026,84 @@ static void etm4_cpu_restore(struct coresight_device *csdev)
{
int i;
struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_save_state *state = drvdata->save_state;
struct csdev_access *csa = &drvdata->csdev->access;
etm4_cs_unlock(drvdata, csa);
etm4x_relaxed_write32(csa, state->trcclaimset, TRCCLAIMSET);
- if (drvdata->nr_pe)
+ if (caps->nr_pe)
etm4x_relaxed_write32(csa, state->trcprocselr, TRCPROCSELR);
etm4x_relaxed_write32(csa, state->trcconfigr, TRCCONFIGR);
etm4x_relaxed_write32(csa, state->trcauxctlr, TRCAUXCTLR);
etm4x_relaxed_write32(csa, state->trceventctl0r, TRCEVENTCTL0R);
etm4x_relaxed_write32(csa, state->trceventctl1r, TRCEVENTCTL1R);
- if (drvdata->stallctl)
+ if (caps->stallctl)
etm4x_relaxed_write32(csa, state->trcstallctlr, TRCSTALLCTLR);
etm4x_relaxed_write32(csa, state->trctsctlr, TRCTSCTLR);
etm4x_relaxed_write32(csa, state->trcsyncpr, TRCSYNCPR);
etm4x_relaxed_write32(csa, state->trcccctlr, TRCCCCTLR);
etm4x_relaxed_write32(csa, state->trcbbctlr, TRCBBCTLR);
etm4x_relaxed_write32(csa, state->trctraceidr, TRCTRACEIDR);
- if (drvdata->q_filt)
+ if (caps->q_filt)
etm4x_relaxed_write32(csa, state->trcqctlr, TRCQCTLR);
etm4x_relaxed_write32(csa, state->trcvictlr, TRCVICTLR);
etm4x_relaxed_write32(csa, state->trcviiectlr, TRCVIIECTLR);
etm4x_relaxed_write32(csa, state->trcvissctlr, TRCVISSCTLR);
- if (drvdata->nr_pe_cmp)
+ if (caps->nr_pe_cmp)
etm4x_relaxed_write32(csa, state->trcvipcssctlr, TRCVIPCSSCTLR);
- for (i = 0; i < drvdata->nr_seq_ctrls; i++)
+ for (i = 0; i < caps->nr_seq_ctrls; i++)
etm4x_relaxed_write32(csa, state->trcseqevr[i], TRCSEQEVRn(i));
- if (drvdata->nrseqstate) {
+ if (caps->nrseqstate) {
etm4x_relaxed_write32(csa, state->trcseqrstevr, TRCSEQRSTEVR);
etm4x_relaxed_write32(csa, state->trcseqstr, TRCSEQSTR);
}
- if (drvdata->numextinsel)
+ if (caps->numextinsel)
etm4x_relaxed_write32(csa, state->trcextinselr, TRCEXTINSELR);
- for (i = 0; i < drvdata->nr_cntr; i++) {
+ for (i = 0; i < caps->nr_cntr; i++) {
etm4x_relaxed_write32(csa, state->trccntrldvr[i], TRCCNTRLDVRn(i));
etm4x_relaxed_write32(csa, state->trccntctlr[i], TRCCNTCTLRn(i));
etm4x_relaxed_write32(csa, state->trccntvr[i], TRCCNTVRn(i));
}
/* Resource selector pair 0 is reserved */
- for (i = 2; i < drvdata->nr_resource * 2; i++)
+ for (i = 2; i < caps->nr_resource * 2; i++)
etm4x_relaxed_write32(csa, state->trcrsctlr[i], TRCRSCTLRn(i));
- for (i = 0; i < drvdata->nr_ss_cmp; i++) {
+ for (i = 0; i < caps->nr_ss_cmp; i++) {
etm4x_relaxed_write32(csa, state->trcssccr[i], TRCSSCCRn(i));
etm4x_relaxed_write32(csa, state->trcsscsr[i], TRCSSCSRn(i));
if (etm4x_sspcicrn_present(drvdata, i))
etm4x_relaxed_write32(csa, state->trcsspcicr[i], TRCSSPCICRn(i));
}
- for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) {
+ for (i = 0; i < caps->nr_addr_cmp * 2; i++) {
etm4x_relaxed_write64(csa, state->trcacvr[i], TRCACVRn(i));
etm4x_relaxed_write64(csa, state->trcacatr[i], TRCACATRn(i));
}
- for (i = 0; i < drvdata->numcidc; i++)
+ for (i = 0; i < caps->numcidc; i++)
etm4x_relaxed_write64(csa, state->trccidcvr[i], TRCCIDCVRn(i));
- for (i = 0; i < drvdata->numvmidc; i++)
+ for (i = 0; i < caps->numvmidc; i++)
etm4x_relaxed_write64(csa, state->trcvmidcvr[i], TRCVMIDCVRn(i));
etm4x_relaxed_write32(csa, state->trccidcctlr0, TRCCIDCCTLR0);
- if (drvdata->numcidc > 4)
+ if (caps->numcidc > 4)
etm4x_relaxed_write32(csa, state->trccidcctlr1, TRCCIDCCTLR1);
etm4x_relaxed_write32(csa, state->trcvmidcctlr0, TRCVMIDCCTLR0);
- if (drvdata->numvmidc > 4)
+ if (caps->numvmidc > 4)
etm4x_relaxed_write32(csa, state->trcvmidcctlr1, TRCVMIDCCTLR1);
etm4x_relaxed_write32(csa, state->trcclaimset, TRCCLAIMSET);
- if (!drvdata->skip_power_up)
+ if (!caps->skip_power_up)
etm4x_relaxed_write32(csa, state->trcpdcr, TRCPDCR);
/*
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index 9c237507ac30..0f1f50b588f2 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -62,8 +62,9 @@ static ssize_t nr_pe_cmp_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
- val = drvdata->nr_pe_cmp;
+ val = caps->nr_pe_cmp;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
static DEVICE_ATTR_RO(nr_pe_cmp);
@@ -74,8 +75,9 @@ static ssize_t nr_addr_cmp_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
- val = drvdata->nr_addr_cmp;
+ val = caps->nr_addr_cmp;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
static DEVICE_ATTR_RO(nr_addr_cmp);
@@ -86,8 +88,9 @@ static ssize_t nr_cntr_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
- val = drvdata->nr_cntr;
+ val = caps->nr_cntr;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
static DEVICE_ATTR_RO(nr_cntr);
@@ -98,8 +101,9 @@ static ssize_t nr_ext_inp_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
- val = drvdata->nr_ext_inp;
+ val = caps->nr_ext_inp;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
static DEVICE_ATTR_RO(nr_ext_inp);
@@ -110,8 +114,9 @@ static ssize_t numcidc_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
- val = drvdata->numcidc;
+ val = caps->numcidc;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
static DEVICE_ATTR_RO(numcidc);
@@ -122,8 +127,9 @@ static ssize_t numvmidc_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
- val = drvdata->numvmidc;
+ val = caps->numvmidc;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
static DEVICE_ATTR_RO(numvmidc);
@@ -134,8 +140,9 @@ static ssize_t nrseqstate_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
- val = drvdata->nrseqstate;
+ val = caps->nrseqstate;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
static DEVICE_ATTR_RO(nrseqstate);
@@ -146,8 +153,9 @@ static ssize_t nr_resource_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
- val = drvdata->nr_resource;
+ val = caps->nr_resource;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
static DEVICE_ATTR_RO(nr_resource);
@@ -158,8 +166,9 @@ static ssize_t nr_ss_cmp_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
- val = drvdata->nr_ss_cmp;
+ val = caps->nr_ss_cmp;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
static DEVICE_ATTR_RO(nr_ss_cmp);
@@ -171,6 +180,7 @@ static ssize_t reset_store(struct device *dev,
int i;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
@@ -200,7 +210,7 @@ static ssize_t reset_store(struct device *dev,
config->stall_ctrl = 0x0;
/* Reset trace synchronization period to 2^8 = 256 bytes*/
- if (drvdata->syncpr == false)
+ if (!caps->syncpr)
config->syncfreq = 0x8;
/*
@@ -209,7 +219,7 @@ static ssize_t reset_store(struct device *dev,
* each trace run.
*/
config->vinst_ctrl = FIELD_PREP(TRCVICTLR_EVENT_MASK, 0x01);
- if (drvdata->nr_addr_cmp > 0) {
+ if (caps->nr_addr_cmp > 0) {
config->mode |= ETM_MODE_VIEWINST_STARTSTOP;
/* SSSTATUS, bit[9] */
config->vinst_ctrl |= TRCVICTLR_SSSTATUS;
@@ -223,7 +233,7 @@ static ssize_t reset_store(struct device *dev,
config->vipcssctlr = 0x0;
/* Disable seq events */
- for (i = 0; i < drvdata->nr_seq_ctrls; i++)
+ for (i = 0; i < caps->nr_seq_ctrls; i++)
config->seq_ctrl[i] = 0x0;
config->seq_rst = 0x0;
config->seq_state = 0x0;
@@ -232,38 +242,38 @@ static ssize_t reset_store(struct device *dev,
config->ext_inp = 0x0;
config->cntr_idx = 0x0;
- for (i = 0; i < drvdata->nr_cntr; i++) {
+ for (i = 0; i < caps->nr_cntr; i++) {
config->cntrldvr[i] = 0x0;
config->cntr_ctrl[i] = 0x0;
config->cntr_val[i] = 0x0;
}
config->res_idx = 0x0;
- for (i = 2; i < 2 * drvdata->nr_resource; i++)
+ for (i = 2; i < 2 * caps->nr_resource; i++)
config->res_ctrl[i] = 0x0;
config->ss_idx = 0x0;
- for (i = 0; i < drvdata->nr_ss_cmp; i++) {
+ for (i = 0; i < caps->nr_ss_cmp; i++) {
config->ss_ctrl[i] = 0x0;
config->ss_pe_cmp[i] = 0x0;
}
config->addr_idx = 0x0;
- for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) {
+ for (i = 0; i < caps->nr_addr_cmp * 2; i++) {
config->addr_val[i] = 0x0;
config->addr_acc[i] = 0x0;
config->addr_type[i] = ETM_ADDR_TYPE_NONE;
}
config->ctxid_idx = 0x0;
- for (i = 0; i < drvdata->numcidc; i++)
+ for (i = 0; i < caps->numcidc; i++)
config->ctxid_pid[i] = 0x0;
config->ctxid_mask0 = 0x0;
config->ctxid_mask1 = 0x0;
config->vmid_idx = 0x0;
- for (i = 0; i < drvdata->numvmidc; i++)
+ for (i = 0; i < caps->numvmidc; i++)
config->vmid_val[i] = 0x0;
config->vmid_mask0 = 0x0;
config->vmid_mask1 = 0x0;
@@ -297,6 +307,7 @@ static ssize_t mode_store(struct device *dev,
{
unsigned long val, mode;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
@@ -305,7 +316,7 @@ static ssize_t mode_store(struct device *dev,
raw_spin_lock(&drvdata->spinlock);
config->mode = val & ETMv4_MODE_ALL;
- if (drvdata->instrp0 == true) {
+ if (caps->instrp0) {
/* start by clearing instruction P0 field */
config->cfg &= ~TRCCONFIGR_INSTP0_LOAD_STORE;
if (config->mode & ETM_MODE_LOAD)
@@ -323,45 +334,44 @@ static ssize_t mode_store(struct device *dev,
}
/* bit[3], Branch broadcast mode */
- if ((config->mode & ETM_MODE_BB) && (drvdata->trcbb == true))
+ if ((config->mode & ETM_MODE_BB) && (caps->trcbb))
config->cfg |= TRCCONFIGR_BB;
else
config->cfg &= ~TRCCONFIGR_BB;
/* bit[4], Cycle counting instruction trace bit */
if ((config->mode & ETMv4_MODE_CYCACC) &&
- (drvdata->trccci == true))
+ (caps->trccci == true))
config->cfg |= TRCCONFIGR_CCI;
else
config->cfg &= ~TRCCONFIGR_CCI;
/* bit[6], Context ID tracing bit */
- if ((config->mode & ETMv4_MODE_CTXID) && (drvdata->ctxid_size))
+ if ((config->mode & ETMv4_MODE_CTXID) && (caps->ctxid_size))
config->cfg |= TRCCONFIGR_CID;
else
config->cfg &= ~TRCCONFIGR_CID;
- if ((config->mode & ETM_MODE_VMID) && (drvdata->vmid_size))
+ if ((config->mode & ETM_MODE_VMID) && (caps->vmid_size))
config->cfg |= TRCCONFIGR_VMID;
else
config->cfg &= ~TRCCONFIGR_VMID;
/* bits[10:8], Conditional instruction tracing bit */
mode = ETM_MODE_COND(config->mode);
- if (drvdata->trccond == true) {
+ if (caps->trccond) {
config->cfg &= ~TRCCONFIGR_COND_MASK;
config->cfg |= mode << __bf_shf(TRCCONFIGR_COND_MASK);
}
/* bit[11], Global timestamp tracing bit */
- if ((config->mode & ETMv4_MODE_TIMESTAMP) && (drvdata->ts_size))
+ if ((config->mode & ETMv4_MODE_TIMESTAMP) && (caps->ts_size))
config->cfg |= TRCCONFIGR_TS;
else
config->cfg &= ~TRCCONFIGR_TS;
/* bit[12], Return stack enable bit */
- if ((config->mode & ETM_MODE_RETURNSTACK) &&
- (drvdata->retstack == true))
+ if ((config->mode & ETM_MODE_RETURNSTACK) && (caps->retstack))
config->cfg |= TRCCONFIGR_RS;
else
config->cfg &= ~TRCCONFIGR_RS;
@@ -375,31 +385,29 @@ static ssize_t mode_store(struct device *dev,
* Always set the low bit for any requested mode. Valid combos are
* 0b00, 0b01 and 0b11.
*/
- if (mode && drvdata->q_support)
+ if (mode && caps->q_support)
config->cfg |= TRCCONFIGR_QE_W_COUNTS;
/*
* if supported, Q elements with and without instruction
* counts are enabled
*/
- if ((mode & BIT(1)) && (drvdata->q_support & BIT(1)))
+ if ((mode & BIT(1)) && (caps->q_support & BIT(1)))
config->cfg |= TRCCONFIGR_QE_WO_COUNTS;
/* bit[11], AMBA Trace Bus (ATB) trigger enable bit */
- if ((config->mode & ETM_MODE_ATB_TRIGGER) &&
- (drvdata->atbtrig == true))
+ if ((config->mode & ETM_MODE_ATB_TRIGGER) && (caps->atbtrig))
config->eventctrl1 |= TRCEVENTCTL1R_ATB;
else
config->eventctrl1 &= ~TRCEVENTCTL1R_ATB;
/* bit[12], Low-power state behavior override bit */
- if ((config->mode & ETM_MODE_LPOVERRIDE) &&
- (drvdata->lpoverride == true))
+ if ((config->mode & ETM_MODE_LPOVERRIDE) && (caps->lpoverride))
config->eventctrl1 |= TRCEVENTCTL1R_LPOVERRIDE;
else
config->eventctrl1 &= ~TRCEVENTCTL1R_LPOVERRIDE;
/* bit[8], Instruction stall bit */
- if ((config->mode & ETM_MODE_ISTALL_EN) && (drvdata->stallctl == true))
+ if ((config->mode & ETM_MODE_ISTALL_EN) && (caps->stallctl))
config->stall_ctrl |= TRCSTALLCTLR_ISTALL;
else
config->stall_ctrl &= ~TRCSTALLCTLR_ISTALL;
@@ -411,8 +419,7 @@ static ssize_t mode_store(struct device *dev,
config->stall_ctrl &= ~TRCSTALLCTLR_INSTPRIORITY;
/* bit[13], Trace overflow prevention bit */
- if ((config->mode & ETM_MODE_NOOVERFLOW) &&
- (drvdata->nooverflow == true))
+ if ((config->mode & ETM_MODE_NOOVERFLOW) && (caps->nooverflow))
config->stall_ctrl |= TRCSTALLCTLR_NOOVERFLOW;
else
config->stall_ctrl &= ~TRCSTALLCTLR_NOOVERFLOW;
@@ -430,8 +437,7 @@ static ssize_t mode_store(struct device *dev,
config->vinst_ctrl &= ~TRCVICTLR_TRCRESET;
/* bit[11], Whether a trace unit must trace a system error exception */
- if ((config->mode & ETM_MODE_TRACE_ERR) &&
- (drvdata->trc_error == true))
+ if ((config->mode & ETM_MODE_TRACE_ERR) && (caps->trc_error))
config->vinst_ctrl |= TRCVICTLR_TRCERR;
else
config->vinst_ctrl &= ~TRCVICTLR_TRCERR;
@@ -463,13 +469,14 @@ static ssize_t pe_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- if (val > drvdata->nr_pe) {
+ if (val > caps->nr_pe) {
raw_spin_unlock(&drvdata->spinlock);
return -EINVAL;
}
@@ -498,13 +505,14 @@ static ssize_t event_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- switch (drvdata->nr_event) {
+ switch (caps->nr_event) {
case 0x0:
/* EVENT0, bits[7:0] */
config->eventctrl0 = val & 0xFF;
@@ -547,6 +555,7 @@ static ssize_t event_instren_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
@@ -555,7 +564,7 @@ static ssize_t event_instren_store(struct device *dev,
raw_spin_lock(&drvdata->spinlock);
/* start by clearing all instruction event enable bits */
config->eventctrl1 &= ~TRCEVENTCTL1R_INSTEN_MASK;
- switch (drvdata->nr_event) {
+ switch (caps->nr_event) {
case 0x0:
/* generate Event element for event 1 */
config->eventctrl1 |= val & TRCEVENTCTL1R_INSTEN_1;
@@ -603,11 +612,12 @@ static ssize_t event_ts_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
- if (!drvdata->ts_size)
+ if (!caps->ts_size)
return -EINVAL;
config->ts_ctrl = val & ETMv4_EVENT_MASK;
@@ -633,11 +643,12 @@ static ssize_t syncfreq_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
- if (drvdata->syncpr == true)
+ if (caps->syncpr)
return -EINVAL;
config->syncfreq = val & ETMv4_SYNC_MASK;
@@ -663,6 +674,7 @@ static ssize_t cyc_threshold_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
@@ -670,7 +682,7 @@ static ssize_t cyc_threshold_store(struct device *dev,
/* mask off max threshold before checking min value */
val &= ETM_CYC_THRESHOLD_MASK;
- if (val < drvdata->ccitmin)
+ if (val < caps->ccitmin)
return -EINVAL;
config->ccctlr = val;
@@ -696,13 +708,14 @@ static ssize_t bb_ctrl_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
- if (drvdata->trcbb == false)
+ if (!caps->trcbb)
return -EINVAL;
- if (!drvdata->nr_addr_cmp)
+ if (!caps->nr_addr_cmp)
return -EINVAL;
/*
@@ -768,6 +781,7 @@ static ssize_t s_exlevel_vinst_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
@@ -777,7 +791,7 @@ static ssize_t s_exlevel_vinst_store(struct device *dev,
/* clear all EXLEVEL_S bits */
config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_S_MASK;
/* enable instruction tracing for corresponding exception level */
- val &= drvdata->s_ex_level;
+ val &= caps->s_ex_level;
config->vinst_ctrl |= val << __bf_shf(TRCVICTLR_EXLEVEL_S_MASK);
raw_spin_unlock(&drvdata->spinlock);
return size;
@@ -803,6 +817,7 @@ static ssize_t ns_exlevel_vinst_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
@@ -812,7 +827,7 @@ static ssize_t ns_exlevel_vinst_store(struct device *dev,
/* clear EXLEVEL_NS bits */
config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_NS_MASK;
/* enable instruction tracing for corresponding exception level */
- val &= drvdata->ns_ex_level;
+ val &= caps->ns_ex_level;
config->vinst_ctrl |= val << __bf_shf(TRCVICTLR_EXLEVEL_NS_MASK);
raw_spin_unlock(&drvdata->spinlock);
return size;
@@ -837,11 +852,12 @@ static ssize_t addr_idx_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
- if (val >= drvdata->nr_addr_cmp * 2)
+ if (val >= caps->nr_addr_cmp * 2)
return -EINVAL;
/*
@@ -1060,6 +1076,7 @@ static ssize_t addr_start_store(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
@@ -1067,7 +1084,7 @@ static ssize_t addr_start_store(struct device *dev,
raw_spin_lock(&drvdata->spinlock);
idx = config->addr_idx;
- if (!drvdata->nr_addr_cmp) {
+ if (!caps->nr_addr_cmp) {
raw_spin_unlock(&drvdata->spinlock);
return -EINVAL;
}
@@ -1115,6 +1132,7 @@ static ssize_t addr_stop_store(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
@@ -1122,7 +1140,7 @@ static ssize_t addr_stop_store(struct device *dev,
raw_spin_lock(&drvdata->spinlock);
idx = config->addr_idx;
- if (!drvdata->nr_addr_cmp) {
+ if (!caps->nr_addr_cmp) {
raw_spin_unlock(&drvdata->spinlock);
return -EINVAL;
}
@@ -1167,6 +1185,7 @@ static ssize_t addr_ctxtype_store(struct device *dev,
u8 idx;
char str[10] = "";
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (strlen(buf) >= 10)
@@ -1181,13 +1200,13 @@ static ssize_t addr_ctxtype_store(struct device *dev,
config->addr_acc[idx] &= ~TRCACATRn_CONTEXTTYPE_MASK;
else if (!strcmp(str, "ctxid")) {
/* 0b01 The trace unit performs a Context ID */
- if (drvdata->numcidc) {
+ if (caps->numcidc) {
config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_CTXID;
config->addr_acc[idx] &= ~TRCACATRn_CONTEXTTYPE_VMID;
}
} else if (!strcmp(str, "vmid")) {
/* 0b10 The trace unit performs a VMID */
- if (drvdata->numvmidc) {
+ if (caps->numvmidc) {
config->addr_acc[idx] &= ~TRCACATRn_CONTEXTTYPE_CTXID;
config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_VMID;
}
@@ -1196,9 +1215,9 @@ static ssize_t addr_ctxtype_store(struct device *dev,
* 0b11 The trace unit performs a Context ID
* comparison and a VMID
*/
- if (drvdata->numcidc)
+ if (caps->numcidc)
config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_CTXID;
- if (drvdata->numvmidc)
+ if (caps->numvmidc)
config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_VMID;
}
raw_spin_unlock(&drvdata->spinlock);
@@ -1230,14 +1249,15 @@ static ssize_t addr_context_store(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
- if ((drvdata->numcidc <= 1) && (drvdata->numvmidc <= 1))
+ if ((caps->numcidc <= 1) && (caps->numvmidc <= 1))
return -EINVAL;
- if (val >= (drvdata->numcidc >= drvdata->numvmidc ?
- drvdata->numcidc : drvdata->numvmidc))
+ if (val >= (caps->numcidc >= caps->numvmidc ?
+ caps->numcidc : caps->numvmidc))
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
@@ -1348,9 +1368,10 @@ static ssize_t vinst_pe_cmp_start_stop_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
- if (!drvdata->nr_pe_cmp)
+ if (!caps->nr_pe_cmp)
return -EINVAL;
val = config->vipcssctlr;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
@@ -1361,11 +1382,12 @@ static ssize_t vinst_pe_cmp_start_stop_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
- if (!drvdata->nr_pe_cmp)
+ if (!caps->nr_pe_cmp)
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
@@ -1393,13 +1415,14 @@ static ssize_t seq_idx_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
- if (!drvdata->nr_seq_ctrls)
+ if (!caps->nr_seq_ctrls)
return -ENOTSUPP;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
- if (val >= drvdata->nr_seq_ctrls)
+ if (val >= caps->nr_seq_ctrls)
return -EINVAL;
/*
@@ -1431,11 +1454,12 @@ static ssize_t seq_state_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
- if (val >= drvdata->nrseqstate)
+ if (val >= caps->nrseqstate)
return -EINVAL;
if (IS_ERR_OR_NULL(drvdata) ||
coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS)
@@ -1501,11 +1525,12 @@ static ssize_t seq_reset_event_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
- if (!(drvdata->nrseqstate))
+ if (!(caps->nrseqstate))
return -EINVAL;
config->seq_rst = val & ETMv4_EVENT_MASK;
@@ -1531,11 +1556,12 @@ static ssize_t cntr_idx_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
- if (val >= drvdata->nr_cntr)
+ if (val >= caps->nr_cntr)
return -EINVAL;
/*
@@ -1682,6 +1708,7 @@ static ssize_t res_idx_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
@@ -1690,7 +1717,7 @@ static ssize_t res_idx_store(struct device *dev,
* Resource selector pair 0 is always implemented and reserved,
* namely an idx with 0 and 1 is illegal.
*/
- if ((val < 2) || (val >= 2 * drvdata->nr_resource))
+ if ((val < 2) || (val >= 2 * caps->nr_resource))
return -EINVAL;
/*
@@ -1764,11 +1791,12 @@ static ssize_t sshot_idx_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
- if (val >= drvdata->nr_ss_cmp)
+ if (val >= caps->nr_ss_cmp)
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
@@ -1882,11 +1910,12 @@ static ssize_t ctxid_idx_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
- if (val >= drvdata->numcidc)
+ if (val >= caps->numcidc)
return -EINVAL;
/*
@@ -1930,6 +1959,7 @@ static ssize_t ctxid_pid_store(struct device *dev,
u8 idx;
unsigned long pid;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
/*
@@ -1949,7 +1979,7 @@ static ssize_t ctxid_pid_store(struct device *dev,
* ctxid comparator is implemented and ctxid is greater than 0 bits
* in length
*/
- if (!drvdata->ctxid_size || !drvdata->numcidc)
+ if (!caps->ctxid_size || !caps->numcidc)
return -EINVAL;
if (kstrtoul(buf, 16, &pid))
return -EINVAL;
@@ -1991,6 +2021,7 @@ static ssize_t ctxid_masks_store(struct device *dev,
u8 i, j, maskbyte;
unsigned long val1, val2, mask;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
int nr_inputs;
@@ -2006,11 +2037,11 @@ static ssize_t ctxid_masks_store(struct device *dev,
* ctxid comparator is implemented and ctxid is greater than 0 bits
* in length
*/
- if (!drvdata->ctxid_size || !drvdata->numcidc)
+ if (!caps->ctxid_size || !caps->numcidc)
return -EINVAL;
/* one mask if <= 4 comparators, two for up to 8 */
nr_inputs = sscanf(buf, "%lx %lx", &val1, &val2);
- if ((drvdata->numcidc > 4) && (nr_inputs != 2))
+ if ((caps->numcidc > 4) && (nr_inputs != 2))
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
@@ -2018,7 +2049,7 @@ static ssize_t ctxid_masks_store(struct device *dev,
* each byte[0..3] controls mask value applied to ctxid
* comparator[0..3]
*/
- switch (drvdata->numcidc) {
+ switch (caps->numcidc) {
case 0x1:
/* COMP0, bits[7:0] */
config->ctxid_mask0 = val1 & 0xFF;
@@ -2065,7 +2096,7 @@ static ssize_t ctxid_masks_store(struct device *dev,
* of ctxid comparator0 value (corresponding to byte 0) register.
*/
mask = config->ctxid_mask0;
- for (i = 0; i < drvdata->numcidc; i++) {
+ for (i = 0; i < caps->numcidc; i++) {
/* mask value of corresponding ctxid comparator */
maskbyte = mask & ETMv4_EVENT_MASK;
/*
@@ -2108,11 +2139,12 @@ static ssize_t vmid_idx_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
- if (val >= drvdata->numvmidc)
+ if (val >= caps->numvmidc)
return -EINVAL;
/*
@@ -2153,6 +2185,7 @@ static ssize_t vmid_val_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
/*
@@ -2166,7 +2199,7 @@ static ssize_t vmid_val_store(struct device *dev,
* only implemented when vmid tracing is enabled, i.e. at least one
* vmid comparator is implemented and at least 8 bit vmid size
*/
- if (!drvdata->vmid_size || !drvdata->numvmidc)
+ if (!caps->vmid_size || !caps->numvmidc)
return -EINVAL;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
@@ -2206,6 +2239,7 @@ static ssize_t vmid_masks_store(struct device *dev,
u8 i, j, maskbyte;
unsigned long val1, val2, mask;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->config;
int nr_inputs;
@@ -2220,11 +2254,11 @@ static ssize_t vmid_masks_store(struct device *dev,
* only implemented when vmid tracing is enabled, i.e. at least one
* vmid comparator is implemented and at least 8 bit vmid size
*/
- if (!drvdata->vmid_size || !drvdata->numvmidc)
+ if (!caps->vmid_size || !caps->numvmidc)
return -EINVAL;
/* one mask if <= 4 comparators, two for up to 8 */
nr_inputs = sscanf(buf, "%lx %lx", &val1, &val2);
- if ((drvdata->numvmidc > 4) && (nr_inputs != 2))
+ if ((caps->numvmidc > 4) && (nr_inputs != 2))
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
@@ -2233,7 +2267,7 @@ static ssize_t vmid_masks_store(struct device *dev,
* each byte[0..3] controls mask value applied to vmid
* comparator[0..3]
*/
- switch (drvdata->numvmidc) {
+ switch (caps->numvmidc) {
case 0x1:
/* COMP0, bits[7:0] */
config->vmid_mask0 = val1 & 0xFF;
@@ -2281,7 +2315,7 @@ static ssize_t vmid_masks_store(struct device *dev,
* of vmid comparator0 value (corresponding to byte 0) register.
*/
mask = config->vmid_mask0;
- for (i = 0; i < drvdata->numvmidc; i++) {
+ for (i = 0; i < caps->numvmidc; i++) {
/* mask value of corresponding vmid comparator */
maskbyte = mask & ETMv4_EVENT_MASK;
/*
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
index 52f66e26ceaa..b4579261868d 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -813,6 +813,97 @@ enum etm_impdef_type {
ETM4_IMPDEF_FEATURE_MAX,
};
+/**
+ * struct etmv4_caps - specifics ETM capabilities
+ * @nr_pe: The number of processing entity available for tracing.
+ * @nr_pe_cmp: The number of processing entity comparator inputs that are
+ * available for tracing.
+ * @nr_addr_cmp:Number of pairs of address comparators available
+ * as found in ETMIDR4 0-3.
+ * @nr_cntr: Number of counters as found in ETMIDR5 bit 28-30.
+ * @nr_ext_inp: Number of external input.
+ * @numcidc: Number of contextID comparators.
+ * @numextinsel: Number of external input selector resources.
+ * @numvmidc: Number of VMID comparators.
+ * @nrseqstate: The number of sequencer states that are implemented.
+ * @nr_seq_ctrls: The number of sequence state transition control registers.
+ * @nr_event: Indicates how many events the trace unit support.
+ * @nr_resource:The number of resource selection pairs available for tracing.
+ * @nr_ss_cmp: Number of single-shot comparator controls that are available.
+ * @trcid_size: Indicates the trace ID width.
+ * @ts_size: Global timestamp size field.
+ * @ctxid_size: Size of the context ID field to consider.
+ * @vmid_size: Size of the VM ID comparator to consider.
+ * @ccsize: Indicates the size of the cycle counter in bits.
+ * @ccitmin: minimum value that can be programmed in
+ * @s_ex_level: In secure state, indicates whether instruction tracing is
+ * supported for the corresponding Exception level.
+ * @ns_ex_level:In non-secure state, indicates whether instruction tracing is
+ * supported for the corresponding Exception level.
+ * @q_support: Q element support characteristics.
+ * @os_lock_model: OSLock model.
+ * @instrp0: Tracing of load and store instructions
+ * as P0 elements is supported.
+ * @q_filt: Q element filtering support, if Q elements are supported.
+ * @trcbb: Indicates if the trace unit supports branch broadcast tracing.
+ * @trccond: If the trace unit supports conditional
+ * instruction tracing.
+ * @retstack: Indicates if the implementation supports a return stack.
+ * @trccci: Indicates if the trace unit supports cycle counting
+ * for instruction.
+ * @trc_error: Whether a trace unit can trace a system
+ * error exception.
+ * @syncpr: Indicates if an implementation has a fixed
+ * synchronization period.
+ * @stallctl: If functionality that prevents trace unit buffer overflows
+ * is available.
+ * @sysstall: Does the system support stall control of the PE?
+ * @nooverflow: Indicate if overflow prevention is supported.
+ * @atbtrig: If the implementation can support ATB triggers
+ * @lpoverride: If the implementation can support low-power state over.
+ * @skip_power_up: Indicates if an implementation can skip powering up
+ * the trace unit.
+ */
+struct etmv4_caps {
+ u8 nr_pe;
+ u8 nr_pe_cmp;
+ u8 nr_addr_cmp;
+ u8 nr_cntr;
+ u8 nr_ext_inp;
+ u8 numcidc;
+ u8 numextinsel;
+ u8 numvmidc;
+ u8 nrseqstate;
+ u8 nr_seq_ctrls;
+ u8 nr_event;
+ u8 nr_resource;
+ u8 nr_ss_cmp;
+ u8 trcid_size;
+ u8 ts_size;
+ u8 ctxid_size;
+ u8 vmid_size;
+ u8 ccsize;
+ u16 ccitmin;
+ u8 s_ex_level;
+ u8 ns_ex_level;
+ u8 q_support;
+ u8 os_lock_model;
+ bool instrp0 : 1;
+ bool q_filt : 1;
+ bool trcbb : 1;
+ bool trccond : 1;
+ bool retstack : 1;
+ bool trccci : 1;
+ bool trc_error : 1;
+ bool syncpr : 1;
+ bool stallctl : 1;
+ bool sysstall : 1;
+ bool nooverflow : 1;
+ bool atbtrig : 1;
+ bool lpoverride : 1;
+ bool skip_power_up : 1;
+};
+
/**
* struct etmv4_config - configuration information related to an ETMv4
* @mode: Controls various modes supported by this ETM.
@@ -820,8 +911,8 @@ enum etm_impdef_type {
* @cfg: Controls the tracing options.
* @eventctrl0: Controls the tracing of arbitrary events.
* @eventctrl1: Controls the behavior of the events that @event_ctrl0 selects.
- * @stallctl: If functionality that prevents trace unit buffer overflows
- * is available.
+ * @stall_ctrl: Enables trace unit functionality that prevents trace
+ * unit buffer overflows.
* @ts_ctrl: Controls the insertion of global timestamps in the
* trace streams.
* @syncfreq: Controls how often trace synchronization requests occur.
@@ -967,54 +1058,11 @@ struct etmv4_save_state {
* @mode: This tracer's mode, i.e sysFS, Perf or disabled.
* @cpu: The cpu this component is affined to.
* @arch: ETM architecture version.
- * @nr_pe: The number of processing entity available for tracing.
- * @nr_pe_cmp: The number of processing entity comparator inputs that are
- * available for tracing.
- * @nr_addr_cmp:Number of pairs of address comparators available
- * as found in ETMIDR4 0-3.
- * @nr_cntr: Number of counters as found in ETMIDR5 bit 28-30.
- * @nr_ext_inp: Number of external input.
- * @numcidc: Number of contextID comparators.
- * @numvmidc: Number of VMID comparators.
- * @nrseqstate: The number of sequencer states that are implemented.
- * @nr_seq_ctrls: The number of sequence state transition control registers.
- * @nr_event: Indicates how many events the trace unit support.
- * @nr_resource:The number of resource selection pairs available for tracing.
- * @nr_ss_cmp: Number of single-shot comparator controls that are available.
+ * @caps: ETM capabilities.
* @trcid: value of the current ID for this component.
- * @trcid_size: Indicates the trace ID width.
- * @ts_size: Global timestamp size field.
- * @ctxid_size: Size of the context ID field to consider.
- * @vmid_size: Size of the VM ID comparator to consider.
- * @ccsize: Indicates the size of the cycle counter in bits.
- * @ccitmin: minimum value that can be programmed in
- * @s_ex_level: In secure state, indicates whether instruction tracing is
- * supported for the corresponding Exception level.
- * @ns_ex_level:In non-secure state, indicates whether instruction tracing is
- * supported for the corresponding Exception level.
* @sticky_enable: true if ETM base configuration has been done.
* @boot_enable:True if we should start tracing at boot time.
* @os_unlock: True if access to management registers is allowed.
- * @instrp0: Tracing of load and store instructions
- * as P0 elements is supported.
- * @q_filt: Q element filtering support, if Q elements are supported.
- * @trcbb: Indicates if the trace unit supports branch broadcast tracing.
- * @trccond: If the trace unit supports conditional
- * instruction tracing.
- * @retstack: Indicates if the implementation supports a return stack.
- * @trccci: Indicates if the trace unit supports cycle counting
- * for instruction.
- * @q_support: Q element support characteristics.
- * @trc_error: Whether a trace unit can trace a system
- * error exception.
- * @syncpr: Indicates if an implementation has a fixed
- * synchronization period.
- * @stall_ctrl: Enables trace unit functionality that prevents trace
- * unit buffer overflows.
- * @sysstall: Does the system support stall control of the PE?
- * @nooverflow: Indicate if overflow prevention is supported.
- * @atbtrig: If the implementation can support ATB triggers
- * @lpoverride: If the implementation can support low-power state over.
* @trfcr: If the CPU supports FEAT_TRF, value of the TRFCR_ELx that
* allows tracing at all ELs. We don't want to compute this
* at runtime, due to the additional setting of TRFCR_CX when
@@ -1022,8 +1070,6 @@ struct etmv4_save_state {
* @curr_config: structure holding current applied configuration.
* @config: structure holding sysfs mode configuration.
* @save_state: State to be preserved across power loss
- * @skip_power_up: Indicates if an implementation can skip powering up
- * the trace unit.
* @paused: Indicates if the trace unit is paused.
* @arch_features: Bitmap of arch features of etmv4 devices.
*/
@@ -1035,47 +1081,11 @@ struct etmv4_drvdata {
raw_spinlock_t spinlock;
int cpu;
u8 arch;
- u8 nr_pe;
- u8 nr_pe_cmp;
- u8 nr_addr_cmp;
- u8 nr_cntr;
- u8 nr_ext_inp;
- u8 numcidc;
- u8 numextinsel;
- u8 numvmidc;
- u8 nrseqstate;
- u8 nr_seq_ctrls;
- u8 nr_event;
- u8 nr_resource;
- u8 nr_ss_cmp;
+ struct etmv4_caps caps;
u8 trcid;
- u8 trcid_size;
- u8 ts_size;
- u8 ctxid_size;
- u8 vmid_size;
- u8 ccsize;
- u16 ccitmin;
- u8 s_ex_level;
- u8 ns_ex_level;
- u8 q_support;
- u8 os_lock_model;
bool sticky_enable : 1;
bool boot_enable : 1;
bool os_unlock : 1;
- bool instrp0 : 1;
- bool q_filt : 1;
- bool trcbb : 1;
- bool trccond : 1;
- bool retstack : 1;
- bool trccci : 1;
- bool trc_error : 1;
- bool syncpr : 1;
- bool stallctl : 1;
- bool sysstall : 1;
- bool nooverflow : 1;
- bool atbtrig : 1;
- bool lpoverride : 1;
- bool skip_power_up : 1;
bool paused : 1;
u64 trfcr;
struct etmv4_config curr_config;
--
2.43.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v12 08/14] coresight: etm4x: exclude ss_status from drvdata->config
2026-09-24 17:33 [PATCH v12 00/14] fix several inconsistencies with sysfs configuration in etmX Yeoreum Yun
` (6 preceding siblings ...)
2026-09-24 17:33 ` [PATCH v12 07/14] coresight: etm4x: introduce struct etm4_caps Yeoreum Yun
@ 2026-09-24 17:33 ` Yeoreum Yun
2026-09-24 18:21 ` sashiko-bot
2026-09-24 17:33 ` [PATCH v12 09/14] coresight: etm4x: remove s_ex_level from config Yeoreum Yun
` (5 subsequent siblings)
13 siblings, 1 reply; 19+ messages in thread
From: Yeoreum Yun @ 2026-09-24 17:33 UTC (permalink / raw)
To: Mike Leach, James Clark, Leo Yan, Greg Kroah-Hartman,
Mathieu Poirier, coresight, linux-arm-kernel, linux-kernel,
linux-rt-devel
Cc: Suzuki K Poulose, Alexander Shishkin, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, Yeoreum Yun
The purpose of TRCSSCSRn register is to show status of
the corresponding Single-shot Comparator Control and input supports.
That means writable field's purpose for reset or restore from idle status
not for configuration.
Therefore, exclude ss_status from drvdata->config and move it to drvdata.
Before this patch, clearing the PENDING and STATUS bits when enabling
a perf session could trigger multiple single-shot events within
the same session. This issue will be addressed in a future patch;
this patch intentionally preserves the existing behavior.
Reviewed-by: Leo Yan <leo.yan@arm.com>
Tested-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
drivers/hwtracing/coresight/coresight-etm4x-cfg.c | 1 -
drivers/hwtracing/coresight/coresight-etm4x-core.c | 18 +++++++-----------
drivers/hwtracing/coresight/coresight-etm4x-sysfs.c | 10 +++++-----
drivers/hwtracing/coresight/coresight-etm4x.h | 8 +++++++-
4 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
index a9f6ed47a2f5..52cb036bb04b 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
@@ -86,7 +86,6 @@ static int etm4_cfg_map_reg_offset(struct etmv4_drvdata *drvdata,
off_mask = (offset & GENMASK(11, 5));
do {
CHECKREGIDX(TRCSSCCRn(0), ss_ctrl, idx, off_mask);
- CHECKREGIDX(TRCSSCSRn(0), ss_status, idx, off_mask);
CHECKREGIDX(TRCSSPCICRn(0), ss_pe_cmp, idx, off_mask);
} while (0);
} else if ((offset >= TRCCIDCVRn(0)) && (offset <= TRCVMIDCVRn(7))) {
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 3900b96e9c7c..4a8c1070bbcb 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -95,7 +95,7 @@ static bool etm4x_sspcicrn_present(struct etmv4_drvdata *drvdata, int n)
const struct etmv4_caps *caps = &drvdata->caps;
return (n < caps->nr_ss_cmp) && caps->nr_pe_cmp &&
- (drvdata->config.ss_status[n] & TRCSSCSRn_PC);
+ (drvdata->ss_status[n] & TRCSSCSRn_PC);
}
u64 etm4x_sysreg_read(u32 offset, bool _relaxed, bool _64bit)
@@ -572,11 +572,11 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
etm4x_relaxed_write32(csa, config->res_ctrl[i], TRCRSCTLRn(i));
for (i = 0; i < caps->nr_ss_cmp; i++) {
- /* always clear status bit on restart if using single-shot */
+ /* always clear status and pending bits on restart if using single-shot */
if (config->ss_ctrl[i] || config->ss_pe_cmp[i])
- config->ss_status[i] &= ~TRCSSCSRn_STATUS;
+ drvdata->ss_status[i] &= ~(TRCSSCSRn_STATUS | TRCSSCSRn_PENDING);
etm4x_relaxed_write32(csa, config->ss_ctrl[i], TRCSSCCRn(i));
- etm4x_relaxed_write32(csa, config->ss_status[i], TRCSSCSRn(i));
+ etm4x_relaxed_write32(csa, drvdata->ss_status[i], TRCSSCSRn(i));
if (etm4x_sspcicrn_present(drvdata, i))
etm4x_relaxed_write32(csa, config->ss_pe_cmp[i], TRCSSPCICRn(i));
}
@@ -1078,7 +1078,7 @@ static void etm4_disable_hw(struct etmv4_drvdata *drvdata)
/* read the status of the single shot comparators */
for (i = 0; i < caps->nr_ss_cmp; i++) {
- config->ss_status[i] =
+ drvdata->ss_status[i] =
etm4x_relaxed_read32(csa, TRCSSCSRn(i));
}
@@ -1163,12 +1163,9 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
drvdata, 1);
/*
- * Userspace may read ss_status and cntr_val through sysfs after
+ * Userspace may read cntr_val through sysfs after
* the sysfs-session has been disabled.
*/
- for (i = 0; i < caps->nr_ss_cmp; i++)
- config->ss_status[i] = curr_config->ss_status[i];
-
for (i = 0; i < caps->nr_cntr; i++)
config->cntr_val[i] = curr_config->cntr_val[i];
@@ -1528,8 +1525,7 @@ static void etm4_init_arch_data(void *info)
*/
caps->nr_ss_cmp = FIELD_GET(TRCIDR4_NUMSSCC_MASK, etmidr4);
for (i = 0; i < caps->nr_ss_cmp; i++) {
- drvdata->config.ss_status[i] =
- etm4x_relaxed_read32(csa, TRCSSCSRn(i));
+ drvdata->ss_status[i] = etm4x_relaxed_read32(csa, TRCSSCSRn(i));
}
/* NUMCIDC, bits[27:24] number of Context ID comparators for tracing */
caps->numcidc = FIELD_GET(TRCIDR4_NUMCIDC_MASK, etmidr4);
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index 0f1f50b588f2..a66f34c942ba 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -1835,8 +1835,8 @@ static ssize_t sshot_ctrl_store(struct device *dev,
raw_spin_lock(&drvdata->spinlock);
idx = config->ss_idx;
config->ss_ctrl[idx] = FIELD_PREP(TRCSSCCRn_SAC_ARC_RST_MASK, val);
- /* must clear bit 31 in related status register on programming */
- config->ss_status[idx] &= ~TRCSSCSRn_STATUS;
+ /* must clear bit 31 and 30 in related status register on programming */
+ drvdata->ss_status[idx] &= ~(TRCSSCSRn_STATUS | TRCSSCSRn_PENDING);
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -1850,7 +1850,7 @@ static ssize_t sshot_status_show(struct device *dev,
struct etmv4_config *config = &drvdata->config;
raw_spin_lock(&drvdata->spinlock);
- val = config->ss_status[config->ss_idx];
+ val = drvdata->ss_status[config->ss_idx];
raw_spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1885,8 +1885,8 @@ static ssize_t sshot_pe_ctrl_store(struct device *dev,
raw_spin_lock(&drvdata->spinlock);
idx = config->ss_idx;
config->ss_pe_cmp[idx] = FIELD_PREP(TRCSSPCICRn_PC_MASK, val);
- /* must clear bit 31 in related status register on programming */
- config->ss_status[idx] &= ~TRCSSCSRn_STATUS;
+ /* must clear bit 31 and 30 in related status register on programming */
+ drvdata->ss_status[idx] &= ~(TRCSSCSRn_STATUS | TRCSSCSRn_PENDING);
raw_spin_unlock(&drvdata->spinlock);
return size;
}
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
index b4579261868d..67071f7cbdbc 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -213,6 +213,11 @@
#define TRCACATRn_EXLEVEL_MASK GENMASK(14, 8)
#define TRCSSCSRn_STATUS BIT(31)
+/*
+ * TRCSSCSR.PENDING is only implemented by ETE and is therefore not
+ * described in DEN0117. See Arm ARM (DDI0487) M.c, section D24.4.59.
+ */
+#define TRCSSCSRn_PENDING BIT(30)
#define TRCSSCCRn_SAC_ARC_RST_MASK GENMASK(24, 0)
#define TRCSSPCICRn_PC_MASK GENMASK(7, 0)
@@ -980,7 +985,6 @@ struct etmv4_config {
u32 res_ctrl[ETM_MAX_RES_SEL]; /* TRCRSCTLRn */
u8 ss_idx;
u32 ss_ctrl[ETM_MAX_SS_CMP];
- u32 ss_status[ETM_MAX_SS_CMP];
u32 ss_pe_cmp[ETM_MAX_SS_CMP];
u8 addr_idx;
u64 addr_val[ETM_MAX_SINGLE_ADDR_CMP];
@@ -1071,6 +1075,7 @@ struct etmv4_save_state {
* @config: structure holding sysfs mode configuration.
* @save_state: State to be preserved across power loss
* @paused: Indicates if the trace unit is paused.
+ * @ss_status: The status of the corresponding single-shot comparator.
* @arch_features: Bitmap of arch features of etmv4 devices.
*/
struct etmv4_drvdata {
@@ -1091,6 +1096,7 @@ struct etmv4_drvdata {
struct etmv4_config curr_config;
struct etmv4_config config;
struct etmv4_save_state *save_state;
+ u32 ss_status[ETM_MAX_SS_CMP];
DECLARE_BITMAP(arch_features, ETM4_IMPDEF_FEATURE_MAX);
};
--
2.43.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v12 09/14] coresight: etm4x: remove s_ex_level from config
2026-09-24 17:33 [PATCH v12 00/14] fix several inconsistencies with sysfs configuration in etmX Yeoreum Yun
` (7 preceding siblings ...)
2026-09-24 17:33 ` [PATCH v12 08/14] coresight: etm4x: exclude ss_status from drvdata->config Yeoreum Yun
@ 2026-09-24 17:33 ` Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 10/14] coresight: etm4x: rename local config as curr_config referring drvdata->curr_config Yeoreum Yun
` (4 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Yeoreum Yun @ 2026-09-24 17:33 UTC (permalink / raw)
To: Mike Leach, James Clark, Leo Yan, Greg Kroah-Hartman,
Mathieu Poirier, coresight, linux-arm-kernel, linux-kernel,
linux-rt-devel
Cc: Suzuki K Poulose, Alexander Shishkin, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, Yeoreum Yun
s_ex_level is a hardware capability rather than a configurable parameter.
As such, it should not be stored in the configuration structure.
Remove s_ex_level from the config structure and pass etm4_caps to the
functions that need to access this capability.
Reviewed-by: Mike Leach <mike.leach@arm.com>
Tested-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
drivers/hwtracing/coresight/coresight-etm4x-core.c | 58 +++++++++++++---------
.../hwtracing/coresight/coresight-etm4x-sysfs.c | 2 +-
drivers/hwtracing/coresight/coresight-etm4x.h | 5 +-
3 files changed, 38 insertions(+), 27 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 4a8c1070bbcb..99d4e2d39e66 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -66,10 +66,12 @@ MODULE_PARM_DESC(pm_save_enable,
"Save/restore state on power down: 1 = never, 2 = self-hosted. MMIO and DT only.");
static struct etmv4_drvdata *etmdrvdata[NR_CPUS];
-static void etm4_set_default_config(struct etmv4_config *config);
+static void etm4_set_default_config(struct etmv4_config *config,
+ const struct etmv4_caps *caps);
static int etm4_set_event_filters(struct etmv4_drvdata *drvdata,
struct perf_event *event);
-static u64 etm4_get_access_type(struct etmv4_config *config);
+static u64 etm4_get_access_type(struct etmv4_config *config,
+ const struct etmv4_caps *caps);
static enum cpuhp_state hp_online;
@@ -800,7 +802,7 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
config->mode |= ETM_MODE_EXCL_GUEST;
/* Always start from the default config */
- etm4_set_default_config(config);
+ etm4_set_default_config(config, caps);
/* Configure filters specified on the perf cmd line, if any. */
ret = etm4_set_event_filters(drvdata, event);
@@ -1474,7 +1476,6 @@ static void etm4_init_arch_data(void *info)
/* EXLEVEL_S, bits[19:16] Secure state instruction tracing */
caps->s_ex_level = FIELD_GET(TRCIDR3_EXLEVEL_S_MASK, etmidr3);
- drvdata->config.s_ex_level = caps->s_ex_level;
/* EXLEVEL_NS, bits[23:20] Non-secure state instruction tracing */
caps->ns_ex_level = FIELD_GET(TRCIDR3_EXLEVEL_NS_MASK, etmidr3);
/*
@@ -1557,19 +1558,22 @@ static void etm4_init_arch_data(void *info)
cpu_detect_trace_filtering(drvdata);
}
-static u32 etm4_get_victlr_access_type(struct etmv4_config *config)
+static u32 etm4_get_victlr_access_type(struct etmv4_config *config,
+ const struct etmv4_caps *caps)
{
- return etm4_get_access_type(config) << __bf_shf(TRCVICTLR_EXLEVEL_MASK);
+ return etm4_get_access_type(config, caps) << __bf_shf(TRCVICTLR_EXLEVEL_MASK);
}
/* Set ELx trace filter access in the TRCVICTLR register */
-static void etm4_set_victlr_access(struct etmv4_config *config)
+static void etm4_set_victlr_access(struct etmv4_config *config,
+ const struct etmv4_caps *caps)
{
config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_MASK;
- config->vinst_ctrl |= etm4_get_victlr_access_type(config);
+ config->vinst_ctrl |= etm4_get_victlr_access_type(config, caps);
}
-static void etm4_set_default_config(struct etmv4_config *config)
+static void etm4_set_default_config(struct etmv4_config *config,
+ const struct etmv4_caps *caps)
{
/* disable all events tracing */
config->eventctrl0 = 0x0;
@@ -1588,7 +1592,7 @@ static void etm4_set_default_config(struct etmv4_config *config)
config->vinst_ctrl = FIELD_PREP(TRCVICTLR_EVENT_MASK, 0x01);
/* TRCVICTLR::EXLEVEL_NS:EXLEVELS: Set kernel / user filtering */
- etm4_set_victlr_access(config);
+ etm4_set_victlr_access(config, caps);
}
static u64 etm4_get_ns_access_type(struct etmv4_config *config)
@@ -1620,21 +1624,24 @@ static u64 etm4_get_ns_access_type(struct etmv4_config *config)
* This must be shifted to the corresponding register field
* for usage.
*/
-static u64 etm4_get_access_type(struct etmv4_config *config)
+static u64 etm4_get_access_type(struct etmv4_config *config,
+ const struct etmv4_caps *caps)
{
/* All Secure exception levels are excluded from the trace */
- return etm4_get_ns_access_type(config) | (u64)config->s_ex_level;
+ return etm4_get_ns_access_type(config) | (u64)caps->s_ex_level;
}
-static u64 etm4_get_comparator_access_type(struct etmv4_config *config)
+static u64 etm4_get_comparator_access_type(struct etmv4_config *config,
+ const struct etmv4_caps *caps)
{
- return etm4_get_access_type(config) << TRCACATR_EXLEVEL_SHIFT;
+ return etm4_get_access_type(config, caps) << TRCACATR_EXLEVEL_SHIFT;
}
static void etm4_set_comparator_filter(struct etmv4_config *config,
+ const struct etmv4_caps *caps,
u64 start, u64 stop, int comparator)
{
- u64 access_type = etm4_get_comparator_access_type(config);
+ u64 access_type = etm4_get_comparator_access_type(config, caps);
/* First half of default address comparator */
config->addr_val[comparator] = start;
@@ -1665,11 +1672,12 @@ static void etm4_set_comparator_filter(struct etmv4_config *config,
}
static void etm4_set_start_stop_filter(struct etmv4_config *config,
+ const struct etmv4_caps *caps,
u64 address, int comparator,
enum etm_addr_type type)
{
int shift;
- u64 access_type = etm4_get_comparator_access_type(config);
+ u64 access_type = etm4_get_comparator_access_type(config, caps);
/* Configure the comparator */
config->addr_val[comparator] = address;
@@ -1701,7 +1709,8 @@ static void etm4_set_default_filter(struct etmv4_config *config)
config->vissctlr = 0x0;
}
-static void etm4_set_default(struct etmv4_config *config)
+static void etm4_set_default(struct etmv4_config *config,
+ const struct etmv4_caps *caps)
{
if (WARN_ON_ONCE(!config))
return;
@@ -1713,7 +1722,7 @@ static void etm4_set_default(struct etmv4_config *config)
* full instruction trace - with a default filter for trace all
* achieved by having no filtering.
*/
- etm4_set_default_config(config);
+ etm4_set_default_config(config, caps);
etm4_set_default_filter(config);
}
@@ -1761,6 +1770,7 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata,
{
int i, comparator, ret = 0;
u64 address;
+ const struct etmv4_caps *caps = &drvdata->caps;
struct etmv4_config *config = &drvdata->curr_config;
struct etm_filters *filters = event->hw.addr_filters;
@@ -1790,7 +1800,7 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata,
switch (type) {
case ETM_ADDR_TYPE_RANGE:
- etm4_set_comparator_filter(config,
+ etm4_set_comparator_filter(config, caps,
filter->start_addr,
filter->stop_addr,
comparator);
@@ -1811,7 +1821,7 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata,
filter->stop_addr);
/* Configure comparator */
- etm4_set_start_stop_filter(config, address,
+ etm4_set_start_stop_filter(config, caps, address,
comparator, type);
/*
@@ -1847,7 +1857,8 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata,
return ret;
}
-void etm4_config_trace_mode(struct etmv4_config *config)
+void etm4_config_trace_mode(struct etmv4_config *config,
+ const struct etmv4_caps *caps)
{
u32 mode;
@@ -1861,7 +1872,7 @@ void etm4_config_trace_mode(struct etmv4_config *config)
if (!(mode & ETM_MODE_EXCL_KERN) && !(mode & ETM_MODE_EXCL_USER))
return;
- etm4_set_victlr_access(config);
+ etm4_set_victlr_access(config, caps);
}
static int etm4_online_cpu(unsigned int cpu)
@@ -2173,6 +2184,7 @@ static int etm4_add_coresight_dev(struct etm4_init_arg *init_arg)
struct coresight_platform_data *pdata = NULL;
struct device *dev = init_arg->dev;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
+ const struct etmv4_caps *caps = &drvdata->caps;
struct coresight_desc desc = { 0 };
u8 major, minor;
char *type_name;
@@ -2202,7 +2214,7 @@ 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->config, caps);
if (etm4x_always_pm_save(dev, init_arg->csa))
pm_save = true;
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index a66f34c942ba..8f5ea8edf5d8 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -443,7 +443,7 @@ static ssize_t mode_store(struct device *dev,
config->vinst_ctrl &= ~TRCVICTLR_TRCERR;
if (config->mode & (ETM_MODE_EXCL_KERN | ETM_MODE_EXCL_USER))
- etm4_config_trace_mode(config);
+ etm4_config_trace_mode(config, caps);
raw_spin_unlock(&drvdata->spinlock);
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
index 67071f7cbdbc..ae97c5c004bf 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -956,7 +956,6 @@ struct etmv4_caps {
* @vmid_mask0: VM ID comparator mask for comparator 0-3.
* @vmid_mask1: VM ID comparator mask for comparator 4-7.
* @ext_inp: External input selection.
- * @s_ex_level: Secure ELs where tracing is supported.
*/
struct etmv4_config {
u64 mode;
@@ -999,7 +998,6 @@ struct etmv4_config {
u32 vmid_mask0;
u32 vmid_mask1;
u32 ext_inp;
- u8 s_ex_level;
};
/**
@@ -1117,7 +1115,8 @@ enum etm_addr_ctxtype {
};
extern const struct attribute_group *coresight_etmv4_groups[];
-void etm4_config_trace_mode(struct etmv4_config *config);
+void etm4_config_trace_mode(struct etmv4_config *config,
+ const struct etmv4_caps *caps);
u64 etm4x_sysreg_read(u32 offset, bool _relaxed, bool _64bit);
void etm4x_sysreg_write(u64 val, u32 offset, bool _relaxed, bool _64bit);
--
2.43.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v12 10/14] coresight: etm4x: rename local config as curr_config referring drvdata->curr_config
2026-09-24 17:33 [PATCH v12 00/14] fix several inconsistencies with sysfs configuration in etmX Yeoreum Yun
` (8 preceding siblings ...)
2026-09-24 17:33 ` [PATCH v12 09/14] coresight: etm4x: remove s_ex_level from config Yeoreum Yun
@ 2026-09-24 17:33 ` Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 11/14] coresight: etm4x: rename drvdata->config to sysfs_config Yeoreum Yun
` (3 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Yeoreum Yun @ 2026-09-24 17:33 UTC (permalink / raw)
To: Mike Leach, James Clark, Leo Yan, Greg Kroah-Hartman,
Mathieu Poirier, coresight, linux-arm-kernel, linux-kernel,
linux-rt-devel
Cc: Suzuki K Poulose, Alexander Shishkin, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, Yeoreum Yun
For readability, rename the local config variable to curr_config in
places where it refers to drvdata->curr_config.
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
drivers/hwtracing/coresight/coresight-etm4x-core.c | 164 ++++++++++-----------
1 file changed, 82 insertions(+), 82 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 99d4e2d39e66..5db11309bfbb 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -270,11 +270,11 @@ static void etm4x_prohibit_trace(struct etmv4_drvdata *drvdata)
static u64 etm4x_get_kern_user_filter(struct etmv4_drvdata *drvdata)
{
u64 trfcr = drvdata->trfcr;
- struct etmv4_config *config = &drvdata->curr_config;
+ struct etmv4_config *curr_config = &drvdata->curr_config;
- if (config->mode & ETM_MODE_EXCL_KERN)
+ if (curr_config->mode & ETM_MODE_EXCL_KERN)
trfcr &= ~TRFCR_EL1_ExTRE;
- if (config->mode & ETM_MODE_EXCL_USER)
+ if (curr_config->mode & ETM_MODE_EXCL_USER)
trfcr &= ~TRFCR_EL1_E0TRE;
return trfcr;
@@ -293,13 +293,13 @@ static u64 etm4x_get_kern_user_filter(struct etmv4_drvdata *drvdata)
static void etm4x_allow_trace(struct etmv4_drvdata *drvdata)
{
u64 trfcr, guest_trfcr;
- struct etmv4_config *config = &drvdata->curr_config;
+ struct etmv4_config *curr_config = &drvdata->curr_config;
/* If the CPU doesn't support FEAT_TRF, nothing to do */
if (!drvdata->trfcr)
return;
- if (config->mode & ETM_MODE_EXCL_HOST)
+ if (curr_config->mode & ETM_MODE_EXCL_HOST)
trfcr = drvdata->trfcr & ~(TRFCR_EL1_ExTRE | TRFCR_EL1_E0TRE);
else
trfcr = etm4x_get_kern_user_filter(drvdata);
@@ -307,7 +307,7 @@ static void etm4x_allow_trace(struct etmv4_drvdata *drvdata)
write_trfcr(trfcr);
/* Set filters for guests and pass to KVM */
- if (config->mode & ETM_MODE_EXCL_GUEST)
+ if (curr_config->mode & ETM_MODE_EXCL_GUEST)
guest_trfcr = drvdata->trfcr & ~(TRFCR_EL1_ExTRE | TRFCR_EL1_E0TRE);
else
guest_trfcr = etm4x_get_kern_user_filter(drvdata);
@@ -501,7 +501,7 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
{
int i, rc;
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->curr_config;
+ struct etmv4_config *curr_config = &drvdata->curr_config;
struct coresight_device *csdev = drvdata->csdev;
struct device *etm_dev = &csdev->dev;
struct csdev_access *csa = &csdev->access;
@@ -533,37 +533,37 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
dev_err(etm_dev,
"timeout while waiting for Idle Trace Status\n");
if (caps->nr_pe)
- etm4x_relaxed_write32(csa, config->pe_sel, TRCPROCSELR);
- etm4x_relaxed_write32(csa, config->cfg, TRCCONFIGR);
+ etm4x_relaxed_write32(csa, curr_config->pe_sel, TRCPROCSELR);
+ etm4x_relaxed_write32(csa, curr_config->cfg, TRCCONFIGR);
/* nothing specific implemented */
etm4x_relaxed_write32(csa, 0x0, TRCAUXCTLR);
- etm4x_relaxed_write32(csa, config->eventctrl0, TRCEVENTCTL0R);
- etm4x_relaxed_write32(csa, config->eventctrl1, TRCEVENTCTL1R);
+ etm4x_relaxed_write32(csa, curr_config->eventctrl0, TRCEVENTCTL0R);
+ etm4x_relaxed_write32(csa, curr_config->eventctrl1, TRCEVENTCTL1R);
if (caps->stallctl)
- etm4x_relaxed_write32(csa, config->stall_ctrl, TRCSTALLCTLR);
- etm4x_relaxed_write32(csa, config->ts_ctrl, TRCTSCTLR);
- etm4x_relaxed_write32(csa, config->syncfreq, TRCSYNCPR);
- etm4x_relaxed_write32(csa, config->ccctlr, TRCCCCTLR);
- etm4x_relaxed_write32(csa, config->bb_ctrl, TRCBBCTLR);
+ etm4x_relaxed_write32(csa, curr_config->stall_ctrl, TRCSTALLCTLR);
+ etm4x_relaxed_write32(csa, curr_config->ts_ctrl, TRCTSCTLR);
+ etm4x_relaxed_write32(csa, curr_config->syncfreq, TRCSYNCPR);
+ etm4x_relaxed_write32(csa, curr_config->ccctlr, TRCCCCTLR);
+ etm4x_relaxed_write32(csa, curr_config->bb_ctrl, TRCBBCTLR);
etm4x_relaxed_write32(csa, drvdata->trcid, TRCTRACEIDR);
- etm4x_relaxed_write32(csa, config->vinst_ctrl, TRCVICTLR);
- etm4x_relaxed_write32(csa, config->viiectlr, TRCVIIECTLR);
- etm4x_relaxed_write32(csa, config->vissctlr, TRCVISSCTLR);
+ etm4x_relaxed_write32(csa, curr_config->vinst_ctrl, TRCVICTLR);
+ etm4x_relaxed_write32(csa, curr_config->viiectlr, TRCVIIECTLR);
+ etm4x_relaxed_write32(csa, curr_config->vissctlr, TRCVISSCTLR);
if (caps->nr_pe_cmp)
- etm4x_relaxed_write32(csa, config->vipcssctlr, TRCVIPCSSCTLR);
+ etm4x_relaxed_write32(csa, curr_config->vipcssctlr, TRCVIPCSSCTLR);
for (i = 0; i < caps->nr_seq_ctrls; i++)
- etm4x_relaxed_write32(csa, config->seq_ctrl[i], TRCSEQEVRn(i));
+ etm4x_relaxed_write32(csa, curr_config->seq_ctrl[i], TRCSEQEVRn(i));
if (caps->nrseqstate) {
- etm4x_relaxed_write32(csa, config->seq_rst, TRCSEQRSTEVR);
- etm4x_relaxed_write32(csa, config->seq_state, TRCSEQSTR);
+ etm4x_relaxed_write32(csa, curr_config->seq_rst, TRCSEQRSTEVR);
+ etm4x_relaxed_write32(csa, curr_config->seq_state, TRCSEQSTR);
}
if (caps->numextinsel)
- etm4x_relaxed_write32(csa, config->ext_inp, TRCEXTINSELR);
+ etm4x_relaxed_write32(csa, curr_config->ext_inp, TRCEXTINSELR);
for (i = 0; i < caps->nr_cntr; i++) {
- etm4x_relaxed_write32(csa, config->cntrldvr[i], TRCCNTRLDVRn(i));
- etm4x_relaxed_write32(csa, config->cntr_ctrl[i], TRCCNTCTLRn(i));
- etm4x_relaxed_write32(csa, config->cntr_val[i], TRCCNTVRn(i));
+ etm4x_relaxed_write32(csa, curr_config->cntrldvr[i], TRCCNTRLDVRn(i));
+ etm4x_relaxed_write32(csa, curr_config->cntr_ctrl[i], TRCCNTCTLRn(i));
+ etm4x_relaxed_write32(csa, curr_config->cntr_val[i], TRCCNTVRn(i));
}
/*
@@ -571,32 +571,32 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
* such start at 2.
*/
for (i = 2; i < caps->nr_resource * 2; i++)
- etm4x_relaxed_write32(csa, config->res_ctrl[i], TRCRSCTLRn(i));
+ etm4x_relaxed_write32(csa, curr_config->res_ctrl[i], TRCRSCTLRn(i));
for (i = 0; i < caps->nr_ss_cmp; i++) {
/* always clear status and pending bits on restart if using single-shot */
- if (config->ss_ctrl[i] || config->ss_pe_cmp[i])
+ if (curr_config->ss_ctrl[i] || curr_config->ss_pe_cmp[i])
drvdata->ss_status[i] &= ~(TRCSSCSRn_STATUS | TRCSSCSRn_PENDING);
- etm4x_relaxed_write32(csa, config->ss_ctrl[i], TRCSSCCRn(i));
+ etm4x_relaxed_write32(csa, curr_config->ss_ctrl[i], TRCSSCCRn(i));
etm4x_relaxed_write32(csa, drvdata->ss_status[i], TRCSSCSRn(i));
if (etm4x_sspcicrn_present(drvdata, i))
- etm4x_relaxed_write32(csa, config->ss_pe_cmp[i], TRCSSPCICRn(i));
+ etm4x_relaxed_write32(csa, curr_config->ss_pe_cmp[i], TRCSSPCICRn(i));
}
for (i = 0; i < caps->nr_addr_cmp * 2; i++) {
- etm4x_relaxed_write64(csa, config->addr_val[i], TRCACVRn(i));
- etm4x_relaxed_write64(csa, config->addr_acc[i], TRCACATRn(i));
+ etm4x_relaxed_write64(csa, curr_config->addr_val[i], TRCACVRn(i));
+ etm4x_relaxed_write64(csa, curr_config->addr_acc[i], TRCACATRn(i));
}
for (i = 0; i < caps->numcidc; i++)
- etm4x_relaxed_write64(csa, config->ctxid_pid[i], TRCCIDCVRn(i));
- etm4x_relaxed_write32(csa, config->ctxid_mask0, TRCCIDCCTLR0);
+ etm4x_relaxed_write64(csa, curr_config->ctxid_pid[i], TRCCIDCVRn(i));
+ etm4x_relaxed_write32(csa, curr_config->ctxid_mask0, TRCCIDCCTLR0);
if (caps->numcidc > 4)
- etm4x_relaxed_write32(csa, config->ctxid_mask1, TRCCIDCCTLR1);
+ etm4x_relaxed_write32(csa, curr_config->ctxid_mask1, TRCCIDCCTLR1);
for (i = 0; i < caps->numvmidc; i++)
- etm4x_relaxed_write64(csa, config->vmid_val[i], TRCVMIDCVRn(i));
- etm4x_relaxed_write32(csa, config->vmid_mask0, TRCVMIDCCTLR0);
+ etm4x_relaxed_write64(csa, curr_config->vmid_val[i], TRCVMIDCVRn(i));
+ etm4x_relaxed_write32(csa, curr_config->vmid_mask0, TRCVMIDCCTLR0);
if (caps->numvmidc > 4)
- etm4x_relaxed_write32(csa, config->vmid_mask1, TRCVMIDCCTLR1);
+ etm4x_relaxed_write32(csa, curr_config->vmid_mask1, TRCVMIDCCTLR1);
if (!caps->skip_power_up) {
u32 trcpdcr = etm4x_relaxed_read32(csa, TRCPDCR);
@@ -694,7 +694,7 @@ static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata,
int ctridx;
int rselector;
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->curr_config;
+ struct etmv4_config *curr_config = &drvdata->curr_config;
/* No point in trying if we don't have at least one counter */
if (!caps->nr_cntr)
@@ -702,7 +702,7 @@ static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata,
/* Find a counter that hasn't been initialised */
for (ctridx = 0; ctridx < caps->nr_cntr; ctridx++)
- if (config->cntr_val[ctridx] == 0)
+ if (curr_config->cntr_val[ctridx] == 0)
break;
/* All the counters have been configured already, bail out */
@@ -723,7 +723,7 @@ static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata,
* by 2.
*/
for (rselector = 2; rselector < caps->nr_resource * 2; rselector++)
- if (!config->res_ctrl[rselector])
+ if (!curr_config->res_ctrl[rselector])
break;
if (rselector == caps->nr_resource * 2) {
@@ -733,7 +733,7 @@ static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata,
}
/* Initialise original and reload counter value. */
- config->cntr_val[ctridx] = config->cntrldvr[ctridx] = 1 << (ts_level - 1);
+ curr_config->cntr_val[ctridx] = curr_config->cntrldvr[ctridx] = 1 << (ts_level - 1);
/*
* Trace Counter Control Register TRCCNTCTLRn
@@ -743,11 +743,11 @@ static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata,
* RLDEVENT = RES_SEL_FALSE (0), reload on single false resource (never reload)
* CNTEVENT = RES_SEL_TRUE (1), count single fixed 'always true' resource (always decrement)
*/
- config->cntr_ctrl[ctridx] = TRCCNTCTLRn_RLDSELF |
- FIELD_PREP(TRCCNTCTLRn_RLDEVENT_MASK,
- etm4_res_sel_single(ETM4_RES_SEL_FALSE)) |
- FIELD_PREP(TRCCNTCTLRn_CNTEVENT_MASK,
- etm4_res_sel_single(ETM4_RES_SEL_TRUE));
+ curr_config->cntr_ctrl[ctridx] = TRCCNTCTLRn_RLDSELF |
+ FIELD_PREP(TRCCNTCTLRn_RLDEVENT_MASK,
+ etm4_res_sel_single(ETM4_RES_SEL_FALSE)) |
+ FIELD_PREP(TRCCNTCTLRn_CNTEVENT_MASK,
+ etm4_res_sel_single(ETM4_RES_SEL_TRUE));
/*
* Resource Selection Control Register TRCRSCTLRn
@@ -758,16 +758,16 @@ static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata,
* Multiple counters can be selected, and each bit signifies a counter,
* so set bit 'ctridx' to select our counter.
*/
- config->res_ctrl[rselector] = FIELD_PREP(TRCRSCTLRn_GROUP_MASK, 2) |
- FIELD_PREP(TRCRSCTLRn_SELECT_MASK, 1 << ctridx);
+ curr_config->res_ctrl[rselector] = FIELD_PREP(TRCRSCTLRn_GROUP_MASK, 2) |
+ FIELD_PREP(TRCRSCTLRn_SELECT_MASK, 1 << ctridx);
/*
* Global Timestamp Control Register TRCTSCTLR
*
* EVENT = generate timestamp on single resource 'rselector'
*/
- config->ts_ctrl = FIELD_PREP(TRCTSCTLR_EVENT_MASK,
- etm4_res_sel_single(rselector));
+ curr_config->ts_ctrl = FIELD_PREP(TRCTSCTLR_EVENT_MASK,
+ etm4_res_sel_single(rselector));
return 0;
}
@@ -778,7 +778,7 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
int ret = 0;
struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->curr_config;
+ struct etmv4_config *curr_config = &drvdata->curr_config;
struct perf_event_attr max_timestamp = {
.ATTR_CFG_FLD_timestamp_CFG = U64_MAX,
};
@@ -787,22 +787,22 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
u8 ts_level;
/* Clear configuration from previous run */
- memset(config, 0, sizeof(struct etmv4_config));
+ memset(curr_config, 0, sizeof(struct etmv4_config));
if (attr->exclude_kernel)
- config->mode = ETM_MODE_EXCL_KERN;
+ curr_config->mode = ETM_MODE_EXCL_KERN;
if (attr->exclude_user)
- config->mode = ETM_MODE_EXCL_USER;
+ curr_config->mode = ETM_MODE_EXCL_USER;
if (attr->exclude_host)
- config->mode |= ETM_MODE_EXCL_HOST;
+ curr_config->mode |= ETM_MODE_EXCL_HOST;
if (attr->exclude_guest)
- config->mode |= ETM_MODE_EXCL_GUEST;
+ curr_config->mode |= ETM_MODE_EXCL_GUEST;
/* Always start from the default config */
- etm4_set_default_config(config, caps);
+ etm4_set_default_config(curr_config, caps);
/* Configure filters specified on the perf cmd line, if any. */
ret = etm4_set_event_filters(drvdata, event);
@@ -811,14 +811,14 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
/* Go from generic option to ETMv4 specifics */
if (ATTR_CFG_GET_FLD(attr, cycacc)) {
- config->cfg |= TRCCONFIGR_CCI;
+ curr_config->cfg |= TRCCONFIGR_CCI;
/* TRM: Must program this for cycacc to work */
cc_threshold = ATTR_CFG_GET_FLD(attr, cc_threshold);
if (!cc_threshold)
cc_threshold = ETM_CYC_THRESHOLD_DEFAULT;
if (cc_threshold < caps->ccitmin)
cc_threshold = caps->ccitmin;
- config->ccctlr = cc_threshold;
+ curr_config->ccctlr = cc_threshold;
}
ts_level = max(ATTR_CFG_GET_FLD(attr, timestamp),
@@ -840,14 +840,14 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
}
/* bit[11], Global timestamp tracing bit */
- config->cfg |= TRCCONFIGR_TS;
+ curr_config->cfg |= TRCCONFIGR_TS;
}
/* Only trace contextID when runs in root PID namespace */
if (ATTR_CFG_GET_FLD(attr, contextid1) &&
task_is_in_init_pid_ns(current))
/* bit[6], Context ID tracing bit */
- config->cfg |= TRCCONFIGR_CID;
+ curr_config->cfg |= TRCCONFIGR_CID;
/*
* If set bit contextid2 in perf config, this asks to trace VMID for
@@ -861,13 +861,13 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
}
/* Only trace virtual contextID when runs in root PID namespace */
if (task_is_in_init_pid_ns(current))
- config->cfg |= TRCCONFIGR_VMID | TRCCONFIGR_VMIDOPT;
+ curr_config->cfg |= TRCCONFIGR_VMID | TRCCONFIGR_VMIDOPT;
}
/* return stack - enable if selected and supported */
if (ATTR_CFG_GET_FLD(attr, retstack) && caps->retstack)
/* bit[12], Return stack enable bit */
- config->cfg |= TRCCONFIGR_RS;
+ curr_config->cfg |= TRCCONFIGR_RS;
/* branch broadcast - enable if selected and supported */
if (ATTR_CFG_GET_FLD(attr, branch_broadcast)) {
@@ -879,7 +879,7 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
ret = -EINVAL;
goto out;
} else {
- config->cfg |= TRCCONFIGR_BB;
+ curr_config->cfg |= TRCCONFIGR_BB;
}
}
@@ -1061,7 +1061,7 @@ static void etm4_disable_hw(struct etmv4_drvdata *drvdata)
{
u32 control;
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->curr_config;
+ struct etmv4_config *curr_config = &drvdata->curr_config;
struct coresight_device *csdev = drvdata->csdev;
struct csdev_access *csa = &csdev->access;
int i;
@@ -1086,13 +1086,13 @@ static void etm4_disable_hw(struct etmv4_drvdata *drvdata)
/* read back the current counter values */
for (i = 0; i < caps->nr_cntr; i++) {
- config->cntr_val[i] =
- etm4x_relaxed_read32(csa, TRCCNTVRn(i));
+ curr_config->cntr_val[i] =
+ etm4x_relaxed_read32(csa, TRCCNTVRn(i));
}
/* read back the sequence state */
if (caps->nrseqstate)
- config->seq_state = etm4x_relaxed_read32(csa, TRCSEQSTR);
+ curr_config->seq_state = etm4x_relaxed_read32(csa, TRCSEQSTR);
coresight_disclaim_device_unlocked(csdev);
etm4_cs_lock(drvdata, csa);
@@ -1729,7 +1729,7 @@ static void etm4_set_default(struct etmv4_config *config,
static int etm4_get_next_comparator(struct etmv4_drvdata *drvdata, u32 type)
{
int nr_comparator, index = 0;
- struct etmv4_config *config = &drvdata->curr_config;
+ struct etmv4_config *curr_config = &drvdata->curr_config;
/*
* nr_addr_cmp holds the number of comparator _pair_, so time 2
@@ -1741,8 +1741,8 @@ static int etm4_get_next_comparator(struct etmv4_drvdata *drvdata, u32 type)
while (index < nr_comparator) {
switch (type) {
case ETM_ADDR_TYPE_RANGE:
- if (config->addr_type[index] == ETM_ADDR_TYPE_NONE &&
- config->addr_type[index + 1] == ETM_ADDR_TYPE_NONE)
+ if (curr_config->addr_type[index] == ETM_ADDR_TYPE_NONE &&
+ curr_config->addr_type[index + 1] == ETM_ADDR_TYPE_NONE)
return index;
/* Address range comparators go in pairs */
@@ -1750,7 +1750,7 @@ static int etm4_get_next_comparator(struct etmv4_drvdata *drvdata, u32 type)
break;
case ETM_ADDR_TYPE_START:
case ETM_ADDR_TYPE_STOP:
- if (config->addr_type[index] == ETM_ADDR_TYPE_NONE)
+ if (curr_config->addr_type[index] == ETM_ADDR_TYPE_NONE)
return index;
/* Start/stop address can have odd indexes */
@@ -1771,7 +1771,7 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata,
int i, comparator, ret = 0;
u64 address;
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->curr_config;
+ struct etmv4_config *curr_config = &drvdata->curr_config;
struct etm_filters *filters = event->hw.addr_filters;
if (!filters)
@@ -1800,7 +1800,7 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata,
switch (type) {
case ETM_ADDR_TYPE_RANGE:
- etm4_set_comparator_filter(config, caps,
+ etm4_set_comparator_filter(curr_config, caps,
filter->start_addr,
filter->stop_addr,
comparator);
@@ -1808,10 +1808,10 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata,
* TRCVICTLR::SSSTATUS == 1, the start-stop logic is
* in the started state
*/
- config->vinst_ctrl |= TRCVICTLR_SSSTATUS;
+ curr_config->vinst_ctrl |= TRCVICTLR_SSSTATUS;
/* No start-stop filtering for ViewInst */
- config->vissctlr = 0x0;
+ curr_config->vissctlr = 0x0;
break;
case ETM_ADDR_TYPE_START:
case ETM_ADDR_TYPE_STOP:
@@ -1821,7 +1821,7 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata,
filter->stop_addr);
/* Configure comparator */
- etm4_set_start_stop_filter(config, caps, address,
+ etm4_set_start_stop_filter(curr_config, caps, address,
comparator, type);
/*
@@ -1836,10 +1836,10 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata,
* etm4_disable_perf().
*/
if (filters->ssstatus)
- config->vinst_ctrl |= TRCVICTLR_SSSTATUS;
+ curr_config->vinst_ctrl |= TRCVICTLR_SSSTATUS;
/* No include/exclude filtering for ViewInst */
- config->viiectlr = 0x0;
+ curr_config->viiectlr = 0x0;
break;
default:
ret = -EINVAL;
@@ -1851,7 +1851,7 @@ static int etm4_set_event_filters(struct etmv4_drvdata *drvdata,
default_filter:
- etm4_set_default_filter(config);
+ etm4_set_default_filter(curr_config);
out:
return ret;
--
2.43.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v12 11/14] coresight: etm4x: rename drvdata->config to sysfs_config
2026-09-24 17:33 [PATCH v12 00/14] fix several inconsistencies with sysfs configuration in etmX Yeoreum Yun
` (9 preceding siblings ...)
2026-09-24 17:33 ` [PATCH v12 10/14] coresight: etm4x: rename local config as curr_config referring drvdata->curr_config Yeoreum Yun
@ 2026-09-24 17:33 ` Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 12/14] coresight: etm3x: introduce struct etm_caps Yeoreum Yun
` (2 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Yeoreum Yun @ 2026-09-24 17:33 UTC (permalink / raw)
To: Mike Leach, James Clark, Leo Yan, Greg Kroah-Hartman,
Mathieu Poirier, coresight, linux-arm-kernel, linux-kernel,
linux-rt-devel
Cc: Suzuki K Poulose, Alexander Shishkin, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, Yeoreum Yun
drvdata->config is used only by the sysfs interface.
Rename it to sysfs_config to clarify its purpose.
For readability, also rename local config variables to sysfs_config
where they refer to drvdata->sysfs_config.
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
drivers/hwtracing/coresight/coresight-etm4x-core.c | 10 +-
.../hwtracing/coresight/coresight-etm4x-sysfs.c | 775 +++++++++++----------
drivers/hwtracing/coresight/coresight-etm4x.h | 4 +-
3 files changed, 395 insertions(+), 394 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 5db11309bfbb..2a4751a75382 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -960,7 +960,7 @@ static int etm4_enable_sysfs(struct coresight_device *csdev, struct coresight_pa
arg.path = path;
scoped_guard(raw_spinlock, &drvdata->spinlock) {
- drvdata->curr_config = drvdata->config;
+ drvdata->curr_config = drvdata->sysfs_config;
}
ret = smp_call_function_single(drvdata->cpu,
@@ -1153,7 +1153,7 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
{
struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
const struct etmv4_config *curr_config = &drvdata->curr_config;
int i;
@@ -1169,9 +1169,9 @@ static void etm4_disable_sysfs(struct coresight_device *csdev)
* the sysfs-session has been disabled.
*/
for (i = 0; i < caps->nr_cntr; i++)
- config->cntr_val[i] = curr_config->cntr_val[i];
+ sysfs_config->cntr_val[i] = curr_config->cntr_val[i];
- config->seq_state = curr_config->seq_state;
+ sysfs_config->seq_state = curr_config->seq_state;
coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED);
@@ -2214,7 +2214,7 @@ static int etm4_add_coresight_dev(struct etm4_init_arg *init_arg)
if (!desc.name)
return -ENOMEM;
- etm4_set_default(&drvdata->config, caps);
+ etm4_set_default(&drvdata->sysfs_config, caps);
if (etm4x_always_pm_save(dev, init_arg->csa))
pm_save = true;
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index 8f5ea8edf5d8..9dadf2c6f1be 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -16,15 +16,15 @@
static int etm4_set_mode_exclude(struct etmv4_drvdata *drvdata, bool exclude)
{
u8 idx;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- idx = config->addr_idx;
+ idx = sysfs_config->addr_idx;
/*
* TRCACATRn.TYPE bit[1:0]: type of comparison
* the trace unit performs
*/
- if (FIELD_GET(TRCACATRn_TYPE_MASK, config->addr_acc[idx]) == TRCACATRn_TYPE_ADDR) {
+ if (FIELD_GET(TRCACATRn_TYPE_MASK, sysfs_config->addr_acc[idx]) == TRCACATRn_TYPE_ADDR) {
if (idx % 2 != 0)
return -EINVAL;
@@ -33,8 +33,8 @@ static int etm4_set_mode_exclude(struct etmv4_drvdata *drvdata, bool exclude)
* relevant bit of ViewInst Include/Exclude Control register
* for corresponding address comparator pair.
*/
- if (config->addr_type[idx] != ETM_ADDR_TYPE_RANGE ||
- config->addr_type[idx + 1] != ETM_ADDR_TYPE_RANGE)
+ if (sysfs_config->addr_type[idx] != ETM_ADDR_TYPE_RANGE ||
+ sysfs_config->addr_type[idx + 1] != ETM_ADDR_TYPE_RANGE)
return -EINVAL;
if (exclude == true) {
@@ -42,15 +42,15 @@ static int etm4_set_mode_exclude(struct etmv4_drvdata *drvdata, bool exclude)
* Set exclude bit and unset the include bit
* corresponding to comparator pair
*/
- config->viiectlr |= BIT(idx / 2 + 16);
- config->viiectlr &= ~BIT(idx / 2);
+ sysfs_config->viiectlr |= BIT(idx / 2 + 16);
+ sysfs_config->viiectlr &= ~BIT(idx / 2);
} else {
/*
* Set include bit and unset exclude bit
* corresponding to comparator pair
*/
- config->viiectlr |= BIT(idx / 2);
- config->viiectlr &= ~BIT(idx / 2 + 16);
+ sysfs_config->viiectlr |= BIT(idx / 2);
+ sysfs_config->viiectlr &= ~BIT(idx / 2 + 16);
}
}
return 0;
@@ -181,102 +181,102 @@ static ssize_t reset_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
if (val)
- config->mode = 0x0;
+ sysfs_config->mode = 0x0;
/* Disable data tracing: do not trace load and store data transfers */
- config->mode &= ~(ETM_MODE_LOAD | ETM_MODE_STORE);
- config->cfg &= ~(TRCCONFIGR_INSTP0_LOAD | TRCCONFIGR_INSTP0_STORE);
+ sysfs_config->mode &= ~(ETM_MODE_LOAD | ETM_MODE_STORE);
+ sysfs_config->cfg &= ~(TRCCONFIGR_INSTP0_LOAD | TRCCONFIGR_INSTP0_STORE);
/* Disable data value and data address tracing */
- config->mode &= ~(ETM_MODE_DATA_TRACE_ADDR |
+ sysfs_config->mode &= ~(ETM_MODE_DATA_TRACE_ADDR |
ETM_MODE_DATA_TRACE_VAL);
- config->cfg &= ~(TRCCONFIGR_DA | TRCCONFIGR_DV);
+ sysfs_config->cfg &= ~(TRCCONFIGR_DA | TRCCONFIGR_DV);
/* Disable all events tracing */
- config->eventctrl0 = 0x0;
- config->eventctrl1 = 0x0;
+ sysfs_config->eventctrl0 = 0x0;
+ sysfs_config->eventctrl1 = 0x0;
/* Disable timestamp event */
- config->ts_ctrl = 0x0;
+ sysfs_config->ts_ctrl = 0x0;
/* Disable stalling */
- config->stall_ctrl = 0x0;
+ sysfs_config->stall_ctrl = 0x0;
/* Reset trace synchronization period to 2^8 = 256 bytes*/
if (!caps->syncpr)
- config->syncfreq = 0x8;
+ sysfs_config->syncfreq = 0x8;
/*
* Enable ViewInst to trace everything with start-stop logic in
* started state. ARM recommends start-stop logic is set before
* each trace run.
*/
- config->vinst_ctrl = FIELD_PREP(TRCVICTLR_EVENT_MASK, 0x01);
+ sysfs_config->vinst_ctrl = FIELD_PREP(TRCVICTLR_EVENT_MASK, 0x01);
if (caps->nr_addr_cmp > 0) {
- config->mode |= ETM_MODE_VIEWINST_STARTSTOP;
+ sysfs_config->mode |= ETM_MODE_VIEWINST_STARTSTOP;
/* SSSTATUS, bit[9] */
- config->vinst_ctrl |= TRCVICTLR_SSSTATUS;
+ sysfs_config->vinst_ctrl |= TRCVICTLR_SSSTATUS;
}
/* No address range filtering for ViewInst */
- config->viiectlr = 0x0;
+ sysfs_config->viiectlr = 0x0;
/* No start-stop filtering for ViewInst */
- config->vissctlr = 0x0;
- config->vipcssctlr = 0x0;
+ sysfs_config->vissctlr = 0x0;
+ sysfs_config->vipcssctlr = 0x0;
/* Disable seq events */
for (i = 0; i < caps->nr_seq_ctrls; i++)
- config->seq_ctrl[i] = 0x0;
- config->seq_rst = 0x0;
- config->seq_state = 0x0;
+ sysfs_config->seq_ctrl[i] = 0x0;
+ sysfs_config->seq_rst = 0x0;
+ sysfs_config->seq_state = 0x0;
/* Disable external input events */
- config->ext_inp = 0x0;
+ sysfs_config->ext_inp = 0x0;
- config->cntr_idx = 0x0;
+ sysfs_config->cntr_idx = 0x0;
for (i = 0; i < caps->nr_cntr; i++) {
- config->cntrldvr[i] = 0x0;
- config->cntr_ctrl[i] = 0x0;
- config->cntr_val[i] = 0x0;
+ sysfs_config->cntrldvr[i] = 0x0;
+ sysfs_config->cntr_ctrl[i] = 0x0;
+ sysfs_config->cntr_val[i] = 0x0;
}
- config->res_idx = 0x0;
+ sysfs_config->res_idx = 0x0;
for (i = 2; i < 2 * caps->nr_resource; i++)
- config->res_ctrl[i] = 0x0;
+ sysfs_config->res_ctrl[i] = 0x0;
- config->ss_idx = 0x0;
+ sysfs_config->ss_idx = 0x0;
for (i = 0; i < caps->nr_ss_cmp; i++) {
- config->ss_ctrl[i] = 0x0;
- config->ss_pe_cmp[i] = 0x0;
+ sysfs_config->ss_ctrl[i] = 0x0;
+ sysfs_config->ss_pe_cmp[i] = 0x0;
}
- config->addr_idx = 0x0;
+ sysfs_config->addr_idx = 0x0;
for (i = 0; i < caps->nr_addr_cmp * 2; i++) {
- config->addr_val[i] = 0x0;
- config->addr_acc[i] = 0x0;
- config->addr_type[i] = ETM_ADDR_TYPE_NONE;
+ sysfs_config->addr_val[i] = 0x0;
+ sysfs_config->addr_acc[i] = 0x0;
+ sysfs_config->addr_type[i] = ETM_ADDR_TYPE_NONE;
}
- config->ctxid_idx = 0x0;
+ sysfs_config->ctxid_idx = 0x0;
for (i = 0; i < caps->numcidc; i++)
- config->ctxid_pid[i] = 0x0;
+ sysfs_config->ctxid_pid[i] = 0x0;
- config->ctxid_mask0 = 0x0;
- config->ctxid_mask1 = 0x0;
+ sysfs_config->ctxid_mask0 = 0x0;
+ sysfs_config->ctxid_mask1 = 0x0;
- config->vmid_idx = 0x0;
+ sysfs_config->vmid_idx = 0x0;
for (i = 0; i < caps->numvmidc; i++)
- config->vmid_val[i] = 0x0;
- config->vmid_mask0 = 0x0;
- config->vmid_mask1 = 0x0;
+ sysfs_config->vmid_val[i] = 0x0;
+ sysfs_config->vmid_mask0 = 0x0;
+ sysfs_config->vmid_mask1 = 0x0;
raw_spin_unlock(&drvdata->spinlock);
@@ -295,9 +295,9 @@ static ssize_t mode_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- val = config->mode;
+ val = sysfs_config->mode;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -308,142 +308,142 @@ static ssize_t mode_store(struct device *dev,
unsigned long val, mode;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- config->mode = val & ETMv4_MODE_ALL;
+ sysfs_config->mode = val & ETMv4_MODE_ALL;
if (caps->instrp0) {
/* start by clearing instruction P0 field */
- config->cfg &= ~TRCCONFIGR_INSTP0_LOAD_STORE;
- if (config->mode & ETM_MODE_LOAD)
+ sysfs_config->cfg &= ~TRCCONFIGR_INSTP0_LOAD_STORE;
+ if (sysfs_config->mode & ETM_MODE_LOAD)
/* 0b01 Trace load instructions as P0 instructions */
- config->cfg |= TRCCONFIGR_INSTP0_LOAD;
- if (config->mode & ETM_MODE_STORE)
+ sysfs_config->cfg |= TRCCONFIGR_INSTP0_LOAD;
+ if (sysfs_config->mode & ETM_MODE_STORE)
/* 0b10 Trace store instructions as P0 instructions */
- config->cfg |= TRCCONFIGR_INSTP0_STORE;
- if (config->mode & ETM_MODE_LOAD_STORE)
+ sysfs_config->cfg |= TRCCONFIGR_INSTP0_STORE;
+ if (sysfs_config->mode & ETM_MODE_LOAD_STORE)
/*
* 0b11 Trace load and store instructions
* as P0 instructions
*/
- config->cfg |= TRCCONFIGR_INSTP0_LOAD_STORE;
+ sysfs_config->cfg |= TRCCONFIGR_INSTP0_LOAD_STORE;
}
/* bit[3], Branch broadcast mode */
- if ((config->mode & ETM_MODE_BB) && (caps->trcbb))
- config->cfg |= TRCCONFIGR_BB;
+ if ((sysfs_config->mode & ETM_MODE_BB) && (caps->trcbb))
+ sysfs_config->cfg |= TRCCONFIGR_BB;
else
- config->cfg &= ~TRCCONFIGR_BB;
+ sysfs_config->cfg &= ~TRCCONFIGR_BB;
/* bit[4], Cycle counting instruction trace bit */
- if ((config->mode & ETMv4_MODE_CYCACC) &&
+ if ((sysfs_config->mode & ETMv4_MODE_CYCACC) &&
(caps->trccci == true))
- config->cfg |= TRCCONFIGR_CCI;
+ sysfs_config->cfg |= TRCCONFIGR_CCI;
else
- config->cfg &= ~TRCCONFIGR_CCI;
+ sysfs_config->cfg &= ~TRCCONFIGR_CCI;
/* bit[6], Context ID tracing bit */
- if ((config->mode & ETMv4_MODE_CTXID) && (caps->ctxid_size))
- config->cfg |= TRCCONFIGR_CID;
+ if ((sysfs_config->mode & ETMv4_MODE_CTXID) && (caps->ctxid_size))
+ sysfs_config->cfg |= TRCCONFIGR_CID;
else
- config->cfg &= ~TRCCONFIGR_CID;
+ sysfs_config->cfg &= ~TRCCONFIGR_CID;
- if ((config->mode & ETM_MODE_VMID) && (caps->vmid_size))
- config->cfg |= TRCCONFIGR_VMID;
+ if ((sysfs_config->mode & ETM_MODE_VMID) && (caps->vmid_size))
+ sysfs_config->cfg |= TRCCONFIGR_VMID;
else
- config->cfg &= ~TRCCONFIGR_VMID;
+ sysfs_config->cfg &= ~TRCCONFIGR_VMID;
/* bits[10:8], Conditional instruction tracing bit */
- mode = ETM_MODE_COND(config->mode);
+ mode = ETM_MODE_COND(sysfs_config->mode);
if (caps->trccond) {
- config->cfg &= ~TRCCONFIGR_COND_MASK;
- config->cfg |= mode << __bf_shf(TRCCONFIGR_COND_MASK);
+ sysfs_config->cfg &= ~TRCCONFIGR_COND_MASK;
+ sysfs_config->cfg |= mode << __bf_shf(TRCCONFIGR_COND_MASK);
}
/* bit[11], Global timestamp tracing bit */
- if ((config->mode & ETMv4_MODE_TIMESTAMP) && (caps->ts_size))
- config->cfg |= TRCCONFIGR_TS;
+ if ((sysfs_config->mode & ETMv4_MODE_TIMESTAMP) && (caps->ts_size))
+ sysfs_config->cfg |= TRCCONFIGR_TS;
else
- config->cfg &= ~TRCCONFIGR_TS;
+ sysfs_config->cfg &= ~TRCCONFIGR_TS;
/* bit[12], Return stack enable bit */
- if ((config->mode & ETM_MODE_RETURNSTACK) && (caps->retstack))
- config->cfg |= TRCCONFIGR_RS;
+ if ((sysfs_config->mode & ETM_MODE_RETURNSTACK) && (caps->retstack))
+ sysfs_config->cfg |= TRCCONFIGR_RS;
else
- config->cfg &= ~TRCCONFIGR_RS;
+ sysfs_config->cfg &= ~TRCCONFIGR_RS;
/* bits[14:13], Q element enable field */
- mode = ETM_MODE_QELEM(config->mode);
+ mode = ETM_MODE_QELEM(sysfs_config->mode);
/* start by clearing QE bits */
- config->cfg &= ~(TRCCONFIGR_QE_W_COUNTS | TRCCONFIGR_QE_WO_COUNTS);
+ sysfs_config->cfg &= ~(TRCCONFIGR_QE_W_COUNTS | TRCCONFIGR_QE_WO_COUNTS);
/*
* if supported, Q elements with instruction counts are enabled.
* Always set the low bit for any requested mode. Valid combos are
* 0b00, 0b01 and 0b11.
*/
if (mode && caps->q_support)
- config->cfg |= TRCCONFIGR_QE_W_COUNTS;
+ sysfs_config->cfg |= TRCCONFIGR_QE_W_COUNTS;
/*
* if supported, Q elements with and without instruction
* counts are enabled
*/
if ((mode & BIT(1)) && (caps->q_support & BIT(1)))
- config->cfg |= TRCCONFIGR_QE_WO_COUNTS;
+ sysfs_config->cfg |= TRCCONFIGR_QE_WO_COUNTS;
/* bit[11], AMBA Trace Bus (ATB) trigger enable bit */
- if ((config->mode & ETM_MODE_ATB_TRIGGER) && (caps->atbtrig))
- config->eventctrl1 |= TRCEVENTCTL1R_ATB;
+ if ((sysfs_config->mode & ETM_MODE_ATB_TRIGGER) && (caps->atbtrig))
+ sysfs_config->eventctrl1 |= TRCEVENTCTL1R_ATB;
else
- config->eventctrl1 &= ~TRCEVENTCTL1R_ATB;
+ sysfs_config->eventctrl1 &= ~TRCEVENTCTL1R_ATB;
/* bit[12], Low-power state behavior override bit */
- if ((config->mode & ETM_MODE_LPOVERRIDE) && (caps->lpoverride))
- config->eventctrl1 |= TRCEVENTCTL1R_LPOVERRIDE;
+ if ((sysfs_config->mode & ETM_MODE_LPOVERRIDE) && (caps->lpoverride))
+ sysfs_config->eventctrl1 |= TRCEVENTCTL1R_LPOVERRIDE;
else
- config->eventctrl1 &= ~TRCEVENTCTL1R_LPOVERRIDE;
+ sysfs_config->eventctrl1 &= ~TRCEVENTCTL1R_LPOVERRIDE;
/* bit[8], Instruction stall bit */
- if ((config->mode & ETM_MODE_ISTALL_EN) && (caps->stallctl))
- config->stall_ctrl |= TRCSTALLCTLR_ISTALL;
+ if ((sysfs_config->mode & ETM_MODE_ISTALL_EN) && (caps->stallctl))
+ sysfs_config->stall_ctrl |= TRCSTALLCTLR_ISTALL;
else
- config->stall_ctrl &= ~TRCSTALLCTLR_ISTALL;
+ sysfs_config->stall_ctrl &= ~TRCSTALLCTLR_ISTALL;
/* bit[10], Prioritize instruction trace bit */
- if (config->mode & ETM_MODE_INSTPRIO)
- config->stall_ctrl |= TRCSTALLCTLR_INSTPRIORITY;
+ if (sysfs_config->mode & ETM_MODE_INSTPRIO)
+ sysfs_config->stall_ctrl |= TRCSTALLCTLR_INSTPRIORITY;
else
- config->stall_ctrl &= ~TRCSTALLCTLR_INSTPRIORITY;
+ sysfs_config->stall_ctrl &= ~TRCSTALLCTLR_INSTPRIORITY;
/* bit[13], Trace overflow prevention bit */
- if ((config->mode & ETM_MODE_NOOVERFLOW) && (caps->nooverflow))
- config->stall_ctrl |= TRCSTALLCTLR_NOOVERFLOW;
+ if ((sysfs_config->mode & ETM_MODE_NOOVERFLOW) && (caps->nooverflow))
+ sysfs_config->stall_ctrl |= TRCSTALLCTLR_NOOVERFLOW;
else
- config->stall_ctrl &= ~TRCSTALLCTLR_NOOVERFLOW;
+ sysfs_config->stall_ctrl &= ~TRCSTALLCTLR_NOOVERFLOW;
/* bit[9] Start/stop logic control bit */
- if (config->mode & ETM_MODE_VIEWINST_STARTSTOP)
- config->vinst_ctrl |= TRCVICTLR_SSSTATUS;
+ if (sysfs_config->mode & ETM_MODE_VIEWINST_STARTSTOP)
+ sysfs_config->vinst_ctrl |= TRCVICTLR_SSSTATUS;
else
- config->vinst_ctrl &= ~TRCVICTLR_SSSTATUS;
+ sysfs_config->vinst_ctrl &= ~TRCVICTLR_SSSTATUS;
/* bit[10], Whether a trace unit must trace a Reset exception */
- if (config->mode & ETM_MODE_TRACE_RESET)
- config->vinst_ctrl |= TRCVICTLR_TRCRESET;
+ if (sysfs_config->mode & ETM_MODE_TRACE_RESET)
+ sysfs_config->vinst_ctrl |= TRCVICTLR_TRCRESET;
else
- config->vinst_ctrl &= ~TRCVICTLR_TRCRESET;
+ sysfs_config->vinst_ctrl &= ~TRCVICTLR_TRCRESET;
/* bit[11], Whether a trace unit must trace a system error exception */
- if ((config->mode & ETM_MODE_TRACE_ERR) && (caps->trc_error))
- config->vinst_ctrl |= TRCVICTLR_TRCERR;
+ if ((sysfs_config->mode & ETM_MODE_TRACE_ERR) && (caps->trc_error))
+ sysfs_config->vinst_ctrl |= TRCVICTLR_TRCERR;
else
- config->vinst_ctrl &= ~TRCVICTLR_TRCERR;
+ sysfs_config->vinst_ctrl &= ~TRCVICTLR_TRCERR;
- if (config->mode & (ETM_MODE_EXCL_KERN | ETM_MODE_EXCL_USER))
- etm4_config_trace_mode(config, caps);
+ if (sysfs_config->mode & (ETM_MODE_EXCL_KERN | ETM_MODE_EXCL_USER))
+ etm4_config_trace_mode(sysfs_config, caps);
raw_spin_unlock(&drvdata->spinlock);
@@ -457,9 +457,9 @@ static ssize_t pe_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- val = config->pe_sel;
+ val = sysfs_config->pe_sel;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -470,7 +470,7 @@ static ssize_t pe_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
@@ -481,7 +481,7 @@ static ssize_t pe_store(struct device *dev,
return -EINVAL;
}
- config->pe_sel = val;
+ sysfs_config->pe_sel = val;
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -493,9 +493,9 @@ static ssize_t event_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- val = config->eventctrl0;
+ val = sysfs_config->eventctrl0;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -506,7 +506,7 @@ static ssize_t event_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
@@ -515,19 +515,19 @@ static ssize_t event_store(struct device *dev,
switch (caps->nr_event) {
case 0x0:
/* EVENT0, bits[7:0] */
- config->eventctrl0 = val & 0xFF;
+ sysfs_config->eventctrl0 = val & 0xFF;
break;
case 0x1:
/* EVENT1, bits[15:8] */
- config->eventctrl0 = val & 0xFFFF;
+ sysfs_config->eventctrl0 = val & 0xFFFF;
break;
case 0x2:
/* EVENT2, bits[23:16] */
- config->eventctrl0 = val & 0xFFFFFF;
+ sysfs_config->eventctrl0 = val & 0xFFFFFF;
break;
case 0x3:
/* EVENT3, bits[31:24] */
- config->eventctrl0 = val;
+ sysfs_config->eventctrl0 = val;
break;
default:
break;
@@ -543,9 +543,9 @@ static ssize_t event_instren_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- val = FIELD_GET(TRCEVENTCTL1R_INSTEN_MASK, config->eventctrl1);
+ val = FIELD_GET(TRCEVENTCTL1R_INSTEN_MASK, sysfs_config->eventctrl1);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -556,32 +556,33 @@ static ssize_t event_instren_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
/* start by clearing all instruction event enable bits */
- config->eventctrl1 &= ~TRCEVENTCTL1R_INSTEN_MASK;
+ sysfs_config->eventctrl1 &= ~TRCEVENTCTL1R_INSTEN_MASK;
switch (caps->nr_event) {
case 0x0:
/* generate Event element for event 1 */
- config->eventctrl1 |= val & TRCEVENTCTL1R_INSTEN_1;
+ sysfs_config->eventctrl1 |= val & TRCEVENTCTL1R_INSTEN_1;
break;
case 0x1:
/* generate Event element for event 1 and 2 */
- config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 | TRCEVENTCTL1R_INSTEN_1);
+ sysfs_config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 |
+ TRCEVENTCTL1R_INSTEN_1);
break;
case 0x2:
/* generate Event element for event 1, 2 and 3 */
- config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 |
+ sysfs_config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 |
TRCEVENTCTL1R_INSTEN_1 |
TRCEVENTCTL1R_INSTEN_2);
break;
case 0x3:
/* generate Event element for all 4 events */
- config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 |
+ sysfs_config->eventctrl1 |= val & (TRCEVENTCTL1R_INSTEN_0 |
TRCEVENTCTL1R_INSTEN_1 |
TRCEVENTCTL1R_INSTEN_2 |
TRCEVENTCTL1R_INSTEN_3);
@@ -600,9 +601,9 @@ static ssize_t event_ts_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- val = config->ts_ctrl;
+ val = sysfs_config->ts_ctrl;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -613,14 +614,14 @@ static ssize_t event_ts_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
if (!caps->ts_size)
return -EINVAL;
- config->ts_ctrl = val & ETMv4_EVENT_MASK;
+ sysfs_config->ts_ctrl = val & ETMv4_EVENT_MASK;
return size;
}
static DEVICE_ATTR_RW(event_ts);
@@ -631,9 +632,9 @@ static ssize_t syncfreq_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- val = config->syncfreq;
+ val = sysfs_config->syncfreq;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -644,14 +645,14 @@ static ssize_t syncfreq_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
if (caps->syncpr)
return -EINVAL;
- config->syncfreq = val & ETMv4_SYNC_MASK;
+ sysfs_config->syncfreq = val & ETMv4_SYNC_MASK;
return size;
}
static DEVICE_ATTR_RW(syncfreq);
@@ -662,9 +663,9 @@ static ssize_t cyc_threshold_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- val = config->ccctlr;
+ val = sysfs_config->ccctlr;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -675,7 +676,7 @@ static ssize_t cyc_threshold_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
@@ -685,7 +686,7 @@ static ssize_t cyc_threshold_store(struct device *dev,
if (val < caps->ccitmin)
return -EINVAL;
- config->ccctlr = val;
+ sysfs_config->ccctlr = val;
return size;
}
static DEVICE_ATTR_RW(cyc_threshold);
@@ -696,9 +697,9 @@ static ssize_t bb_ctrl_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- val = config->bb_ctrl;
+ val = sysfs_config->bb_ctrl;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -709,7 +710,7 @@ static ssize_t bb_ctrl_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
@@ -726,7 +727,7 @@ static ssize_t bb_ctrl_store(struct device *dev,
if ((val & TRCBBCTLR_MODE) && (FIELD_GET(TRCBBCTLR_RANGE_MASK, val) == 0))
return -EINVAL;
- config->bb_ctrl = val & (TRCBBCTLR_MODE | TRCBBCTLR_RANGE_MASK);
+ sysfs_config->bb_ctrl = val & (TRCBBCTLR_MODE | TRCBBCTLR_RANGE_MASK);
return size;
}
static DEVICE_ATTR_RW(bb_ctrl);
@@ -737,9 +738,9 @@ static ssize_t event_vinst_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- val = FIELD_GET(TRCVICTLR_EVENT_MASK, config->vinst_ctrl);
+ val = FIELD_GET(TRCVICTLR_EVENT_MASK, sysfs_config->vinst_ctrl);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -749,15 +750,15 @@ static ssize_t event_vinst_store(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
val &= TRCVICTLR_EVENT_MASK >> __bf_shf(TRCVICTLR_EVENT_MASK);
- config->vinst_ctrl &= ~TRCVICTLR_EVENT_MASK;
- config->vinst_ctrl |= FIELD_PREP(TRCVICTLR_EVENT_MASK, val);
+ sysfs_config->vinst_ctrl &= ~TRCVICTLR_EVENT_MASK;
+ sysfs_config->vinst_ctrl |= FIELD_PREP(TRCVICTLR_EVENT_MASK, val);
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -769,9 +770,9 @@ static ssize_t s_exlevel_vinst_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- val = FIELD_GET(TRCVICTLR_EXLEVEL_S_MASK, config->vinst_ctrl);
+ val = FIELD_GET(TRCVICTLR_EXLEVEL_S_MASK, sysfs_config->vinst_ctrl);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -782,17 +783,17 @@ static ssize_t s_exlevel_vinst_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
/* clear all EXLEVEL_S bits */
- config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_S_MASK;
+ sysfs_config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_S_MASK;
/* enable instruction tracing for corresponding exception level */
val &= caps->s_ex_level;
- config->vinst_ctrl |= val << __bf_shf(TRCVICTLR_EXLEVEL_S_MASK);
+ sysfs_config->vinst_ctrl |= val << __bf_shf(TRCVICTLR_EXLEVEL_S_MASK);
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -804,10 +805,10 @@ static ssize_t ns_exlevel_vinst_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
/* EXLEVEL_NS, bits[23:20] */
- val = FIELD_GET(TRCVICTLR_EXLEVEL_NS_MASK, config->vinst_ctrl);
+ val = FIELD_GET(TRCVICTLR_EXLEVEL_NS_MASK, sysfs_config->vinst_ctrl);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -818,17 +819,17 @@ static ssize_t ns_exlevel_vinst_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
/* clear EXLEVEL_NS bits */
- config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_NS_MASK;
+ sysfs_config->vinst_ctrl &= ~TRCVICTLR_EXLEVEL_NS_MASK;
/* enable instruction tracing for corresponding exception level */
val &= caps->ns_ex_level;
- config->vinst_ctrl |= val << __bf_shf(TRCVICTLR_EXLEVEL_NS_MASK);
+ sysfs_config->vinst_ctrl |= val << __bf_shf(TRCVICTLR_EXLEVEL_NS_MASK);
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -840,9 +841,9 @@ static ssize_t addr_idx_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- val = config->addr_idx;
+ val = sysfs_config->addr_idx;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -853,7 +854,7 @@ static ssize_t addr_idx_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
@@ -865,7 +866,7 @@ static ssize_t addr_idx_store(struct device *dev,
* dereferenced multiple times within a spinlock block elsewhere.
*/
raw_spin_lock(&drvdata->spinlock);
- config->addr_idx = val;
+ sysfs_config->addr_idx = val;
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -878,11 +879,11 @@ static ssize_t addr_instdatatype_show(struct device *dev,
ssize_t len;
u8 val, idx;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
raw_spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
- val = FIELD_GET(TRCACATRn_TYPE_MASK, config->addr_acc[idx]);
+ idx = sysfs_config->addr_idx;
+ val = FIELD_GET(TRCACATRn_TYPE_MASK, sysfs_config->addr_acc[idx]);
len = scnprintf(buf, PAGE_SIZE, "%s\n",
val == TRCACATRn_TYPE_ADDR ? "instr" :
(val == TRCACATRn_TYPE_DATA_LOAD_ADDR ? "data_load" :
@@ -899,7 +900,7 @@ static ssize_t addr_instdatatype_store(struct device *dev,
u8 idx;
char str[20] = "";
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (strlen(buf) >= 20)
return -EINVAL;
@@ -907,10 +908,10 @@ static ssize_t addr_instdatatype_store(struct device *dev,
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
+ idx = sysfs_config->addr_idx;
if (!strcmp(str, "instr"))
/* TYPE, bits[1:0] */
- config->addr_acc[idx] &= ~TRCACATRn_TYPE_MASK;
+ sysfs_config->addr_acc[idx] &= ~TRCACATRn_TYPE_MASK;
raw_spin_unlock(&drvdata->spinlock);
return size;
@@ -924,16 +925,16 @@ static ssize_t addr_single_show(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- idx = config->addr_idx;
+ idx = sysfs_config->addr_idx;
raw_spin_lock(&drvdata->spinlock);
- if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
- config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
+ if (!(sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+ sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
raw_spin_unlock(&drvdata->spinlock);
return -EPERM;
}
- val = (unsigned long)config->addr_val[idx];
+ val = (unsigned long)sysfs_config->addr_val[idx];
raw_spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -945,21 +946,21 @@ static ssize_t addr_single_store(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
- if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
- config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
+ idx = sysfs_config->addr_idx;
+ if (!(sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+ sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
raw_spin_unlock(&drvdata->spinlock);
return -EPERM;
}
- config->addr_val[idx] = (u64)val;
- config->addr_type[idx] = ETM_ADDR_TYPE_SINGLE;
+ sysfs_config->addr_val[idx] = (u64)val;
+ sysfs_config->addr_type[idx] = ETM_ADDR_TYPE_SINGLE;
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -972,24 +973,24 @@ static ssize_t addr_range_show(struct device *dev,
u8 idx;
unsigned long val1, val2;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
raw_spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
+ idx = sysfs_config->addr_idx;
if (idx % 2 != 0) {
raw_spin_unlock(&drvdata->spinlock);
return -EPERM;
}
- if (!((config->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
- config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
- (config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
- config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
+ if (!((sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
+ sysfs_config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
+ (sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
+ sysfs_config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
raw_spin_unlock(&drvdata->spinlock);
return -EPERM;
}
- val1 = (unsigned long)config->addr_val[idx];
- val2 = (unsigned long)config->addr_val[idx + 1];
+ val1 = (unsigned long)sysfs_config->addr_val[idx];
+ val2 = (unsigned long)sysfs_config->addr_val[idx + 1];
raw_spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
}
@@ -1001,7 +1002,7 @@ static ssize_t addr_range_store(struct device *dev,
u8 idx;
unsigned long val1, val2;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
int elements, exclude;
elements = sscanf(buf, "%lx %lx %x", &val1, &val2, &exclude);
@@ -1014,31 +1015,31 @@ static ssize_t addr_range_store(struct device *dev,
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
+ idx = sysfs_config->addr_idx;
if (idx % 2 != 0) {
raw_spin_unlock(&drvdata->spinlock);
return -EPERM;
}
- if (!((config->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
- config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
- (config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
- config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
+ if (!((sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
+ sysfs_config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
+ (sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
+ sysfs_config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
raw_spin_unlock(&drvdata->spinlock);
return -EPERM;
}
- config->addr_val[idx] = (u64)val1;
- config->addr_type[idx] = ETM_ADDR_TYPE_RANGE;
- config->addr_val[idx + 1] = (u64)val2;
- config->addr_type[idx + 1] = ETM_ADDR_TYPE_RANGE;
+ sysfs_config->addr_val[idx] = (u64)val1;
+ sysfs_config->addr_type[idx] = ETM_ADDR_TYPE_RANGE;
+ sysfs_config->addr_val[idx + 1] = (u64)val2;
+ sysfs_config->addr_type[idx + 1] = ETM_ADDR_TYPE_RANGE;
/*
* Program include or exclude control bits for vinst or vdata
* whenever we change addr comparators to ETM_ADDR_TYPE_RANGE
* use supplied value, or default to bit set in 'mode'
*/
if (elements != 3)
- exclude = config->mode & ETM_MODE_EXCLUDE;
+ exclude = sysfs_config->mode & ETM_MODE_EXCLUDE;
etm4_set_mode_exclude(drvdata, exclude ? true : false);
raw_spin_unlock(&drvdata->spinlock);
@@ -1053,18 +1054,18 @@ static ssize_t addr_start_show(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
raw_spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
+ idx = sysfs_config->addr_idx;
- if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
- config->addr_type[idx] == ETM_ADDR_TYPE_START)) {
+ if (!(sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+ sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_START)) {
raw_spin_unlock(&drvdata->spinlock);
return -EPERM;
}
- val = (unsigned long)config->addr_val[idx];
+ val = (unsigned long)sysfs_config->addr_val[idx];
raw_spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1077,26 +1078,26 @@ static ssize_t addr_start_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
+ idx = sysfs_config->addr_idx;
if (!caps->nr_addr_cmp) {
raw_spin_unlock(&drvdata->spinlock);
return -EINVAL;
}
- if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
- config->addr_type[idx] == ETM_ADDR_TYPE_START)) {
+ if (!(sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+ sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_START)) {
raw_spin_unlock(&drvdata->spinlock);
return -EPERM;
}
- config->addr_val[idx] = (u64)val;
- config->addr_type[idx] = ETM_ADDR_TYPE_START;
- config->vissctlr |= BIT(idx);
+ sysfs_config->addr_val[idx] = (u64)val;
+ sysfs_config->addr_type[idx] = ETM_ADDR_TYPE_START;
+ sysfs_config->vissctlr |= BIT(idx);
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -1109,18 +1110,18 @@ static ssize_t addr_stop_show(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
raw_spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
+ idx = sysfs_config->addr_idx;
- if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
- config->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
+ if (!(sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+ sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
raw_spin_unlock(&drvdata->spinlock);
return -EPERM;
}
- val = (unsigned long)config->addr_val[idx];
+ val = (unsigned long)sysfs_config->addr_val[idx];
raw_spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1133,26 +1134,26 @@ static ssize_t addr_stop_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
+ idx = sysfs_config->addr_idx;
if (!caps->nr_addr_cmp) {
raw_spin_unlock(&drvdata->spinlock);
return -EINVAL;
}
- if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
- config->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
+ if (!(sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+ sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
raw_spin_unlock(&drvdata->spinlock);
return -EPERM;
}
- config->addr_val[idx] = (u64)val;
- config->addr_type[idx] = ETM_ADDR_TYPE_STOP;
- config->vissctlr |= BIT(idx + 16);
+ sysfs_config->addr_val[idx] = (u64)val;
+ sysfs_config->addr_type[idx] = ETM_ADDR_TYPE_STOP;
+ sysfs_config->vissctlr |= BIT(idx + 16);
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -1165,12 +1166,12 @@ static ssize_t addr_ctxtype_show(struct device *dev,
ssize_t len;
u8 idx, val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
raw_spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
+ idx = sysfs_config->addr_idx;
/* CONTEXTTYPE, bits[3:2] */
- val = FIELD_GET(TRCACATRn_CONTEXTTYPE_MASK, config->addr_acc[idx]);
+ val = FIELD_GET(TRCACATRn_CONTEXTTYPE_MASK, sysfs_config->addr_acc[idx]);
len = scnprintf(buf, PAGE_SIZE, "%s\n", val == ETM_CTX_NONE ? "none" :
(val == ETM_CTX_CTXID ? "ctxid" :
(val == ETM_CTX_VMID ? "vmid" : "all")));
@@ -1186,7 +1187,7 @@ static ssize_t addr_ctxtype_store(struct device *dev,
char str[10] = "";
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (strlen(buf) >= 10)
return -EINVAL;
@@ -1194,21 +1195,21 @@ static ssize_t addr_ctxtype_store(struct device *dev,
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
+ idx = sysfs_config->addr_idx;
if (!strcmp(str, "none"))
/* start by clearing context type bits */
- config->addr_acc[idx] &= ~TRCACATRn_CONTEXTTYPE_MASK;
+ sysfs_config->addr_acc[idx] &= ~TRCACATRn_CONTEXTTYPE_MASK;
else if (!strcmp(str, "ctxid")) {
/* 0b01 The trace unit performs a Context ID */
if (caps->numcidc) {
- config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_CTXID;
- config->addr_acc[idx] &= ~TRCACATRn_CONTEXTTYPE_VMID;
+ sysfs_config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_CTXID;
+ sysfs_config->addr_acc[idx] &= ~TRCACATRn_CONTEXTTYPE_VMID;
}
} else if (!strcmp(str, "vmid")) {
/* 0b10 The trace unit performs a VMID */
if (caps->numvmidc) {
- config->addr_acc[idx] &= ~TRCACATRn_CONTEXTTYPE_CTXID;
- config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_VMID;
+ sysfs_config->addr_acc[idx] &= ~TRCACATRn_CONTEXTTYPE_CTXID;
+ sysfs_config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_VMID;
}
} else if (!strcmp(str, "all")) {
/*
@@ -1216,9 +1217,9 @@ static ssize_t addr_ctxtype_store(struct device *dev,
* comparison and a VMID
*/
if (caps->numcidc)
- config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_CTXID;
+ sysfs_config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_CTXID;
if (caps->numvmidc)
- config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_VMID;
+ sysfs_config->addr_acc[idx] |= TRCACATRn_CONTEXTTYPE_VMID;
}
raw_spin_unlock(&drvdata->spinlock);
return size;
@@ -1232,12 +1233,12 @@ static ssize_t addr_context_show(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
raw_spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
+ idx = sysfs_config->addr_idx;
/* context ID comparator bits[6:4] */
- val = FIELD_GET(TRCACATRn_CONTEXT_MASK, config->addr_acc[idx]);
+ val = FIELD_GET(TRCACATRn_CONTEXT_MASK, sysfs_config->addr_acc[idx]);
raw_spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1250,7 +1251,7 @@ static ssize_t addr_context_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
@@ -1261,10 +1262,10 @@ static ssize_t addr_context_store(struct device *dev,
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
+ idx = sysfs_config->addr_idx;
/* clear context ID comparator bits[6:4] */
- config->addr_acc[idx] &= ~TRCACATRn_CONTEXT_MASK;
- config->addr_acc[idx] |= val << __bf_shf(TRCACATRn_CONTEXT_MASK);
+ sysfs_config->addr_acc[idx] &= ~TRCACATRn_CONTEXT_MASK;
+ sysfs_config->addr_acc[idx] |= val << __bf_shf(TRCACATRn_CONTEXT_MASK);
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -1277,11 +1278,11 @@ static ssize_t addr_exlevel_s_ns_show(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
raw_spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
- val = FIELD_GET(TRCACATRn_EXLEVEL_MASK, config->addr_acc[idx]);
+ idx = sysfs_config->addr_idx;
+ val = FIELD_GET(TRCACATRn_EXLEVEL_MASK, sysfs_config->addr_acc[idx]);
raw_spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1293,7 +1294,7 @@ static ssize_t addr_exlevel_s_ns_store(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 0, &val))
return -EINVAL;
@@ -1302,10 +1303,10 @@ static ssize_t addr_exlevel_s_ns_store(struct device *dev,
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
+ idx = sysfs_config->addr_idx;
/* clear Exlevel_ns & Exlevel_s bits[14:12, 11:8], bit[15] is res0 */
- config->addr_acc[idx] &= ~TRCACATRn_EXLEVEL_MASK;
- config->addr_acc[idx] |= val << __bf_shf(TRCACATRn_EXLEVEL_MASK);
+ sysfs_config->addr_acc[idx] &= ~TRCACATRn_EXLEVEL_MASK;
+ sysfs_config->addr_acc[idx] |= val << __bf_shf(TRCACATRn_EXLEVEL_MASK);
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -1325,24 +1326,24 @@ static ssize_t addr_cmp_view_show(struct device *dev,
u8 idx, addr_type;
unsigned long addr_v, addr_v2, addr_ctrl;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
int size = 0;
bool exclude = false;
raw_spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
- addr_v = config->addr_val[idx];
- addr_ctrl = config->addr_acc[idx];
- addr_type = config->addr_type[idx];
+ idx = sysfs_config->addr_idx;
+ addr_v = sysfs_config->addr_val[idx];
+ addr_ctrl = sysfs_config->addr_acc[idx];
+ addr_type = sysfs_config->addr_type[idx];
if (addr_type == ETM_ADDR_TYPE_RANGE) {
if (idx & 0x1) {
idx -= 1;
addr_v2 = addr_v;
- addr_v = config->addr_val[idx];
+ addr_v = sysfs_config->addr_val[idx];
} else {
- addr_v2 = config->addr_val[idx + 1];
+ addr_v2 = sysfs_config->addr_val[idx + 1];
}
- exclude = config->viiectlr & BIT(idx / 2 + 16);
+ exclude = sysfs_config->viiectlr & BIT(idx / 2 + 16);
}
raw_spin_unlock(&drvdata->spinlock);
if (addr_type) {
@@ -1369,11 +1370,11 @@ static ssize_t vinst_pe_cmp_start_stop_show(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (!caps->nr_pe_cmp)
return -EINVAL;
- val = config->vipcssctlr;
+ val = sysfs_config->vipcssctlr;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
static ssize_t vinst_pe_cmp_start_stop_store(struct device *dev,
@@ -1383,7 +1384,7 @@ static ssize_t vinst_pe_cmp_start_stop_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
@@ -1391,7 +1392,7 @@ static ssize_t vinst_pe_cmp_start_stop_store(struct device *dev,
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- config->vipcssctlr = val;
+ sysfs_config->vipcssctlr = val;
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -1403,9 +1404,9 @@ static ssize_t seq_idx_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- val = config->seq_idx;
+ val = sysfs_config->seq_idx;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1416,7 +1417,7 @@ static ssize_t seq_idx_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (!caps->nr_seq_ctrls)
return -ENOTSUPP;
@@ -1430,7 +1431,7 @@ static ssize_t seq_idx_store(struct device *dev,
* dereferenced multiple times within a spinlock block elsewhere.
*/
raw_spin_lock(&drvdata->spinlock);
- config->seq_idx = val;
+ sysfs_config->seq_idx = val;
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -1442,9 +1443,9 @@ static ssize_t seq_state_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- val = config->seq_state;
+ val = sysfs_config->seq_state;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1455,7 +1456,7 @@ static ssize_t seq_state_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
@@ -1465,7 +1466,7 @@ static ssize_t seq_state_store(struct device *dev,
coresight_get_mode(drvdata->csdev) == CS_MODE_SYSFS)
return -EBUSY;
- config->seq_state = val;
+ sysfs_config->seq_state = val;
return size;
}
static DEVICE_ATTR_RW(seq_state);
@@ -1477,11 +1478,11 @@ static ssize_t seq_event_show(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
raw_spin_lock(&drvdata->spinlock);
- idx = config->seq_idx;
- val = config->seq_ctrl[idx];
+ idx = sysfs_config->seq_idx;
+ val = sysfs_config->seq_ctrl[idx];
raw_spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1493,15 +1494,15 @@ static ssize_t seq_event_store(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- idx = config->seq_idx;
+ idx = sysfs_config->seq_idx;
/* Seq control has two masks B[15:8] F[7:0] */
- config->seq_ctrl[idx] = val & 0xFFFF;
+ sysfs_config->seq_ctrl[idx] = val & 0xFFFF;
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -1513,9 +1514,9 @@ static ssize_t seq_reset_event_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- val = config->seq_rst;
+ val = sysfs_config->seq_rst;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1526,14 +1527,14 @@ static ssize_t seq_reset_event_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
if (!(caps->nrseqstate))
return -EINVAL;
- config->seq_rst = val & ETMv4_EVENT_MASK;
+ sysfs_config->seq_rst = val & ETMv4_EVENT_MASK;
return size;
}
static DEVICE_ATTR_RW(seq_reset_event);
@@ -1544,9 +1545,9 @@ static ssize_t cntr_idx_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- val = config->cntr_idx;
+ val = sysfs_config->cntr_idx;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1557,7 +1558,7 @@ static ssize_t cntr_idx_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
@@ -1569,7 +1570,7 @@ static ssize_t cntr_idx_store(struct device *dev,
* dereferenced multiple times within a spinlock block elsewhere.
*/
raw_spin_lock(&drvdata->spinlock);
- config->cntr_idx = val;
+ sysfs_config->cntr_idx = val;
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -1582,11 +1583,11 @@ static ssize_t cntrldvr_show(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
raw_spin_lock(&drvdata->spinlock);
- idx = config->cntr_idx;
- val = config->cntrldvr[idx];
+ idx = sysfs_config->cntr_idx;
+ val = sysfs_config->cntrldvr[idx];
raw_spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1598,7 +1599,7 @@ static ssize_t cntrldvr_store(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
@@ -1606,8 +1607,8 @@ static ssize_t cntrldvr_store(struct device *dev,
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- idx = config->cntr_idx;
- config->cntrldvr[idx] = val;
+ idx = sysfs_config->cntr_idx;
+ sysfs_config->cntrldvr[idx] = val;
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -1620,11 +1621,11 @@ static ssize_t cntr_val_show(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
raw_spin_lock(&drvdata->spinlock);
- idx = config->cntr_idx;
- val = config->cntr_val[idx];
+ idx = sysfs_config->cntr_idx;
+ val = sysfs_config->cntr_val[idx];
raw_spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1636,7 +1637,7 @@ static ssize_t cntr_val_store(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
@@ -1647,8 +1648,8 @@ static ssize_t cntr_val_store(struct device *dev,
return -EBUSY;
raw_spin_lock(&drvdata->spinlock);
- idx = config->cntr_idx;
- config->cntr_val[idx] = val;
+ idx = sysfs_config->cntr_idx;
+ sysfs_config->cntr_val[idx] = val;
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -1661,11 +1662,11 @@ static ssize_t cntr_ctrl_show(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
raw_spin_lock(&drvdata->spinlock);
- idx = config->cntr_idx;
- val = config->cntr_ctrl[idx];
+ idx = sysfs_config->cntr_idx;
+ val = sysfs_config->cntr_ctrl[idx];
raw_spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1677,14 +1678,14 @@ static ssize_t cntr_ctrl_store(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- idx = config->cntr_idx;
- config->cntr_ctrl[idx] = val;
+ idx = sysfs_config->cntr_idx;
+ sysfs_config->cntr_ctrl[idx] = val;
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -1696,9 +1697,9 @@ static ssize_t res_idx_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- val = config->res_idx;
+ val = sysfs_config->res_idx;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1709,7 +1710,7 @@ static ssize_t res_idx_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
@@ -1725,7 +1726,7 @@ static ssize_t res_idx_store(struct device *dev,
* dereferenced multiple times within a spinlock block elsewhere.
*/
raw_spin_lock(&drvdata->spinlock);
- config->res_idx = val;
+ sysfs_config->res_idx = val;
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -1738,11 +1739,11 @@ static ssize_t res_ctrl_show(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
raw_spin_lock(&drvdata->spinlock);
- idx = config->res_idx;
- val = config->res_ctrl[idx];
+ idx = sysfs_config->res_idx;
+ val = sysfs_config->res_ctrl[idx];
raw_spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1754,18 +1755,18 @@ static ssize_t res_ctrl_store(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- idx = config->res_idx;
+ idx = sysfs_config->res_idx;
/* For odd idx pair inversal bit is RES0 */
if (idx % 2 != 0)
/* PAIRINV, bit[21] */
val &= ~TRCRSCTLRn_PAIRINV;
- config->res_ctrl[idx] = val & (TRCRSCTLRn_PAIRINV |
+ sysfs_config->res_ctrl[idx] = val & (TRCRSCTLRn_PAIRINV |
TRCRSCTLRn_INV |
TRCRSCTLRn_GROUP_MASK |
TRCRSCTLRn_SELECT_MASK);
@@ -1779,9 +1780,9 @@ static ssize_t sshot_idx_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- val = config->ss_idx;
+ val = sysfs_config->ss_idx;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1792,7 +1793,7 @@ static ssize_t sshot_idx_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
@@ -1800,7 +1801,7 @@ static ssize_t sshot_idx_store(struct device *dev,
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- config->ss_idx = val;
+ sysfs_config->ss_idx = val;
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -1812,10 +1813,10 @@ static ssize_t sshot_ctrl_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
raw_spin_lock(&drvdata->spinlock);
- val = config->ss_ctrl[config->ss_idx];
+ val = sysfs_config->ss_ctrl[sysfs_config->ss_idx];
raw_spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1827,14 +1828,14 @@ static ssize_t sshot_ctrl_store(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- idx = config->ss_idx;
- config->ss_ctrl[idx] = FIELD_PREP(TRCSSCCRn_SAC_ARC_RST_MASK, val);
+ idx = sysfs_config->ss_idx;
+ sysfs_config->ss_ctrl[idx] = FIELD_PREP(TRCSSCCRn_SAC_ARC_RST_MASK, val);
/* must clear bit 31 and 30 in related status register on programming */
drvdata->ss_status[idx] &= ~(TRCSSCSRn_STATUS | TRCSSCSRn_PENDING);
raw_spin_unlock(&drvdata->spinlock);
@@ -1847,10 +1848,10 @@ static ssize_t sshot_status_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
raw_spin_lock(&drvdata->spinlock);
- val = drvdata->ss_status[config->ss_idx];
+ val = drvdata->ss_status[sysfs_config->ss_idx];
raw_spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1862,10 +1863,10 @@ static ssize_t sshot_pe_ctrl_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
raw_spin_lock(&drvdata->spinlock);
- val = config->ss_pe_cmp[config->ss_idx];
+ val = sysfs_config->ss_pe_cmp[sysfs_config->ss_idx];
raw_spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1877,14 +1878,14 @@ static ssize_t sshot_pe_ctrl_store(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- idx = config->ss_idx;
- config->ss_pe_cmp[idx] = FIELD_PREP(TRCSSPCICRn_PC_MASK, val);
+ idx = sysfs_config->ss_idx;
+ sysfs_config->ss_pe_cmp[idx] = FIELD_PREP(TRCSSPCICRn_PC_MASK, val);
/* must clear bit 31 and 30 in related status register on programming */
drvdata->ss_status[idx] &= ~(TRCSSCSRn_STATUS | TRCSSCSRn_PENDING);
raw_spin_unlock(&drvdata->spinlock);
@@ -1898,9 +1899,9 @@ static ssize_t ctxid_idx_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- val = config->ctxid_idx;
+ val = sysfs_config->ctxid_idx;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1911,7 +1912,7 @@ static ssize_t ctxid_idx_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
@@ -1923,7 +1924,7 @@ static ssize_t ctxid_idx_store(struct device *dev,
* dereferenced multiple times within a spinlock block elsewhere.
*/
raw_spin_lock(&drvdata->spinlock);
- config->ctxid_idx = val;
+ sysfs_config->ctxid_idx = val;
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -1936,7 +1937,7 @@ static ssize_t ctxid_pid_show(struct device *dev,
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
/*
* Don't use contextID tracing if coming from a PID namespace. See
@@ -1946,8 +1947,8 @@ static ssize_t ctxid_pid_show(struct device *dev,
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- idx = config->ctxid_idx;
- val = (unsigned long)config->ctxid_pid[idx];
+ idx = sysfs_config->ctxid_idx;
+ val = (unsigned long)sysfs_config->ctxid_pid[idx];
raw_spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -1960,7 +1961,7 @@ static ssize_t ctxid_pid_store(struct device *dev,
unsigned long pid;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
/*
* When contextID tracing is enabled the tracers will insert the
@@ -1985,8 +1986,8 @@ static ssize_t ctxid_pid_store(struct device *dev,
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- idx = config->ctxid_idx;
- config->ctxid_pid[idx] = (u64)pid;
+ idx = sysfs_config->ctxid_idx;
+ sysfs_config->ctxid_pid[idx] = (u64)pid;
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -1998,7 +1999,7 @@ static ssize_t ctxid_masks_show(struct device *dev,
{
unsigned long val1, val2;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
/*
* Don't use contextID tracing if coming from a PID namespace. See
@@ -2008,8 +2009,8 @@ static ssize_t ctxid_masks_show(struct device *dev,
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- val1 = config->ctxid_mask0;
- val2 = config->ctxid_mask1;
+ val1 = sysfs_config->ctxid_mask0;
+ val2 = sysfs_config->ctxid_mask1;
raw_spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
}
@@ -2022,7 +2023,7 @@ static ssize_t ctxid_masks_store(struct device *dev,
unsigned long val1, val2, mask;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
int nr_inputs;
/*
@@ -2052,39 +2053,39 @@ static ssize_t ctxid_masks_store(struct device *dev,
switch (caps->numcidc) {
case 0x1:
/* COMP0, bits[7:0] */
- config->ctxid_mask0 = val1 & 0xFF;
+ sysfs_config->ctxid_mask0 = val1 & 0xFF;
break;
case 0x2:
/* COMP1, bits[15:8] */
- config->ctxid_mask0 = val1 & 0xFFFF;
+ sysfs_config->ctxid_mask0 = val1 & 0xFFFF;
break;
case 0x3:
/* COMP2, bits[23:16] */
- config->ctxid_mask0 = val1 & 0xFFFFFF;
+ sysfs_config->ctxid_mask0 = val1 & 0xFFFFFF;
break;
case 0x4:
/* COMP3, bits[31:24] */
- config->ctxid_mask0 = val1;
+ sysfs_config->ctxid_mask0 = val1;
break;
case 0x5:
/* COMP4, bits[7:0] */
- config->ctxid_mask0 = val1;
- config->ctxid_mask1 = val2 & 0xFF;
+ sysfs_config->ctxid_mask0 = val1;
+ sysfs_config->ctxid_mask1 = val2 & 0xFF;
break;
case 0x6:
/* COMP5, bits[15:8] */
- config->ctxid_mask0 = val1;
- config->ctxid_mask1 = val2 & 0xFFFF;
+ sysfs_config->ctxid_mask0 = val1;
+ sysfs_config->ctxid_mask1 = val2 & 0xFFFF;
break;
case 0x7:
/* COMP6, bits[23:16] */
- config->ctxid_mask0 = val1;
- config->ctxid_mask1 = val2 & 0xFFFFFF;
+ sysfs_config->ctxid_mask0 = val1;
+ sysfs_config->ctxid_mask1 = val2 & 0xFFFFFF;
break;
case 0x8:
/* COMP7, bits[31:24] */
- config->ctxid_mask0 = val1;
- config->ctxid_mask1 = val2;
+ sysfs_config->ctxid_mask0 = val1;
+ sysfs_config->ctxid_mask1 = val2;
break;
default:
break;
@@ -2095,7 +2096,7 @@ static ssize_t ctxid_masks_store(struct device *dev,
* For example, if bit[3] of ctxid_mask0 is 1, we must clear bits[31:24]
* of ctxid comparator0 value (corresponding to byte 0) register.
*/
- mask = config->ctxid_mask0;
+ mask = sysfs_config->ctxid_mask0;
for (i = 0; i < caps->numcidc; i++) {
/* mask value of corresponding ctxid comparator */
maskbyte = mask & ETMv4_EVENT_MASK;
@@ -2105,13 +2106,13 @@ static ssize_t ctxid_masks_store(struct device *dev,
*/
for (j = 0; j < 8; j++) {
if (maskbyte & 1)
- config->ctxid_pid[i] &= ~(0xFFUL << (j * 8));
+ sysfs_config->ctxid_pid[i] &= ~(0xFFUL << (j * 8));
maskbyte >>= 1;
}
/* Select the next ctxid comparator mask value */
if (i == 3)
/* ctxid comparators[4-7] */
- mask = config->ctxid_mask1;
+ mask = sysfs_config->ctxid_mask1;
else
mask >>= 0x8;
}
@@ -2127,9 +2128,9 @@ static ssize_t vmid_idx_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
- val = config->vmid_idx;
+ val = sysfs_config->vmid_idx;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -2140,7 +2141,7 @@ static ssize_t vmid_idx_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
@@ -2152,7 +2153,7 @@ static ssize_t vmid_idx_store(struct device *dev,
* dereferenced multiple times within a spinlock block elsewhere.
*/
raw_spin_lock(&drvdata->spinlock);
- config->vmid_idx = val;
+ sysfs_config->vmid_idx = val;
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -2164,7 +2165,7 @@ static ssize_t vmid_val_show(struct device *dev,
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
/*
* Don't use virtual contextID tracing if coming from a PID namespace.
@@ -2174,7 +2175,7 @@ static ssize_t vmid_val_show(struct device *dev,
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- val = (unsigned long)config->vmid_val[config->vmid_idx];
+ val = (unsigned long)sysfs_config->vmid_val[sysfs_config->vmid_idx];
raw_spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
@@ -2186,7 +2187,7 @@ static ssize_t vmid_val_store(struct device *dev,
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
/*
* Don't use virtual contextID tracing if coming from a PID namespace.
@@ -2205,7 +2206,7 @@ static ssize_t vmid_val_store(struct device *dev,
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- config->vmid_val[config->vmid_idx] = (u64)val;
+ sysfs_config->vmid_val[sysfs_config->vmid_idx] = (u64)val;
raw_spin_unlock(&drvdata->spinlock);
return size;
}
@@ -2216,7 +2217,7 @@ static ssize_t vmid_masks_show(struct device *dev,
{
unsigned long val1, val2;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
/*
* Don't use virtual contextID tracing if coming from a PID namespace.
@@ -2226,8 +2227,8 @@ static ssize_t vmid_masks_show(struct device *dev,
return -EINVAL;
raw_spin_lock(&drvdata->spinlock);
- val1 = config->vmid_mask0;
- val2 = config->vmid_mask1;
+ val1 = sysfs_config->vmid_mask0;
+ val2 = sysfs_config->vmid_mask1;
raw_spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
}
@@ -2240,7 +2241,7 @@ static ssize_t vmid_masks_store(struct device *dev,
unsigned long val1, val2, mask;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etmv4_caps *caps = &drvdata->caps;
- struct etmv4_config *config = &drvdata->config;
+ struct etmv4_config *sysfs_config = &drvdata->sysfs_config;
int nr_inputs;
/*
@@ -2270,39 +2271,39 @@ static ssize_t vmid_masks_store(struct device *dev,
switch (caps->numvmidc) {
case 0x1:
/* COMP0, bits[7:0] */
- config->vmid_mask0 = val1 & 0xFF;
+ sysfs_config->vmid_mask0 = val1 & 0xFF;
break;
case 0x2:
/* COMP1, bits[15:8] */
- config->vmid_mask0 = val1 & 0xFFFF;
+ sysfs_config->vmid_mask0 = val1 & 0xFFFF;
break;
case 0x3:
/* COMP2, bits[23:16] */
- config->vmid_mask0 = val1 & 0xFFFFFF;
+ sysfs_config->vmid_mask0 = val1 & 0xFFFFFF;
break;
case 0x4:
/* COMP3, bits[31:24] */
- config->vmid_mask0 = val1;
+ sysfs_config->vmid_mask0 = val1;
break;
case 0x5:
/* COMP4, bits[7:0] */
- config->vmid_mask0 = val1;
- config->vmid_mask1 = val2 & 0xFF;
+ sysfs_config->vmid_mask0 = val1;
+ sysfs_config->vmid_mask1 = val2 & 0xFF;
break;
case 0x6:
/* COMP5, bits[15:8] */
- config->vmid_mask0 = val1;
- config->vmid_mask1 = val2 & 0xFFFF;
+ sysfs_config->vmid_mask0 = val1;
+ sysfs_config->vmid_mask1 = val2 & 0xFFFF;
break;
case 0x7:
/* COMP6, bits[23:16] */
- config->vmid_mask0 = val1;
- config->vmid_mask1 = val2 & 0xFFFFFF;
+ sysfs_config->vmid_mask0 = val1;
+ sysfs_config->vmid_mask1 = val2 & 0xFFFFFF;
break;
case 0x8:
/* COMP7, bits[31:24] */
- config->vmid_mask0 = val1;
- config->vmid_mask1 = val2;
+ sysfs_config->vmid_mask0 = val1;
+ sysfs_config->vmid_mask1 = val2;
break;
default:
break;
@@ -2314,7 +2315,7 @@ static ssize_t vmid_masks_store(struct device *dev,
* For example, if bit[3] of vmid_mask0 is 1, we must clear bits[31:24]
* of vmid comparator0 value (corresponding to byte 0) register.
*/
- mask = config->vmid_mask0;
+ mask = sysfs_config->vmid_mask0;
for (i = 0; i < caps->numvmidc; i++) {
/* mask value of corresponding vmid comparator */
maskbyte = mask & ETMv4_EVENT_MASK;
@@ -2324,13 +2325,13 @@ static ssize_t vmid_masks_store(struct device *dev,
*/
for (j = 0; j < 8; j++) {
if (maskbyte & 1)
- config->vmid_val[i] &= ~(0xFFUL << (j * 8));
+ sysfs_config->vmid_val[i] &= ~(0xFFUL << (j * 8));
maskbyte >>= 1;
}
/* Select the next vmid comparator mask value */
if (i == 3)
/* vmid comparators[4-7] */
- mask = config->vmid_mask1;
+ mask = sysfs_config->vmid_mask1;
else
mask >>= 0x8;
}
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
index ae97c5c004bf..5417280cdb27 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.h
+++ b/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -1070,7 +1070,7 @@ struct etmv4_save_state {
* at runtime, due to the additional setting of TRFCR_CX when
* in EL2. Otherwise, 0.
* @curr_config: structure holding current applied configuration.
- * @config: structure holding sysfs mode configuration.
+ * @sysfs_config: structure holding sysfs mode configuration.
* @save_state: State to be preserved across power loss
* @paused: Indicates if the trace unit is paused.
* @ss_status: The status of the corresponding single-shot comparator.
@@ -1092,7 +1092,7 @@ struct etmv4_drvdata {
bool paused : 1;
u64 trfcr;
struct etmv4_config curr_config;
- struct etmv4_config config;
+ struct etmv4_config sysfs_config;
struct etmv4_save_state *save_state;
u32 ss_status[ETM_MAX_SS_CMP];
DECLARE_BITMAP(arch_features, ETM4_IMPDEF_FEATURE_MAX);
--
2.43.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v12 12/14] coresight: etm3x: introduce struct etm_caps
2026-09-24 17:33 [PATCH v12 00/14] fix several inconsistencies with sysfs configuration in etmX Yeoreum Yun
` (10 preceding siblings ...)
2026-09-24 17:33 ` [PATCH v12 11/14] coresight: etm4x: rename drvdata->config to sysfs_config Yeoreum Yun
@ 2026-09-24 17:33 ` Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 13/14] coresight: etm3x: rename local config as curr_config referring drvdata->curr_config Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 14/14] coresight: etm3x: rename drvdata->config to sysfs_config Yeoreum Yun
13 siblings, 0 replies; 19+ messages in thread
From: Yeoreum Yun @ 2026-09-24 17:33 UTC (permalink / raw)
To: Mike Leach, James Clark, Leo Yan, Greg Kroah-Hartman,
Mathieu Poirier, coresight, linux-arm-kernel, linux-kernel,
linux-rt-devel
Cc: Suzuki K Poulose, Alexander Shishkin, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, Yeoreum Yun
Introduce struct etm_caps to describe ETMv3 capabilities
and move capabilities information into it.
Since drvdata->etmccr and drvdata->etmccer are used to check
whether it supports fifofull logic and timestamping,
remove etmccr and etmccer field from drvdata and add relevant fields
in etm_caps structure.
Reviewed-by: Mike Leach <mike.leach@arm.com>
Tested-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
drivers/hwtracing/coresight/coresight-etm.h | 42 +++++++++++++---------
drivers/hwtracing/coresight/coresight-etm3x-core.c | 42 +++++++++++++---------
.../hwtracing/coresight/coresight-etm3x-sysfs.c | 24 ++++++++-----
3 files changed, 66 insertions(+), 42 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm.h b/drivers/hwtracing/coresight/coresight-etm.h
index 52f23a3c7364..560a58a3817c 100644
--- a/drivers/hwtracing/coresight/coresight-etm.h
+++ b/drivers/hwtracing/coresight/coresight-etm.h
@@ -140,6 +140,30 @@
ETM_ADD_COMP_0 | \
ETM_EVENT_NOT_A)
+/**
+ * struct etm_caps - specifics ETM capabilities
+ * @port_size: port size as reported by ETMCR bit 4-6 and 21.
+ * @nr_addr_cmp:Number of pairs of address comparators as found in ETMCCR.
+ * @nr_cntr: Number of counters as found in ETMCCR bit 13-15.
+ * @nr_ext_inp: Number of external input as found in ETMCCR bit 17-19.
+ * @nr_ext_out: Number of external output as found in ETMCCR bit 20-22.
+ * @nr_ctxid_cmp: Number of contextID comparators as found in ETMCCR bit 24-25.
+ * @fifofull: FIFOFULL logic is present.
+ * @timestamp: Timestamping is implemented.
+ * @retstack: Return stack is implemented.
+ */
+struct etm_caps {
+ int port_size;
+ u8 nr_addr_cmp;
+ u8 nr_cntr;
+ u8 nr_ext_inp;
+ u8 nr_ext_out;
+ u8 nr_ctxid_cmp;
+ bool fifofull : 1;
+ bool timestamp : 1;
+ bool retstack : 1;
+};
+
/**
* struct etm_config - configuration information related to an ETM
* @mode: controls various modes supported by this ETM/PTM.
@@ -212,19 +236,12 @@ struct etm_config {
* @csdev: component vitals needed by the framework.
* @spinlock: only one at a time pls.
* @cpu: the cpu this component is affined to.
- * @port_size: port size as reported by ETMCR bit 4-6 and 21.
* @arch: ETM/PTM version number.
+ * @caps: ETM capabilities.
* @use_cpu14: true if management registers need to be accessed via CP14.
* @sticky_enable: true if ETM base configuration has been done.
* @boot_enable:true if we should start tracing at boot time.
* @os_unlock: true if access to management registers is allowed.
- * @nr_addr_cmp:Number of pairs of address comparators as found in ETMCCR.
- * @nr_cntr: Number of counters as found in ETMCCR bit 13-15.
- * @nr_ext_inp: Number of external input as found in ETMCCR bit 17-19.
- * @nr_ext_out: Number of external output as found in ETMCCR bit 20-22.
- * @nr_ctxid_cmp: Number of contextID comparators as found in ETMCCR bit 24-25.
- * @etmccr: value of register ETMCCR.
- * @etmccer: value of register ETMCCER.
* @traceid: value of the current ID for this component.
* @curr_config: structure holding current running configuration.
* @config: structure holding sysfs mode configuration.
@@ -235,19 +252,12 @@ struct etm_drvdata {
struct coresight_device *csdev;
spinlock_t spinlock;
int cpu;
- int port_size;
u8 arch;
+ struct etm_caps caps;
bool use_cp14;
bool sticky_enable;
bool boot_enable;
bool os_unlock;
- u8 nr_addr_cmp;
- u8 nr_cntr;
- u8 nr_ext_inp;
- u8 nr_ext_out;
- u8 nr_ctxid_cmp;
- u32 etmccr;
- u32 etmccer;
u32 traceid;
struct etm_config curr_config;
struct etm_config config;
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
index ac7c154720cb..ca2ba179b6fb 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
@@ -308,6 +308,7 @@ void etm_config_trace_mode(struct etm_config *config)
static int etm_parse_event_config(struct etm_drvdata *drvdata,
struct perf_event *event)
{
+ const struct etm_caps *caps = &drvdata->caps;
struct etm_config *config = &drvdata->curr_config;
struct perf_event_attr *attr = &event->attr;
u8 ts_level;
@@ -356,8 +357,7 @@ static int etm_parse_event_config(struct etm_drvdata *drvdata,
* has ret stack) on the same SoC. So only enable when it can be honored
* - trace will still continue normally otherwise.
*/
- if (ATTR_CFG_GET_FLD(attr, retstack) &&
- (drvdata->etmccer & ETMCCER_RETSTACK))
+ if (ATTR_CFG_GET_FLD(attr, retstack) && (caps->retstack))
config->ctrl |= ETMCR_RETURN_STACK;
return 0;
@@ -367,6 +367,7 @@ static int etm_enable_hw(struct etm_drvdata *drvdata)
{
int i, rc;
u32 etmcr;
+ const struct etm_caps *caps = &drvdata->caps;
struct etm_config *config = &drvdata->curr_config;
struct coresight_device *csdev = drvdata->csdev;
@@ -388,7 +389,7 @@ static int etm_enable_hw(struct etm_drvdata *drvdata)
etmcr = etm_readl(drvdata, ETMCR);
/* Clear setting from a previous run if need be */
etmcr &= ~ETM3X_SUPPORTED_OPTIONS;
- etmcr |= drvdata->port_size;
+ etmcr |= caps->port_size;
etmcr |= ETMCR_ETM_EN;
etm_writel(drvdata, config->ctrl | etmcr, ETMCR);
etm_writel(drvdata, config->trigger_event, ETMTRIGGER);
@@ -396,11 +397,11 @@ static int etm_enable_hw(struct etm_drvdata *drvdata)
etm_writel(drvdata, config->enable_event, ETMTEEVR);
etm_writel(drvdata, config->enable_ctrl1, ETMTECR1);
etm_writel(drvdata, config->fifofull_level, ETMFFLR);
- for (i = 0; i < drvdata->nr_addr_cmp; i++) {
+ for (i = 0; i < caps->nr_addr_cmp; i++) {
etm_writel(drvdata, config->addr_val[i], ETMACVRn(i));
etm_writel(drvdata, config->addr_acctype[i], ETMACTRn(i));
}
- for (i = 0; i < drvdata->nr_cntr; i++) {
+ for (i = 0; i < caps->nr_cntr; i++) {
etm_writel(drvdata, config->cntr_rld_val[i], ETMCNTRLDVRn(i));
etm_writel(drvdata, config->cntr_event[i], ETMCNTENRn(i));
etm_writel(drvdata, config->cntr_rld_event[i],
@@ -414,9 +415,9 @@ static int etm_enable_hw(struct etm_drvdata *drvdata)
etm_writel(drvdata, config->seq_32_event, ETMSQ32EVR);
etm_writel(drvdata, config->seq_13_event, ETMSQ13EVR);
etm_writel(drvdata, config->seq_curr_state, ETMSQR);
- for (i = 0; i < drvdata->nr_ext_out; i++)
+ for (i = 0; i < caps->nr_ext_out; i++)
etm_writel(drvdata, ETM_DEFAULT_EVENT_VAL, ETMEXTOUTEVRn(i));
- for (i = 0; i < drvdata->nr_ctxid_cmp; i++)
+ for (i = 0; i < caps->nr_ctxid_cmp; i++)
etm_writel(drvdata, config->ctxid_pid[i], ETMCIDCVRn(i));
etm_writel(drvdata, config->ctxid_mask, ETMCIDCMR);
etm_writel(drvdata, config->sync_freq, ETMSYNCFR);
@@ -560,6 +561,7 @@ static int etm_enable(struct coresight_device *csdev, struct perf_event *event,
static void etm_disable_hw(struct etm_drvdata *drvdata)
{
int i;
+ const struct etm_caps *caps = &drvdata->caps;
struct etm_config *config = &drvdata->curr_config;
struct coresight_device *csdev = drvdata->csdev;
@@ -569,7 +571,7 @@ static void etm_disable_hw(struct etm_drvdata *drvdata)
/* Read back sequencer and counters for post trace analysis */
config->seq_curr_state = (etm_readl(drvdata, ETMSQR) & ETM_SQR_MASK);
- for (i = 0; i < drvdata->nr_cntr; i++)
+ for (i = 0; i < caps->nr_cntr; i++)
config->cntr_val[i] = etm_readl(drvdata, ETMCNTVRn(i));
etm_set_pwrdwn(drvdata);
@@ -624,6 +626,7 @@ static void etm_disable_perf(struct coresight_device *csdev)
static void etm_disable_sysfs(struct coresight_device *csdev)
{
struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ const struct etm_caps *caps = &drvdata->caps;
struct etm_config *config = &drvdata->config;
const struct etm_config *curr_config = &drvdata->curr_config;
int i;
@@ -639,7 +642,7 @@ static void etm_disable_sysfs(struct coresight_device *csdev)
* Userspace may read seq_curr_state and cntr_val through sysfs
* after the sysfs-session has been disabled.
*/
- for (i = 0; i < drvdata->nr_cntr; i++)
+ for (i = 0; i < caps->nr_cntr; i++)
config->cntr_val[i] = curr_config->cntr_val[i];
config->seq_curr_state = curr_config->seq_curr_state;
@@ -724,7 +727,9 @@ static void etm_init_arch_data(void *info)
{
u32 etmidr;
u32 etmccr;
+ u32 etmccer;
struct etm_drvdata *drvdata = info;
+ struct etm_caps *caps = &drvdata->caps;
/* Make sure all registers are accessible */
etm_os_unlock(drvdata);
@@ -749,16 +754,19 @@ static void etm_init_arch_data(void *info)
/* Find all capabilities */
etmidr = etm_readl(drvdata, ETMIDR);
drvdata->arch = BMVAL(etmidr, 4, 11);
- drvdata->port_size = etm_readl(drvdata, ETMCR) & PORT_SIZE_MASK;
+ caps->port_size = etm_readl(drvdata, ETMCR) & PORT_SIZE_MASK;
+
+ etmccer = etm_readl(drvdata, ETMCCER);
+ caps->timestamp = !!(etmccer & ETMCCER_TIMESTAMP);
+ caps->retstack = !!(etmccer & ETMCCER_RETSTACK);
- drvdata->etmccer = etm_readl(drvdata, ETMCCER);
etmccr = etm_readl(drvdata, ETMCCR);
- drvdata->etmccr = etmccr;
- drvdata->nr_addr_cmp = BMVAL(etmccr, 0, 3) * 2;
- drvdata->nr_cntr = BMVAL(etmccr, 13, 15);
- drvdata->nr_ext_inp = BMVAL(etmccr, 17, 19);
- drvdata->nr_ext_out = BMVAL(etmccr, 20, 22);
- drvdata->nr_ctxid_cmp = BMVAL(etmccr, 24, 25);
+ caps->fifofull = !!(etmccr & ETMCCR_FIFOFULL);
+ caps->nr_addr_cmp = BMVAL(etmccr, 0, 3) * 2;
+ caps->nr_cntr = BMVAL(etmccr, 13, 15);
+ caps->nr_ext_inp = BMVAL(etmccr, 17, 19);
+ caps->nr_ext_out = BMVAL(etmccr, 20, 22);
+ caps->nr_ctxid_cmp = BMVAL(etmccr, 24, 25);
coresight_clear_self_claim_tag_unlocked(&drvdata->csa);
etm_set_pwrdwn(drvdata);
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
index 284998f18017..c27865d719eb 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
@@ -53,8 +53,9 @@ static ssize_t nr_addr_cmp_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etm_caps *caps = &drvdata->caps;
- val = drvdata->nr_addr_cmp;
+ val = caps->nr_addr_cmp;
return sprintf(buf, "%#lx\n", val);
}
static DEVICE_ATTR_RO(nr_addr_cmp);
@@ -63,8 +64,9 @@ static ssize_t nr_cntr_show(struct device *dev,
struct device_attribute *attr, char *buf)
{ unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etm_caps *caps = &drvdata->caps;
- val = drvdata->nr_cntr;
+ val = caps->nr_cntr;
return sprintf(buf, "%#lx\n", val);
}
static DEVICE_ATTR_RO(nr_cntr);
@@ -75,7 +77,7 @@ static ssize_t nr_ctxid_cmp_show(struct device *dev,
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- val = drvdata->nr_ctxid_cmp;
+ val = drvdata->caps.nr_ctxid_cmp;
return sprintf(buf, "%#lx\n", val);
}
static DEVICE_ATTR_RO(nr_ctxid_cmp);
@@ -117,7 +119,7 @@ static ssize_t reset_store(struct device *dev,
memset(config, 0, sizeof(struct etm_config));
config->mode = ETM_MODE_EXCLUDE;
config->trigger_event = ETM_DEFAULT_EVENT_VAL;
- for (i = 0; i < drvdata->nr_addr_cmp; i++) {
+ for (i = 0; i < drvdata->caps.nr_addr_cmp; i++) {
config->addr_type[i] = ETM_ADDR_TYPE_NONE;
}
@@ -148,6 +150,7 @@ static ssize_t mode_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etm_caps *caps = &drvdata->caps;
struct etm_config *config = &drvdata->config;
ret = kstrtoul(buf, 16, &val);
@@ -168,7 +171,7 @@ static ssize_t mode_store(struct device *dev,
config->ctrl &= ~ETMCR_CYC_ACC;
if (config->mode & ETM_MODE_STALL) {
- if (!(drvdata->etmccr & ETMCCR_FIFOFULL)) {
+ if (!caps->fifofull) {
dev_warn(dev, "stall mode not supported\n");
ret = -EINVAL;
goto err_unlock;
@@ -178,7 +181,7 @@ static ssize_t mode_store(struct device *dev,
config->ctrl &= ~ETMCR_STALL_MODE;
if (config->mode & ETM_MODE_TIMESTAMP) {
- if (!(drvdata->etmccer & ETMCCER_TIMESTAMP)) {
+ if (!caps->timestamp) {
dev_warn(dev, "timestamp not supported\n");
ret = -EINVAL;
goto err_unlock;
@@ -323,13 +326,14 @@ static ssize_t addr_idx_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etm_caps *caps = &drvdata->caps;
struct etm_config *config = &drvdata->config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
- if (val >= drvdata->nr_addr_cmp)
+ if (val >= caps->nr_addr_cmp)
return -EINVAL;
/*
@@ -626,13 +630,14 @@ static ssize_t cntr_idx_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etm_caps *caps = &drvdata->caps;
struct etm_config *config = &drvdata->config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
- if (val >= drvdata->nr_cntr)
+ if (val >= caps->nr_cntr)
return -EINVAL;
/*
* Use spinlock to ensure index doesn't change while it gets
@@ -1033,13 +1038,14 @@ static ssize_t ctxid_idx_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ const struct etm_caps *caps = &drvdata->caps;
struct etm_config *config = &drvdata->config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
- if (val >= drvdata->nr_ctxid_cmp)
+ if (val >= caps->nr_ctxid_cmp)
return -EINVAL;
/*
--
2.43.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v12 13/14] coresight: etm3x: rename local config as curr_config referring drvdata->curr_config
2026-09-24 17:33 [PATCH v12 00/14] fix several inconsistencies with sysfs configuration in etmX Yeoreum Yun
` (11 preceding siblings ...)
2026-09-24 17:33 ` [PATCH v12 12/14] coresight: etm3x: introduce struct etm_caps Yeoreum Yun
@ 2026-09-24 17:33 ` Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 14/14] coresight: etm3x: rename drvdata->config to sysfs_config Yeoreum Yun
13 siblings, 0 replies; 19+ messages in thread
From: Yeoreum Yun @ 2026-09-24 17:33 UTC (permalink / raw)
To: Mike Leach, James Clark, Leo Yan, Greg Kroah-Hartman,
Mathieu Poirier, coresight, linux-arm-kernel, linux-kernel,
linux-rt-devel
Cc: Suzuki K Poulose, Alexander Shishkin, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, Yeoreum Yun
For readability, rename the local config variable to curr_config in
places where it refers to drvdata->curr_config.
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
drivers/hwtracing/coresight/coresight-etm3x-core.c | 76 +++++++++++-----------
1 file changed, 38 insertions(+), 38 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
index ca2ba179b6fb..0cad9ecb49b6 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
@@ -309,7 +309,7 @@ static int etm_parse_event_config(struct etm_drvdata *drvdata,
struct perf_event *event)
{
const struct etm_caps *caps = &drvdata->caps;
- struct etm_config *config = &drvdata->curr_config;
+ struct etm_config *curr_config = &drvdata->curr_config;
struct perf_event_attr *attr = &event->attr;
u8 ts_level;
@@ -317,28 +317,28 @@ static int etm_parse_event_config(struct etm_drvdata *drvdata,
return -EINVAL;
/* Clear configuration from previous run */
- memset(config, 0, sizeof(struct etm_config));
+ memset(curr_config, 0, sizeof(struct etm_config));
if (attr->exclude_kernel)
- config->mode = ETM_MODE_EXCL_KERN;
+ curr_config->mode = ETM_MODE_EXCL_KERN;
if (attr->exclude_user)
- config->mode = ETM_MODE_EXCL_USER;
+ curr_config->mode = ETM_MODE_EXCL_USER;
/* Always start from the default config */
- etm_set_default(config);
+ etm_set_default(curr_config);
/*
* By default the tracers are configured to trace the whole address
* range. Narrow the field only if requested by user space.
*/
- if (config->mode)
- etm_config_trace_mode(config);
+ if (curr_config->mode)
+ etm_config_trace_mode(curr_config);
- config->ctrl = 0;
+ curr_config->ctrl = 0;
if (ATTR_CFG_GET_FLD(attr, cycacc))
- config->ctrl |= ETMCR_CYC_ACC;
+ curr_config->ctrl |= ETMCR_CYC_ACC;
ts_level = max(ATTR_CFG_GET_FLD(attr, timestamp),
ATTR_CFG_GET_FLD(attr, deprecated_timestamp));
@@ -350,7 +350,7 @@ static int etm_parse_event_config(struct etm_drvdata *drvdata,
}
if (ts_level)
- config->ctrl |= ETMCR_TIMESTAMP_EN;
+ curr_config->ctrl |= ETMCR_TIMESTAMP_EN;
/*
* Possible to have cores with PTM (supports ret stack) and ETM (never
@@ -358,7 +358,7 @@ static int etm_parse_event_config(struct etm_drvdata *drvdata,
* - trace will still continue normally otherwise.
*/
if (ATTR_CFG_GET_FLD(attr, retstack) && (caps->retstack))
- config->ctrl |= ETMCR_RETURN_STACK;
+ curr_config->ctrl |= ETMCR_RETURN_STACK;
return 0;
}
@@ -368,7 +368,7 @@ static int etm_enable_hw(struct etm_drvdata *drvdata)
int i, rc;
u32 etmcr;
const struct etm_caps *caps = &drvdata->caps;
- struct etm_config *config = &drvdata->curr_config;
+ struct etm_config *curr_config = &drvdata->curr_config;
struct coresight_device *csdev = drvdata->csdev;
CS_UNLOCK(drvdata->csa.base);
@@ -391,39 +391,39 @@ static int etm_enable_hw(struct etm_drvdata *drvdata)
etmcr &= ~ETM3X_SUPPORTED_OPTIONS;
etmcr |= caps->port_size;
etmcr |= ETMCR_ETM_EN;
- etm_writel(drvdata, config->ctrl | etmcr, ETMCR);
- etm_writel(drvdata, config->trigger_event, ETMTRIGGER);
- etm_writel(drvdata, config->startstop_ctrl, ETMTSSCR);
- etm_writel(drvdata, config->enable_event, ETMTEEVR);
- etm_writel(drvdata, config->enable_ctrl1, ETMTECR1);
- etm_writel(drvdata, config->fifofull_level, ETMFFLR);
+ etm_writel(drvdata, curr_config->ctrl | etmcr, ETMCR);
+ etm_writel(drvdata, curr_config->trigger_event, ETMTRIGGER);
+ etm_writel(drvdata, curr_config->startstop_ctrl, ETMTSSCR);
+ etm_writel(drvdata, curr_config->enable_event, ETMTEEVR);
+ etm_writel(drvdata, curr_config->enable_ctrl1, ETMTECR1);
+ etm_writel(drvdata, curr_config->fifofull_level, ETMFFLR);
for (i = 0; i < caps->nr_addr_cmp; i++) {
- etm_writel(drvdata, config->addr_val[i], ETMACVRn(i));
- etm_writel(drvdata, config->addr_acctype[i], ETMACTRn(i));
+ etm_writel(drvdata, curr_config->addr_val[i], ETMACVRn(i));
+ etm_writel(drvdata, curr_config->addr_acctype[i], ETMACTRn(i));
}
for (i = 0; i < caps->nr_cntr; i++) {
- etm_writel(drvdata, config->cntr_rld_val[i], ETMCNTRLDVRn(i));
- etm_writel(drvdata, config->cntr_event[i], ETMCNTENRn(i));
- etm_writel(drvdata, config->cntr_rld_event[i],
+ etm_writel(drvdata, curr_config->cntr_rld_val[i], ETMCNTRLDVRn(i));
+ etm_writel(drvdata, curr_config->cntr_event[i], ETMCNTENRn(i));
+ etm_writel(drvdata, curr_config->cntr_rld_event[i],
ETMCNTRLDEVRn(i));
- etm_writel(drvdata, config->cntr_val[i], ETMCNTVRn(i));
+ etm_writel(drvdata, curr_config->cntr_val[i], ETMCNTVRn(i));
}
- etm_writel(drvdata, config->seq_12_event, ETMSQ12EVR);
- etm_writel(drvdata, config->seq_21_event, ETMSQ21EVR);
- etm_writel(drvdata, config->seq_23_event, ETMSQ23EVR);
- etm_writel(drvdata, config->seq_31_event, ETMSQ31EVR);
- etm_writel(drvdata, config->seq_32_event, ETMSQ32EVR);
- etm_writel(drvdata, config->seq_13_event, ETMSQ13EVR);
- etm_writel(drvdata, config->seq_curr_state, ETMSQR);
+ etm_writel(drvdata, curr_config->seq_12_event, ETMSQ12EVR);
+ etm_writel(drvdata, curr_config->seq_21_event, ETMSQ21EVR);
+ etm_writel(drvdata, curr_config->seq_23_event, ETMSQ23EVR);
+ etm_writel(drvdata, curr_config->seq_31_event, ETMSQ31EVR);
+ etm_writel(drvdata, curr_config->seq_32_event, ETMSQ32EVR);
+ etm_writel(drvdata, curr_config->seq_13_event, ETMSQ13EVR);
+ etm_writel(drvdata, curr_config->seq_curr_state, ETMSQR);
for (i = 0; i < caps->nr_ext_out; i++)
etm_writel(drvdata, ETM_DEFAULT_EVENT_VAL, ETMEXTOUTEVRn(i));
for (i = 0; i < caps->nr_ctxid_cmp; i++)
- etm_writel(drvdata, config->ctxid_pid[i], ETMCIDCVRn(i));
- etm_writel(drvdata, config->ctxid_mask, ETMCIDCMR);
- etm_writel(drvdata, config->sync_freq, ETMSYNCFR);
+ etm_writel(drvdata, curr_config->ctxid_pid[i], ETMCIDCVRn(i));
+ etm_writel(drvdata, curr_config->ctxid_mask, ETMCIDCMR);
+ etm_writel(drvdata, curr_config->sync_freq, ETMSYNCFR);
/* No external input selected */
etm_writel(drvdata, 0x0, ETMEXTINSELR);
- etm_writel(drvdata, config->timestamp_event, ETMTSEVR);
+ etm_writel(drvdata, curr_config->timestamp_event, ETMTSEVR);
/* No auxiliary control selected */
etm_writel(drvdata, 0x0, ETMAUXCR);
etm_writel(drvdata, drvdata->traceid, ETMTRACEIDR);
@@ -562,17 +562,17 @@ static void etm_disable_hw(struct etm_drvdata *drvdata)
{
int i;
const struct etm_caps *caps = &drvdata->caps;
- struct etm_config *config = &drvdata->curr_config;
+ struct etm_config *curr_config = &drvdata->curr_config;
struct coresight_device *csdev = drvdata->csdev;
CS_UNLOCK(drvdata->csa.base);
etm_set_prog(drvdata);
/* Read back sequencer and counters for post trace analysis */
- config->seq_curr_state = (etm_readl(drvdata, ETMSQR) & ETM_SQR_MASK);
+ curr_config->seq_curr_state = (etm_readl(drvdata, ETMSQR) & ETM_SQR_MASK);
for (i = 0; i < caps->nr_cntr; i++)
- config->cntr_val[i] = etm_readl(drvdata, ETMCNTVRn(i));
+ curr_config->cntr_val[i] = etm_readl(drvdata, ETMCNTVRn(i));
etm_set_pwrdwn(drvdata);
coresight_disclaim_device_unlocked(csdev);
--
2.43.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v12 14/14] coresight: etm3x: rename drvdata->config to sysfs_config
2026-09-24 17:33 [PATCH v12 00/14] fix several inconsistencies with sysfs configuration in etmX Yeoreum Yun
` (12 preceding siblings ...)
2026-09-24 17:33 ` [PATCH v12 13/14] coresight: etm3x: rename local config as curr_config referring drvdata->curr_config Yeoreum Yun
@ 2026-09-24 17:33 ` Yeoreum Yun
2026-09-24 18:36 ` sashiko-bot
13 siblings, 1 reply; 19+ messages in thread
From: Yeoreum Yun @ 2026-09-24 17:33 UTC (permalink / raw)
To: Mike Leach, James Clark, Leo Yan, Greg Kroah-Hartman,
Mathieu Poirier, coresight, linux-arm-kernel, linux-kernel,
linux-rt-devel
Cc: Suzuki K Poulose, Alexander Shishkin, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, Yeoreum Yun
drvdata->config is used only by the sysfs interface.
Rename it to sysfs_config to clarify its purpose.
For readability, also rename local config variables to sysfs_config
where they refer to drvdata->sysfs_config.
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
drivers/hwtracing/coresight/coresight-etm.h | 4 +-
drivers/hwtracing/coresight/coresight-etm3x-core.c | 6 +-
.../hwtracing/coresight/coresight-etm3x-sysfs.c | 356 ++++++++++-----------
3 files changed, 183 insertions(+), 183 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm.h b/drivers/hwtracing/coresight/coresight-etm.h
index 560a58a3817c..cf65d89a8e98 100644
--- a/drivers/hwtracing/coresight/coresight-etm.h
+++ b/drivers/hwtracing/coresight/coresight-etm.h
@@ -244,7 +244,7 @@ struct etm_config {
* @os_unlock: true if access to management registers is allowed.
* @traceid: value of the current ID for this component.
* @curr_config: structure holding current running configuration.
- * @config: structure holding sysfs mode configuration.
+ * @sysfs_config: structure holding sysfs mode configuration.
*/
struct etm_drvdata {
struct csdev_access csa;
@@ -260,7 +260,7 @@ struct etm_drvdata {
bool os_unlock;
u32 traceid;
struct etm_config curr_config;
- struct etm_config config;
+ struct etm_config sysfs_config;
};
static inline void etm_writel(struct etm_drvdata *drvdata,
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
index 0cad9ecb49b6..67f1b71de881 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
@@ -518,7 +518,7 @@ static int etm_enable_sysfs(struct coresight_device *csdev, struct coresight_pat
arg.path = path;
scoped_guard(spinlock, &drvdata->spinlock) {
- drvdata->curr_config = drvdata->config;
+ drvdata->curr_config = drvdata->sysfs_config;
}
ret = smp_call_function_single(drvdata->cpu,
@@ -627,7 +627,7 @@ static void etm_disable_sysfs(struct coresight_device *csdev)
{
struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
const struct etm_caps *caps = &drvdata->caps;
- struct etm_config *config = &drvdata->config;
+ struct etm_config *config = &drvdata->sysfs_config;
const struct etm_config *curr_config = &drvdata->curr_config;
int i;
@@ -844,7 +844,7 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id)
if (etm_arch_supported(drvdata->arch) == false)
return -EINVAL;
- etm_set_default(&drvdata->config);
+ etm_set_default(&drvdata->sysfs_config);
pdata = coresight_get_platform_data(dev);
if (IS_ERR(pdata))
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
index c27865d719eb..d185fb8270e1 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
@@ -104,7 +104,7 @@ static ssize_t reset_store(struct device *dev,
int i, ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
@@ -116,14 +116,14 @@ static ssize_t reset_store(struct device *dev,
if (val) {
spin_lock(&drvdata->spinlock);
- memset(config, 0, sizeof(struct etm_config));
- config->mode = ETM_MODE_EXCLUDE;
- config->trigger_event = ETM_DEFAULT_EVENT_VAL;
+ memset(sysfs_config, 0, sizeof(struct etm_config));
+ sysfs_config->mode = ETM_MODE_EXCLUDE;
+ sysfs_config->trigger_event = ETM_DEFAULT_EVENT_VAL;
for (i = 0; i < drvdata->caps.nr_addr_cmp; i++) {
- config->addr_type[i] = ETM_ADDR_TYPE_NONE;
+ sysfs_config->addr_type[i] = ETM_ADDR_TYPE_NONE;
}
- etm_set_default(config);
+ etm_set_default(sysfs_config);
etm_release_trace_id(drvdata);
spin_unlock(&drvdata->spinlock);
}
@@ -137,9 +137,9 @@ static ssize_t mode_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
- val = config->mode;
+ val = sysfs_config->mode;
return sprintf(buf, "%#lx\n", val);
}
@@ -151,62 +151,62 @@ static ssize_t mode_store(struct device *dev,
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etm_caps *caps = &drvdata->caps;
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
spin_lock(&drvdata->spinlock);
- config->mode = val & ETM_MODE_ALL;
+ sysfs_config->mode = val & ETM_MODE_ALL;
- if (config->mode & ETM_MODE_EXCLUDE)
- config->enable_ctrl1 |= ETMTECR1_INC_EXC;
+ if (sysfs_config->mode & ETM_MODE_EXCLUDE)
+ sysfs_config->enable_ctrl1 |= ETMTECR1_INC_EXC;
else
- config->enable_ctrl1 &= ~ETMTECR1_INC_EXC;
+ sysfs_config->enable_ctrl1 &= ~ETMTECR1_INC_EXC;
- if (config->mode & ETM_MODE_CYCACC)
- config->ctrl |= ETMCR_CYC_ACC;
+ if (sysfs_config->mode & ETM_MODE_CYCACC)
+ sysfs_config->ctrl |= ETMCR_CYC_ACC;
else
- config->ctrl &= ~ETMCR_CYC_ACC;
+ sysfs_config->ctrl &= ~ETMCR_CYC_ACC;
- if (config->mode & ETM_MODE_STALL) {
+ if (sysfs_config->mode & ETM_MODE_STALL) {
if (!caps->fifofull) {
dev_warn(dev, "stall mode not supported\n");
ret = -EINVAL;
goto err_unlock;
}
- config->ctrl |= ETMCR_STALL_MODE;
+ sysfs_config->ctrl |= ETMCR_STALL_MODE;
} else
- config->ctrl &= ~ETMCR_STALL_MODE;
+ sysfs_config->ctrl &= ~ETMCR_STALL_MODE;
- if (config->mode & ETM_MODE_TIMESTAMP) {
+ if (sysfs_config->mode & ETM_MODE_TIMESTAMP) {
if (!caps->timestamp) {
dev_warn(dev, "timestamp not supported\n");
ret = -EINVAL;
goto err_unlock;
}
- config->ctrl |= ETMCR_TIMESTAMP_EN;
+ sysfs_config->ctrl |= ETMCR_TIMESTAMP_EN;
} else
- config->ctrl &= ~ETMCR_TIMESTAMP_EN;
+ sysfs_config->ctrl &= ~ETMCR_TIMESTAMP_EN;
- if (config->mode & ETM_MODE_CTXID)
- config->ctrl |= ETMCR_CTXID_SIZE;
+ if (sysfs_config->mode & ETM_MODE_CTXID)
+ sysfs_config->ctrl |= ETMCR_CTXID_SIZE;
else
- config->ctrl &= ~ETMCR_CTXID_SIZE;
+ sysfs_config->ctrl &= ~ETMCR_CTXID_SIZE;
- if (config->mode & ETM_MODE_BBROAD)
- config->ctrl |= ETMCR_BRANCH_BROADCAST;
+ if (sysfs_config->mode & ETM_MODE_BBROAD)
+ sysfs_config->ctrl |= ETMCR_BRANCH_BROADCAST;
else
- config->ctrl &= ~ETMCR_BRANCH_BROADCAST;
+ sysfs_config->ctrl &= ~ETMCR_BRANCH_BROADCAST;
- if (config->mode & ETM_MODE_RET_STACK)
- config->ctrl |= ETMCR_RETURN_STACK;
+ if (sysfs_config->mode & ETM_MODE_RET_STACK)
+ sysfs_config->ctrl |= ETMCR_RETURN_STACK;
else
- config->ctrl &= ~ETMCR_RETURN_STACK;
+ sysfs_config->ctrl &= ~ETMCR_RETURN_STACK;
- if (config->mode & (ETM_MODE_EXCL_KERN | ETM_MODE_EXCL_USER))
- etm_config_trace_mode(config);
+ if (sysfs_config->mode & (ETM_MODE_EXCL_KERN | ETM_MODE_EXCL_USER))
+ etm_config_trace_mode(sysfs_config);
spin_unlock(&drvdata->spinlock);
@@ -223,9 +223,9 @@ static ssize_t trigger_event_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
- val = config->trigger_event;
+ val = sysfs_config->trigger_event;
return sprintf(buf, "%#lx\n", val);
}
@@ -236,13 +236,13 @@ static ssize_t trigger_event_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
- config->trigger_event = val & ETM_EVENT_MASK;
+ sysfs_config->trigger_event = val & ETM_EVENT_MASK;
return size;
}
@@ -253,9 +253,9 @@ static ssize_t enable_event_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
- val = config->enable_event;
+ val = sysfs_config->enable_event;
return sprintf(buf, "%#lx\n", val);
}
@@ -266,13 +266,13 @@ static ssize_t enable_event_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
- config->enable_event = val & ETM_EVENT_MASK;
+ sysfs_config->enable_event = val & ETM_EVENT_MASK;
return size;
}
@@ -283,9 +283,9 @@ static ssize_t fifofull_level_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
- val = config->fifofull_level;
+ val = sysfs_config->fifofull_level;
return sprintf(buf, "%#lx\n", val);
}
@@ -296,13 +296,13 @@ static ssize_t fifofull_level_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
- config->fifofull_level = val;
+ sysfs_config->fifofull_level = val;
return size;
}
@@ -313,9 +313,9 @@ static ssize_t addr_idx_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
- val = config->addr_idx;
+ val = sysfs_config->addr_idx;
return sprintf(buf, "%#lx\n", val);
}
@@ -327,7 +327,7 @@ static ssize_t addr_idx_store(struct device *dev,
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etm_caps *caps = &drvdata->caps;
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
@@ -341,7 +341,7 @@ static ssize_t addr_idx_store(struct device *dev,
* dereferenced multiple times within a spinlock block elsewhere.
*/
spin_lock(&drvdata->spinlock);
- config->addr_idx = val;
+ sysfs_config->addr_idx = val;
spin_unlock(&drvdata->spinlock);
return size;
@@ -354,17 +354,17 @@ static ssize_t addr_single_show(struct device *dev,
u8 idx;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
- if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
- config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
+ idx = sysfs_config->addr_idx;
+ if (!(sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+ sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
spin_unlock(&drvdata->spinlock);
return -EINVAL;
}
- val = config->addr_val[idx];
+ val = sysfs_config->addr_val[idx];
spin_unlock(&drvdata->spinlock);
return sprintf(buf, "%#lx\n", val);
@@ -378,22 +378,22 @@ static ssize_t addr_single_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
- if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
- config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
+ idx = sysfs_config->addr_idx;
+ if (!(sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+ sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
spin_unlock(&drvdata->spinlock);
return -EINVAL;
}
- config->addr_val[idx] = val;
- config->addr_type[idx] = ETM_ADDR_TYPE_SINGLE;
+ sysfs_config->addr_val[idx] = val;
+ sysfs_config->addr_type[idx] = ETM_ADDR_TYPE_SINGLE;
spin_unlock(&drvdata->spinlock);
return size;
@@ -406,24 +406,24 @@ static ssize_t addr_range_show(struct device *dev,
u8 idx;
unsigned long val1, val2;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
+ idx = sysfs_config->addr_idx;
if (idx % 2 != 0) {
spin_unlock(&drvdata->spinlock);
return -EPERM;
}
- if (!((config->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
- config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
- (config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
- config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
+ if (!((sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
+ sysfs_config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
+ (sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
+ sysfs_config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
spin_unlock(&drvdata->spinlock);
return -EPERM;
}
- val1 = config->addr_val[idx];
- val2 = config->addr_val[idx + 1];
+ val1 = sysfs_config->addr_val[idx];
+ val2 = sysfs_config->addr_val[idx + 1];
spin_unlock(&drvdata->spinlock);
return sprintf(buf, "%#lx %#lx\n", val1, val2);
@@ -436,7 +436,7 @@ static ssize_t addr_range_store(struct device *dev,
u8 idx;
unsigned long val1, val2;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
return -EINVAL;
@@ -445,24 +445,24 @@ static ssize_t addr_range_store(struct device *dev,
return -EINVAL;
spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
+ idx = sysfs_config->addr_idx;
if (idx % 2 != 0) {
spin_unlock(&drvdata->spinlock);
return -EPERM;
}
- if (!((config->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
- config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
- (config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
- config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
+ if (!((sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
+ sysfs_config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
+ (sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
+ sysfs_config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
spin_unlock(&drvdata->spinlock);
return -EPERM;
}
- config->addr_val[idx] = val1;
- config->addr_type[idx] = ETM_ADDR_TYPE_RANGE;
- config->addr_val[idx + 1] = val2;
- config->addr_type[idx + 1] = ETM_ADDR_TYPE_RANGE;
- config->enable_ctrl1 |= (1 << (idx/2));
+ sysfs_config->addr_val[idx] = val1;
+ sysfs_config->addr_type[idx] = ETM_ADDR_TYPE_RANGE;
+ sysfs_config->addr_val[idx + 1] = val2;
+ sysfs_config->addr_type[idx + 1] = ETM_ADDR_TYPE_RANGE;
+ sysfs_config->enable_ctrl1 |= (1 << (idx/2));
spin_unlock(&drvdata->spinlock);
return size;
@@ -475,17 +475,17 @@ static ssize_t addr_start_show(struct device *dev,
u8 idx;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
- if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
- config->addr_type[idx] == ETM_ADDR_TYPE_START)) {
+ idx = sysfs_config->addr_idx;
+ if (!(sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+ sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_START)) {
spin_unlock(&drvdata->spinlock);
return -EPERM;
}
- val = config->addr_val[idx];
+ val = sysfs_config->addr_val[idx];
spin_unlock(&drvdata->spinlock);
return sprintf(buf, "%#lx\n", val);
@@ -499,24 +499,24 @@ static ssize_t addr_start_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
- if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
- config->addr_type[idx] == ETM_ADDR_TYPE_START)) {
+ idx = sysfs_config->addr_idx;
+ if (!(sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+ sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_START)) {
spin_unlock(&drvdata->spinlock);
return -EPERM;
}
- config->addr_val[idx] = val;
- config->addr_type[idx] = ETM_ADDR_TYPE_START;
- config->startstop_ctrl |= (1 << idx);
- config->enable_ctrl1 |= ETMTECR1_START_STOP;
+ sysfs_config->addr_val[idx] = val;
+ sysfs_config->addr_type[idx] = ETM_ADDR_TYPE_START;
+ sysfs_config->startstop_ctrl |= (1 << idx);
+ sysfs_config->enable_ctrl1 |= ETMTECR1_START_STOP;
spin_unlock(&drvdata->spinlock);
return size;
@@ -529,17 +529,17 @@ static ssize_t addr_stop_show(struct device *dev,
u8 idx;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
- if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
- config->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
+ idx = sysfs_config->addr_idx;
+ if (!(sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+ sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
spin_unlock(&drvdata->spinlock);
return -EPERM;
}
- val = config->addr_val[idx];
+ val = sysfs_config->addr_val[idx];
spin_unlock(&drvdata->spinlock);
return sprintf(buf, "%#lx\n", val);
@@ -553,24 +553,24 @@ static ssize_t addr_stop_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
spin_lock(&drvdata->spinlock);
- idx = config->addr_idx;
- if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
- config->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
+ idx = sysfs_config->addr_idx;
+ if (!(sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+ sysfs_config->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
spin_unlock(&drvdata->spinlock);
return -EPERM;
}
- config->addr_val[idx] = val;
- config->addr_type[idx] = ETM_ADDR_TYPE_STOP;
- config->startstop_ctrl |= (1 << (idx + 16));
- config->enable_ctrl1 |= ETMTECR1_START_STOP;
+ sysfs_config->addr_val[idx] = val;
+ sysfs_config->addr_type[idx] = ETM_ADDR_TYPE_STOP;
+ sysfs_config->startstop_ctrl |= (1 << (idx + 16));
+ sysfs_config->enable_ctrl1 |= ETMTECR1_START_STOP;
spin_unlock(&drvdata->spinlock);
return size;
@@ -582,10 +582,10 @@ static ssize_t addr_acctype_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
spin_lock(&drvdata->spinlock);
- val = config->addr_acctype[config->addr_idx];
+ val = sysfs_config->addr_acctype[sysfs_config->addr_idx];
spin_unlock(&drvdata->spinlock);
return sprintf(buf, "%#lx\n", val);
@@ -598,14 +598,14 @@ static ssize_t addr_acctype_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
spin_lock(&drvdata->spinlock);
- config->addr_acctype[config->addr_idx] = val;
+ sysfs_config->addr_acctype[sysfs_config->addr_idx] = val;
spin_unlock(&drvdata->spinlock);
return size;
@@ -617,9 +617,9 @@ static ssize_t cntr_idx_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
- val = config->cntr_idx;
+ val = sysfs_config->cntr_idx;
return sprintf(buf, "%#lx\n", val);
}
@@ -631,7 +631,7 @@ static ssize_t cntr_idx_store(struct device *dev,
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etm_caps *caps = &drvdata->caps;
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
@@ -644,7 +644,7 @@ static ssize_t cntr_idx_store(struct device *dev,
* dereferenced multiple times within a spinlock block elsewhere.
*/
spin_lock(&drvdata->spinlock);
- config->cntr_idx = val;
+ sysfs_config->cntr_idx = val;
spin_unlock(&drvdata->spinlock);
return size;
@@ -656,10 +656,10 @@ static ssize_t cntr_rld_val_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
spin_lock(&drvdata->spinlock);
- val = config->cntr_rld_val[config->cntr_idx];
+ val = sysfs_config->cntr_rld_val[sysfs_config->cntr_idx];
spin_unlock(&drvdata->spinlock);
return sprintf(buf, "%#lx\n", val);
@@ -672,14 +672,14 @@ static ssize_t cntr_rld_val_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
spin_lock(&drvdata->spinlock);
- config->cntr_rld_val[config->cntr_idx] = val;
+ sysfs_config->cntr_rld_val[sysfs_config->cntr_idx] = val;
spin_unlock(&drvdata->spinlock);
return size;
@@ -691,10 +691,10 @@ static ssize_t cntr_event_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
spin_lock(&drvdata->spinlock);
- val = config->cntr_event[config->cntr_idx];
+ val = sysfs_config->cntr_event[sysfs_config->cntr_idx];
spin_unlock(&drvdata->spinlock);
return sprintf(buf, "%#lx\n", val);
@@ -707,14 +707,14 @@ static ssize_t cntr_event_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
spin_lock(&drvdata->spinlock);
- config->cntr_event[config->cntr_idx] = val & ETM_EVENT_MASK;
+ sysfs_config->cntr_event[sysfs_config->cntr_idx] = val & ETM_EVENT_MASK;
spin_unlock(&drvdata->spinlock);
return size;
@@ -726,10 +726,10 @@ static ssize_t cntr_rld_event_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
spin_lock(&drvdata->spinlock);
- val = config->cntr_rld_event[config->cntr_idx];
+ val = sysfs_config->cntr_rld_event[sysfs_config->cntr_idx];
spin_unlock(&drvdata->spinlock);
return sprintf(buf, "%#lx\n", val);
@@ -742,14 +742,14 @@ static ssize_t cntr_rld_event_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
spin_lock(&drvdata->spinlock);
- config->cntr_rld_event[config->cntr_idx] = val & ETM_EVENT_MASK;
+ sysfs_config->cntr_rld_event[sysfs_config->cntr_idx] = val & ETM_EVENT_MASK;
spin_unlock(&drvdata->spinlock);
return size;
@@ -763,14 +763,14 @@ static ssize_t cntr_val_show(struct device *dev,
u32 val;
unsigned long val2;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
if (!coresight_get_mode(drvdata->csdev)) {
spin_lock(&drvdata->spinlock);
- val = config->cntr_val[config->cntr_idx];
+ val = sysfs_config->cntr_val[sysfs_config->cntr_idx];
spin_unlock(&drvdata->spinlock);
} else {
- ret = etm_readl_cslocked(drvdata, ETMCNTVRn(config->cntr_idx), &val2);
+ ret = etm_readl_cslocked(drvdata, ETMCNTVRn(sysfs_config->cntr_idx), &val2);
if (ret)
return ret;
val = val2;
@@ -786,7 +786,7 @@ static ssize_t cntr_val_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
@@ -796,7 +796,7 @@ static ssize_t cntr_val_store(struct device *dev,
return -EBUSY;
spin_lock(&drvdata->spinlock);
- config->cntr_val[config->cntr_idx] = val;
+ sysfs_config->cntr_val[sysfs_config->cntr_idx] = val;
spin_unlock(&drvdata->spinlock);
return size;
@@ -808,9 +808,9 @@ static ssize_t seq_12_event_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
- val = config->seq_12_event;
+ val = sysfs_config->seq_12_event;
return sprintf(buf, "%#lx\n", val);
}
@@ -821,13 +821,13 @@ static ssize_t seq_12_event_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
- config->seq_12_event = val & ETM_EVENT_MASK;
+ sysfs_config->seq_12_event = val & ETM_EVENT_MASK;
return size;
}
static DEVICE_ATTR_RW(seq_12_event);
@@ -837,9 +837,9 @@ static ssize_t seq_21_event_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
- val = config->seq_21_event;
+ val = sysfs_config->seq_21_event;
return sprintf(buf, "%#lx\n", val);
}
@@ -850,13 +850,13 @@ static ssize_t seq_21_event_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
- config->seq_21_event = val & ETM_EVENT_MASK;
+ sysfs_config->seq_21_event = val & ETM_EVENT_MASK;
return size;
}
static DEVICE_ATTR_RW(seq_21_event);
@@ -866,9 +866,9 @@ static ssize_t seq_23_event_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
- val = config->seq_23_event;
+ val = sysfs_config->seq_23_event;
return sprintf(buf, "%#lx\n", val);
}
@@ -879,13 +879,13 @@ static ssize_t seq_23_event_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
- config->seq_23_event = val & ETM_EVENT_MASK;
+ sysfs_config->seq_23_event = val & ETM_EVENT_MASK;
return size;
}
static DEVICE_ATTR_RW(seq_23_event);
@@ -895,9 +895,9 @@ static ssize_t seq_31_event_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
- val = config->seq_31_event;
+ val = sysfs_config->seq_31_event;
return sprintf(buf, "%#lx\n", val);
}
@@ -908,13 +908,13 @@ static ssize_t seq_31_event_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
- config->seq_31_event = val & ETM_EVENT_MASK;
+ sysfs_config->seq_31_event = val & ETM_EVENT_MASK;
return size;
}
static DEVICE_ATTR_RW(seq_31_event);
@@ -924,9 +924,9 @@ static ssize_t seq_32_event_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
- val = config->seq_32_event;
+ val = sysfs_config->seq_32_event;
return sprintf(buf, "%#lx\n", val);
}
@@ -937,13 +937,13 @@ static ssize_t seq_32_event_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
- config->seq_32_event = val & ETM_EVENT_MASK;
+ sysfs_config->seq_32_event = val & ETM_EVENT_MASK;
return size;
}
static DEVICE_ATTR_RW(seq_32_event);
@@ -953,9 +953,9 @@ static ssize_t seq_13_event_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
- val = config->seq_13_event;
+ val = sysfs_config->seq_13_event;
return sprintf(buf, "%#lx\n", val);
}
@@ -966,13 +966,13 @@ static ssize_t seq_13_event_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
- config->seq_13_event = val & ETM_EVENT_MASK;
+ sysfs_config->seq_13_event = val & ETM_EVENT_MASK;
return size;
}
static DEVICE_ATTR_RW(seq_13_event);
@@ -983,10 +983,10 @@ static ssize_t seq_curr_state_show(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
if (!coresight_get_mode(drvdata->csdev)) {
- val = config->seq_curr_state;
+ val = sysfs_config->seq_curr_state;
goto out;
}
@@ -1005,7 +1005,7 @@ static ssize_t seq_curr_state_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
@@ -1014,7 +1014,7 @@ static ssize_t seq_curr_state_store(struct device *dev,
if (val > ETM_SEQ_STATE_MAX_VAL)
return -EINVAL;
- config->seq_curr_state = val;
+ sysfs_config->seq_curr_state = val;
return size;
}
@@ -1025,9 +1025,9 @@ static ssize_t ctxid_idx_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
- val = config->ctxid_idx;
+ val = sysfs_config->ctxid_idx;
return sprintf(buf, "%#lx\n", val);
}
@@ -1039,7 +1039,7 @@ static ssize_t ctxid_idx_store(struct device *dev,
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
const struct etm_caps *caps = &drvdata->caps;
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
@@ -1053,7 +1053,7 @@ static ssize_t ctxid_idx_store(struct device *dev,
* dereferenced multiple times within a spinlock block elsewhere.
*/
spin_lock(&drvdata->spinlock);
- config->ctxid_idx = val;
+ sysfs_config->ctxid_idx = val;
spin_unlock(&drvdata->spinlock);
return size;
@@ -1065,7 +1065,7 @@ static ssize_t ctxid_pid_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
/*
* Don't use contextID tracing if coming from a PID namespace. See
@@ -1075,7 +1075,7 @@ static ssize_t ctxid_pid_show(struct device *dev,
return -EINVAL;
spin_lock(&drvdata->spinlock);
- val = config->ctxid_pid[config->ctxid_idx];
+ val = sysfs_config->ctxid_pid[sysfs_config->ctxid_idx];
spin_unlock(&drvdata->spinlock);
return sprintf(buf, "%#lx\n", val);
@@ -1088,7 +1088,7 @@ static ssize_t ctxid_pid_store(struct device *dev,
int ret;
unsigned long pid;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
/*
* When contextID tracing is enabled the tracers will insert the
@@ -1107,7 +1107,7 @@ static ssize_t ctxid_pid_store(struct device *dev,
return ret;
spin_lock(&drvdata->spinlock);
- config->ctxid_pid[config->ctxid_idx] = pid;
+ sysfs_config->ctxid_pid[sysfs_config->ctxid_idx] = pid;
spin_unlock(&drvdata->spinlock);
return size;
@@ -1119,7 +1119,7 @@ static ssize_t ctxid_mask_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
/*
* Don't use contextID tracing if coming from a PID namespace. See
@@ -1128,7 +1128,7 @@ static ssize_t ctxid_mask_show(struct device *dev,
if (task_active_pid_ns(current) != &init_pid_ns)
return -EINVAL;
- val = config->ctxid_mask;
+ val = sysfs_config->ctxid_mask;
return sprintf(buf, "%#lx\n", val);
}
@@ -1139,7 +1139,7 @@ static ssize_t ctxid_mask_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
/*
* Don't use contextID tracing if coming from a PID namespace. See
@@ -1152,7 +1152,7 @@ static ssize_t ctxid_mask_store(struct device *dev,
if (ret)
return ret;
- config->ctxid_mask = val;
+ sysfs_config->ctxid_mask = val;
return size;
}
static DEVICE_ATTR_RW(ctxid_mask);
@@ -1162,9 +1162,9 @@ static ssize_t sync_freq_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
- val = config->sync_freq;
+ val = sysfs_config->sync_freq;
return sprintf(buf, "%#lx\n", val);
}
@@ -1175,13 +1175,13 @@ static ssize_t sync_freq_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
- config->sync_freq = val & ETM_SYNC_MASK;
+ sysfs_config->sync_freq = val & ETM_SYNC_MASK;
return size;
}
static DEVICE_ATTR_RW(sync_freq);
@@ -1191,9 +1191,9 @@ static ssize_t timestamp_event_show(struct device *dev,
{
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
- val = config->timestamp_event;
+ val = sysfs_config->timestamp_event;
return sprintf(buf, "%#lx\n", val);
}
@@ -1204,13 +1204,13 @@ static ssize_t timestamp_event_store(struct device *dev,
int ret;
unsigned long val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
- struct etm_config *config = &drvdata->config;
+ struct etm_config *sysfs_config = &drvdata->sysfs_config;
ret = kstrtoul(buf, 16, &val);
if (ret)
return ret;
- config->timestamp_event = val & ETM_EVENT_MASK;
+ sysfs_config->timestamp_event = val & ETM_EVENT_MASK;
return size;
}
static DEVICE_ATTR_RW(timestamp_event);
--
2.43.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v12 01/14] coresight: etm4x: read-back TRCSEQSTR at disabling and prohibit modifying seq_state while enabling.
2026-09-24 17:33 ` [PATCH v12 01/14] coresight: etm4x: read-back TRCSEQSTR at disabling and prohibit modifying seq_state while enabling Yeoreum Yun
@ 2026-09-24 17:46 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-09-24 17:46 UTC (permalink / raw)
To: Yeoreum Yun; +Cc: linux-rt-devel, linux-kernel
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] coresight: TOCTOU race in seq_state_store lockless mode check
- [Low] coresight: misplaced IS_ERR_OR_NULL(drvdata) after dereference
--
commit fb240199cfa6db080873efbe2c007beb70c01070
Author: Yeoreum Yun <yeoreum.yun@arm.com>
coresight: etm4x: read-back TRCSEQSTR at disabling and prohibit modifying seq_state while enabling.
TRCSEQSTR can be changed by the ETM while a session is active. Its value
therefore needs to be preserved when a sysfs session is disabled so that
users can read the current sequence state after the session ends.
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> index cc6cdd3ae29d5..db3cf4ad6806c 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> @@ -1437,6 +1437,8 @@ static ssize_t seq_state_store(struct device *dev,
> return -EINVAL;
> if (val >= drvdata->nrseqstate)
> return -EINVAL;
> + if (IS_ERR_OR_NULL(drvdata) || coresight_get_mode(drvdata->csdev))
> + return -EBUSY;
[Severity: Low]
Does this code introduce a regression by checking drvdata for NULL after it
has already been dereferenced?
Looking at seq_state_store(), drvdata is dereferenced during the check for
val >= drvdata->nrseqstate before IS_ERR_OR_NULL(drvdata) is called.
While drvdata is fundamentally guaranteed to be valid in this sysfs context,
making the check technically dead code rather than a reachable crash, should
the validation be moved before the dereference if it is kept?
>
> config->seq_state = val;
[Severity: Medium]
Could this lockless mode check cause a regression?
A concurrent thread could enable the trace session immediately after the
lockless coresight_get_mode() check evaluates to disabled. This would allow
config->seq_state to be modified while the session is actively starting or
already active, completely defeating the patch's stated goal of prohibiting
state modification during an active session.
Should raw_spin_lock(&drvdata->spinlock) be held across both the mode check
and the subsequent state update to prevent this regression?
> return size;
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260924-separate_etm_cfg_v2-v12-0-a2b41d2f7c2b@arm.com?part=1
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v12 03/14] coresight: etm3x: prohibit modifying cntr_val and reset while session is enabled
2026-09-24 17:33 ` [PATCH v12 03/14] coresight: etm3x: prohibit modifying cntr_val and reset " Yeoreum Yun
@ 2026-09-24 17:58 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-09-24 17:58 UTC (permalink / raw)
To: Yeoreum Yun; +Cc: linux-kernel, linux-rt-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] coresight: TOCTOU race bypasses session-enabled check in sysfs stores
--
commit 0c7e96565d9330c7133fb31d646be9050f666c48
Author: Yeoreum Yun <yeoreum.yun@arm.com>
coresight: etm3x: prohibit modifying cntr_val and reset while session is enabled
This commit prevents cntr_val and reset from being modified while a
Coresight ETM session is enabled. Changes to cntr_val would be lost when
the session is disabled, and reset should not be invoked during an active
session.
> diff --git a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
> index b3c67e96a82a4..cdb70a4382eb8 100644
> --- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
> +++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
> @@ -75,6 +75,10 @@ static ssize_t reset_store(struct device *dev,
> if (ret)
> return ret;
>
> + if (IS_ERR_OR_NULL(drvdata->csdev) ||
> + coresight_get_mode(drvdata->csdev))
> + return -EBUSY;
> +
[Severity: Medium]
Is there a race condition here since the mode check happens outside the
spinlock?
If thread A executes this check and sees the mode is disabled, thread B
could then enable tracing (acquiring drvdata->spinlock, applying config to
hardware, and updating the mode).
When thread A proceeds, it will acquire the spinlock and zero the
configuration while the hardware is actively using it. When thread B later
disables tracing, it would partially overwrite the zeroed configuration with
hardware register values.
Should the coresight_get_mode() check be moved inside the spinlock to
prevent this time-of-check to time-of-use race?
> if (val) {
> spin_lock(&drvdata->spinlock);
> memset(config, 0, sizeof(struct etm_config));
[ ... ]
> @@ -744,6 +748,9 @@ static ssize_t cntr_val_store(struct device *dev,
> ret = kstrtoul(buf, 16, &val);
> if (ret)
> return ret;
> + if (IS_ERR_OR_NULL(drvdata->csdev) ||
> + coresight_get_mode(drvdata->csdev))
> + return -EBUSY;
[Severity: Medium]
Does this have the same vulnerability as reset_store()?
The configuration could be corrupted if tracing is enabled by another thread
immediately after coresight_get_mode() returns but before the spinlock is
acquired.
>
> spin_lock(&drvdata->spinlock);
> config->cntr_val[config->cntr_idx] = val;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260924-separate_etm_cfg_v2-v12-0-a2b41d2f7c2b@arm.com?part=3
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v12 08/14] coresight: etm4x: exclude ss_status from drvdata->config
2026-09-24 17:33 ` [PATCH v12 08/14] coresight: etm4x: exclude ss_status from drvdata->config Yeoreum Yun
@ 2026-09-24 18:21 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-09-24 18:21 UTC (permalink / raw)
To: Yeoreum Yun; +Cc: linux-rt-devel, linux-kernel
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] coresight: etm4x: patch fails to preserve perf single-shot clearing behavior
- [Medium] coresight: etm4x: data race on drvdata->ss_status during sysfs update
--
commit 9755069e34bb3af0812d8f23f42579079827c7ca
Author: Yeoreum Yun <yeoreum.yun@arm.com>
coresight: etm4x: exclude ss_status from drvdata->config
The patch moves ss_status out of drvdata->config and into drvdata directly.
It aims to separate configuration from reset and restore states, while
intentionally preserving existing single-shot clearing behavior.
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
[ ... ]
> @@ -572,11 +572,11 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
> etm4x_relaxed_write32(csa, config->res_ctrl[i], TRCRSCTLRn(i));
>
> for (i = 0; i < caps->nr_ss_cmp; i++) {
> - /* always clear status bit on restart if using single-shot */
> + /* always clear status and pending bits on restart if using single-shot */
> if (config->ss_ctrl[i] || config->ss_pe_cmp[i])
> - config->ss_status[i] &= ~TRCSSCSRn_STATUS;
> + drvdata->ss_status[i] &= ~(TRCSSCSRn_STATUS | TRCSSCSRn_PENDING);
[Severity: Medium]
Is it safe to perform a lockless read-modify-write on drvdata->ss_status
here? This can race with or interrupt sysfs stores.
> etm4x_relaxed_write32(csa, config->ss_ctrl[i], TRCSSCCRn(i));
> - etm4x_relaxed_write32(csa, config->ss_status[i], TRCSSCSRn(i));
> + etm4x_relaxed_write32(csa, drvdata->ss_status[i], TRCSSCSRn(i));
[Severity: Medium]
Does this change preserve the previous behavior for perf sessions as
intended?
When a perf session starts, the configuration is zero-initialized. Before
this patch, the code skipped the bit clearing (since config->ss_ctrl[i]
and ss_pe_cmp[i] were 0) but still wrote config->ss_status[i] to
TRCSSCSRn(i). Because ss_status was zero-initialized, this wrote 0 and
effectively cleared the bits.
Now, it writes drvdata->ss_status[i], which might retain previous hardware
state (potentially 1s). Doesn't this leave the bits uncleared and alter the
hardware state configuration instead of preserving it?
> if (etm4x_sspcicrn_present(drvdata, i))
> etm4x_relaxed_write32(csa, config->ss_pe_cmp[i], TRCSSPCICRn(i));
> }
[ ... ]
> @@ -1078,7 +1078,7 @@ static void etm4_disable_hw(struct etmv4_drvdata *drvdata)
>
> /* read the status of the single shot comparators */
> for (i = 0; i < caps->nr_ss_cmp; i++) {
> - config->ss_status[i] =
> + drvdata->ss_status[i] =
> etm4x_relaxed_read32(csa, TRCSSCSRn(i));
[Severity: Medium]
Can this lockless write in hardirq context race with the RMW sysfs stores,
leading to torn updates on drvdata->ss_status?
> }
>
[ ... ]
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
[ ... ]
> @@ -1835,8 +1835,8 @@ static ssize_t sshot_ctrl_store(struct device *dev,
> raw_spin_lock(&drvdata->spinlock);
> idx = config->ss_idx;
> config->ss_ctrl[idx] = FIELD_PREP(TRCSSCCRn_SAC_ARC_RST_MASK, val);
> - /* must clear bit 31 in related status register on programming */
> - config->ss_status[idx] &= ~TRCSSCSRn_STATUS;
> + /* must clear bit 31 and 30 in related status register on programming */
> + drvdata->ss_status[idx] &= ~(TRCSSCSRn_STATUS | TRCSSCSRn_PENDING);
[Severity: Medium]
Can this read-modify-write be interrupted by the hardware PMU path?
If a user writes to the sshot_ctrl or sshot_pe_ctrl sysfs node concurrently
with a perf session stopping (e.g. during a task context switch),
etm4_disable_hw() can trigger in interrupt context.
Because the sysfs path uses raw_spin_lock() rather than an IRQ-safe variant,
the PMU interrupt can preempt this sequence. Won't this lead to lost updates
or corrupted hardware status capability bits when the sysfs thread resumes?
> raw_spin_unlock(&drvdata->spinlock);
> return size;
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260924-separate_etm_cfg_v2-v12-0-a2b41d2f7c2b@arm.com?part=8
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v12 14/14] coresight: etm3x: rename drvdata->config to sysfs_config
2026-09-24 17:33 ` [PATCH v12 14/14] coresight: etm3x: rename drvdata->config to sysfs_config Yeoreum Yun
@ 2026-09-24 18:36 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-09-24 18:36 UTC (permalink / raw)
To: Yeoreum Yun; +Cc: linux-kernel, linux-rt-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] coresight: missed variable rename in etm_disable_sysfs()
--
commit 675c6e2b645cb58619c01f29029e27576619cf41
Author: Yeoreum Yun <yeoreum.yun@arm.com>
coresight: etm3x: rename drvdata->config to sysfs_config
This commit renames the drvdata->config variable to sysfs_config to clarify
its purpose. It also intends to rename local variables referring to this
configuration for better readability.
> diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
> index 0cad9ecb49b61..67f1b71de8811 100644
> --- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
[ ... ]
> @@ -627,7 +627,7 @@ static void etm_disable_sysfs(struct coresight_device *csdev)
> {
> struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> const struct etm_caps *caps = &drvdata->caps;
> - struct etm_config *config = &drvdata->config;
> + struct etm_config *config = &drvdata->sysfs_config;
[Severity: Low]
This isn't a bug, but should this local variable also be renamed to
sysfs_config?
The commit message mentions "also rename local config variables to
sysfs_config where they refer to drvdata->sysfs_config", but it appears
this instance in etm_disable_sysfs() was missed and remains named config.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260924-separate_etm_cfg_v2-v12-0-a2b41d2f7c2b@arm.com?part=14
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2026-09-24 18:36 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-24 17:33 [PATCH v12 00/14] fix several inconsistencies with sysfs configuration in etmX Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 01/14] coresight: etm4x: read-back TRCSEQSTR at disabling and prohibit modifying seq_state while enabling Yeoreum Yun
2026-09-24 17:46 ` sashiko-bot
2026-09-24 17:33 ` [PATCH v12 02/14] coresight: etm4x: prohibit modifying cntr_val while session is enabled Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 03/14] coresight: etm3x: prohibit modifying cntr_val and reset " Yeoreum Yun
2026-09-24 17:58 ` sashiko-bot
2026-09-24 17:33 ` [PATCH v12 04/14] coresight: etm4x: fix inconsistencies with sysfs configuration Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 05/14] coresight: etm3x: " Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 06/14] coresight: etm3x: remove redundant cpu online check on etm_enable_sysfs() Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 07/14] coresight: etm4x: introduce struct etm4_caps Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 08/14] coresight: etm4x: exclude ss_status from drvdata->config Yeoreum Yun
2026-09-24 18:21 ` sashiko-bot
2026-09-24 17:33 ` [PATCH v12 09/14] coresight: etm4x: remove s_ex_level from config Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 10/14] coresight: etm4x: rename local config as curr_config referring drvdata->curr_config Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 11/14] coresight: etm4x: rename drvdata->config to sysfs_config Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 12/14] coresight: etm3x: introduce struct etm_caps Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 13/14] coresight: etm3x: rename local config as curr_config referring drvdata->curr_config Yeoreum Yun
2026-09-24 17:33 ` [PATCH v12 14/14] coresight: etm3x: rename drvdata->config to sysfs_config Yeoreum Yun
2026-09-24 18:36 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®