From: Mike Leach <mike.leach@arm.com>
To: Yeoreum Yun <yeoreum.yun@arm.com>,
James Clark <james.clark@linaro.org>, Leo Yan <leo.yan@arm.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Mathieu Poirier <mathieu.poirier@linaro.org>,
coresight@lists.linaro.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-rt-devel@lists.linux.dev
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
Clark Williams <clrkwllms@kernel.org>,
Steven Rostedt <rostedt@goodmis.org>
Subject: Re: [PATCH v11 9/9] coresight: etm3x: introduce struct etm_caps
Date: Fri, 18 Sep 2026 15:57:32 +0100 [thread overview]
Message-ID: <3f91ecea-05ad-4b95-9352-37ae2203807b@arm.com> (raw)
In-Reply-To: <20260915-separate_etm_cfg_v2-v11-9-d2b258d51747@arm.com>
Reviewed-by: Mike Leach <mike.leach@arm.com>
On 9/15/26 12:34, Yeoreum Yun wrote:
> 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.
>
> 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 f3796162168d4..cb5f18dcdd974 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.
> * @active_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 active_config;
> struct etm_config config;
> diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
> index 12bb38dc596e7..79c7cbe2084de 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->active_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->active_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);
> @@ -562,6 +563,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->active_config;
> struct coresight_device *csdev = drvdata->csdev;
>
> @@ -571,7 +573,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);
> @@ -626,6 +628,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 *active_config = &drvdata->active_config;
> int i;
> @@ -641,7 +644,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] = active_config->cntr_val[i];
>
> config->seq_curr_state = active_config->seq_curr_state;
> @@ -726,7 +729,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);
> @@ -751,16 +756,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 2c8c129228589..36d4673537930 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);
> @@ -115,7 +117,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;
> }
>
> @@ -146,6 +148,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);
> @@ -166,7 +169,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;
> @@ -176,7 +179,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;
> @@ -321,13 +324,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;
>
> /*
> @@ -624,13 +628,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
> @@ -1030,13 +1035,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;
>
> /*
>
next prev parent reply other threads:[~2026-09-18 14:58 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-15 11:34 [PATCH v11 0/9] fix several inconsistencies with sysfs configuration in etmX Yeoreum Yun
2026-09-15 11:34 ` [PATCH v11 1/9] coresight: etm4x: prohibit modifying ss_status and cntr_val while session is enabled Yeoreum Yun
2026-09-15 11:51 ` sashiko-bot
2026-09-15 13:26 ` Yeoreum Yun
2026-09-18 11:14 ` Mike Leach
2026-09-18 17:08 ` Yeoreum Yun
2026-09-15 11:34 ` [PATCH v11 2/9] coresight: etm3x: prohibit modifying cntr_val and reset " Yeoreum Yun
2026-09-15 11:48 ` sashiko-bot
2026-09-15 13:30 ` Yeoreum Yun
2026-09-15 13:55 ` Yeoreum Yun
2026-09-18 11:15 ` Mike Leach
2026-09-15 11:34 ` [PATCH v11 3/9] coresight: etm4x: fix inconsistencies with sysfs configuration Yeoreum Yun
2026-09-15 11:53 ` sashiko-bot
2026-09-15 12:36 ` Yeoreum Yun
2026-09-18 13:49 ` Mike Leach
2026-09-18 17:00 ` Yeoreum Yun
2026-09-15 11:34 ` [PATCH v11 4/9] coresight: etm3x: " Yeoreum Yun
2026-09-15 11:47 ` sashiko-bot
2026-09-15 13:42 ` Yeoreum Yun
2026-09-18 13:57 ` Mike Leach
2026-09-18 17:09 ` Yeoreum Yun
2026-09-15 11:34 ` [PATCH v11 5/9] coresight: etm3x: remove redundant cpu online check on etm_enable_sysfs() Yeoreum Yun
2026-09-18 13:58 ` Mike Leach
2026-09-15 11:34 ` [PATCH v11 6/9] coresight: etm4x: introduce struct etm4_caps Yeoreum Yun
2026-09-18 14:01 ` Mike Leach
2026-09-15 11:34 ` [PATCH v11 7/9] coresight: etm4x: exclude ss_status from drvdata->config Yeoreum Yun
2026-09-15 11:49 ` sashiko-bot
2026-09-15 13:35 ` Yeoreum Yun
2026-09-18 14:04 ` Mike Leach
2026-09-18 17:13 ` Yeoreum Yun
2026-09-15 11:34 ` [PATCH v11 8/9] coresight: etm4x: remove s_ex_level from config Yeoreum Yun
2026-09-18 14:05 ` Mike Leach
2026-09-15 11:34 ` [PATCH v11 9/9] coresight: etm3x: introduce struct etm_caps Yeoreum Yun
2026-09-18 14:57 ` Mike Leach [this message]
2026-09-24 15:25 ` [PATCH v11 0/9] fix several inconsistencies with sysfs configuration in etmX Leo Yan
2026-09-24 17:28 ` Yeoreum Yun
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3f91ecea-05ad-4b95-9352-37ae2203807b@arm.com \
--to=mike.leach@arm.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=bigeasy@linutronix.de \
--cc=clrkwllms@kernel.org \
--cc=coresight@lists.linaro.org \
--cc=gregkh@linuxfoundation.org \
--cc=james.clark@linaro.org \
--cc=leo.yan@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rt-devel@lists.linux.dev \
--cc=mathieu.poirier@linaro.org \
--cc=rostedt@goodmis.org \
--cc=suzuki.poulose@arm.com \
--cc=yeoreum.yun@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.