Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v2 1/5] coresight: etm4x: introduce struct etm4_caps
From: Yeoreum Yun @ 2026-04-12 15:51 UTC (permalink / raw)
  To: Jie Gan
  Cc: coresight, linux-arm-kernel, linux-kernel, suzuki.poulose,
	mike.leach, james.clark, alexander.shishkin, leo.yan
In-Reply-To: <46776f5b-7167-4e99-ad8d-abb221f02aee@oss.qualcomm.com>

Hi Jie,

>
> On 4/10/2026 3:43 PM, Yeoreum Yun wrote:
> > introduce struct etm4_caps to describe ETMv4 capabilities
> > and move capabilities information into it.
> >
> > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> > ---
> >   .../coresight/coresight-etm4x-core.c          | 234 +++++++++---------
> >   .../coresight/coresight-etm4x-sysfs.c         | 185 ++++++++------
> >   drivers/hwtracing/coresight/coresight-etm4x.h | 175 ++++++-------
> >   3 files changed, 327 insertions(+), 267 deletions(-)
> >
> > diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> > index d565a73f0042..6443f3717b37 100644
> > --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> > +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> > @@ -88,8 +88,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 &&
> > +	const struct etmv4_caps *caps = &drvdata->caps;
> > +
> > +	return (n < caps->nr_ss_cmp) && caps->nr_pe &&
> >   	       (drvdata->config.ss_status[n] & TRCSSCSRn_PC);
> >   }
> > @@ -160,17 +161,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;
> > @@ -179,7 +183,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->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,17 +547,17 @@ 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->nrseqstate - 1; i++)
> > +	for (i = 0; i < caps->nrseqstate - 1; 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));
> > @@ -562,10 +567,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;
> > @@ -574,23 +579,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);
> >   		/*
> > @@ -666,19 +671,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->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;
> >   	}
> > @@ -694,11 +700,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;
> > @@ -749,6 +755,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->config;
> >   	struct perf_event_attr max_timestamp = {
> >   		.ATTR_CFG_FLD_timestamp_CFG = U64_MAX,
> > @@ -788,8 +795,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;
> >   	}
> > @@ -837,7 +844,7 @@ 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;
> > @@ -853,7 +860,7 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
> >   	/* 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.
> > @@ -1028,6 +1035,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->config;
> >   	struct coresight_device *csdev = drvdata->csdev;
> >   	struct csdev_access *csa = &csdev->access;
> > @@ -1036,7 +1044,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;
> > @@ -1046,13 +1054,13 @@ 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));
> >   	}
> > @@ -1350,7 +1358,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
> > @@ -1360,8 +1368,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;
> >   	}
> >   }
> > @@ -1374,11 +1382,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;
> >   	/*
> > @@ -1391,7 +1401,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);
> > @@ -1406,71 +1416,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
> > @@ -1481,41 +1491,41 @@ 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);
> > +	caps->nrseqstate = FIELD_GET(TRCIDR5_NUMSEQSTATE_MASK, etmidr5);
> >   	/* 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);
> > @@ -1691,7 +1701,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) {
> > @@ -1869,6 +1879,7 @@ static int etm4_dying_cpu(unsigned int cpu)
> >   static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
> >   {
> >   	int i, ret = 0;
> > +	const struct etmv4_caps *caps = &drvdata->caps;
> >   	struct etmv4_save_state *state;
> >   	struct coresight_device *csdev = drvdata->csdev;
> >   	struct csdev_access *csa;
> > @@ -1905,57 +1916,57 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
> >   	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->nrseqstate - 1; i++)
> > +	for (i = 0; i < caps->nrseqstate - 1; 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));
> >   	}
> > @@ -1967,23 +1978,23 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
> >   	 * 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->trcvmidcctlr0 = 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 */
> > @@ -2000,7 +2011,7 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
> >   	 * 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:
> > @@ -2027,6 +2038,7 @@ static int etm4_cpu_save(struct etmv4_drvdata *drvdata)
> >   static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata)
> >   {
> >   	int i;
> > +	const struct etmv4_caps *caps = &drvdata->caps;
> >   	struct etmv4_save_state *state = drvdata->save_state;
> >   	struct csdev_access *csa = &drvdata->csdev->access;
> > @@ -2036,77 +2048,77 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata)
> >   	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->nrseqstate - 1; i++)
> > +	for (i = 0; i < caps->nrseqstate - 1; 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->trcvmidcctlr0, 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 e9eeea6240d5..3d5f343130bd 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 == false)
> >   		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->nrseqstate-1; i++)
> > +	for (i = 0; i < caps->nrseqstate-1; i++)
>
> from checkpatch:
> CHECK: spaces preferred around '-'
>     coresight-etm4x-sysfs.c:236: caps->nrseqstate-1

Okay I'll change it.

>
> >   		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 == true) {

>
> find so many foo == true && foo == false formats from legacy codes.
> I think it's worth to change all to if (foo) && if (!foo) ?
>
> example here,
>
> if (caps->instrp0)

Agree. This is good chance to remove some legacy formats.

>
> >   		/* start by clearing instruction P0 field */
> >   		config->cfg  &= ~TRCCONFIGR_INSTP0_LOAD_STORE;
> >   		if (config->mode & ETM_MODE_LOAD)
> > @@ -323,45 +334,45 @@ 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 == true))
> >   		config->cfg |= TRCCONFIGR_BB;
>
> <...>
>
> > @@ -1037,46 +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_event;
> > -	u8				nr_resource;
> > -	u8				nr_ss_cmp;
> > +	struct etmv4_caps 		caps;
>
> reported by checkpatch:
> WARNING: please, no space before tabs

Thanks.

>
> >   	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		config;
>

--
Sincerely,
Yeoreum Yun


^ permalink raw reply

* Re: [PATCH net-next v4 1/2] dt-bindings: net: ti: k3-am654-cpsw-nuss: Add ti,j722s-cpsw-nuss compatible
From: patchwork-bot+netdevbpf @ 2026-04-12 15:50 UTC (permalink / raw)
  To: Nora Schiffer
  Cc: andrew+netdev, davem, edumazet, kuba, pabeni, nm, vigneshr,
	kristo, s-vadapalli, rogerq, robh, krzk+dt, conor+dt, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux
In-Reply-To: <191e9f7e3a6c14eabe891a98c5fb646766479c0a.1775558273.git.nora.schiffer@ew.tq-group.com>

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Tue,  7 Apr 2026 12:48:01 +0200 you wrote:
> The J722S CPSW3G is mostly identical to the AM64's, but additionally
> supports SGMII. The AM64 compatible ti,am642-cpsw-nuss is used as a
> fallback.
> 
> Signed-off-by: Nora Schiffer <nora.schiffer@ew.tq-group.com>
> ---
> 
> [...]

Here is the summary with links:
  - [net-next,v4,1/2] dt-bindings: net: ti: k3-am654-cpsw-nuss: Add ti,j722s-cpsw-nuss compatible
    https://git.kernel.org/netdev/net-next/c/f757a2da6df5
  - [net-next,v4,2/2] net: ethernet: ti: am65-cpsw: add support for J722S SoC family
    https://git.kernel.org/netdev/net-next/c/436e9e48ca51

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




^ permalink raw reply

* Re: [PATCH v2 2/5] coresight: etm4x: exclude ss_status from drvdata->config
From: Yeoreum Yun @ 2026-04-12 15:48 UTC (permalink / raw)
  To: Jie Gan
  Cc: coresight, linux-arm-kernel, linux-kernel, suzuki.poulose,
	mike.leach, james.clark, alexander.shishkin, leo.yan
In-Reply-To: <a8d11f92-2af8-46e7-9098-18a835c6ec8a@oss.qualcomm.com>

Hi Jie,

>
>
> On 4/10/2026 3:43 PM, Yeoreum Yun wrote:
> > 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, move it to etm4x_caps.
> > This includes remove TRCSSCRn from configurable item and
> > remove saving in etm4_disable_hw().
> >
> > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> > ---
> >   .../hwtracing/coresight/coresight-etm4x-cfg.c  |  1 -
> >   .../hwtracing/coresight/coresight-etm4x-core.c | 18 +++++-------------
> >   .../coresight/coresight-etm4x-sysfs.c          |  7 ++-----
> >   drivers/hwtracing/coresight/coresight-etm4x.h  |  3 ++-
> >   4 files changed, 9 insertions(+), 20 deletions(-)
> >
> > diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
> > index c302072b293a..d14d7c8a23e5 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 6443f3717b37..b7abb171f523 100644
> > --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> > +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> > @@ -91,7 +91,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 &&
> > -	       (drvdata->config.ss_status[n] & TRCSSCSRn_PC);
> > +	       (caps->ss_status[n] & TRCSSCSRn_PC);
> >   }
> >   u64 etm4x_sysreg_read(u32 offset, bool _relaxed, bool _64bit)
> > @@ -571,11 +571,9 @@ 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 */
> > -		if (config->ss_ctrl[i] || config->ss_pe_cmp[i])
> > -			config->ss_status[i] &= ~TRCSSCSRn_STATUS;
> >   		etm4x_relaxed_write32(csa, config->ss_ctrl[i], TRCSSCCRn(i));
> > -		etm4x_relaxed_write32(csa, config->ss_status[i], TRCSSCSRn(i));
> > +		/* always clear status bit on restart if using single-shot */
>
> the clear step for the status bit has been removed. but the comment still
> here.
>
> I think we cannot remove the clear step. The hardware requires the STATUS
> bit to be cleared before re-arming a single-shot comparator; failing to do
> so means the comparator will not fire on the next trace session

This one is intended. if you see the patch:

+  /* always clear status bit on restart if using single-shot */
+  etm4x_relaxed_write32(csa, caps->ss_status[i], TRCSSCSRn(i));

cap->ss_status[i] is initialised by etm4_init_arch_data() cleared
STATUS & PENDING bit. so the comment is still valid.


Thanks.

[...]

--
Sincerely,
Yeoreum Yun


^ permalink raw reply

* [GIT PULL] Kbuild and Kconfig changes for v7.1
From: Nicolas Schier @ 2026-04-12 15:46 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Alexander Coffin, Ard Biesheuvel, Arnd Bergmann, Bill Wendling,
	David Howells, Dodji Seketeli, H. Peter Anvin, Helge Deller,
	John Moon, Jonathan Corbet, Josh Poimboeuf, Justin Stitt,
	Kees Cook, Masahiro Yamada, Nathan Chancellor, Nick Desaulniers,
	Shuah Khan, Song Liu, Thomas Weißschuh, Yonghong Song,
	kernel-team, linux-arm-kernel, linux-efi, linux-hexagon,
	linux-kbuild, linux-kernel, linux-parisc, linux-s390,
	linuxppc-dev, llvm, loongarch

[-- Attachment #1: Type: text/plain, Size: 9589 bytes --]

Hi Linus,

please pull these changes to Kbuild and Kconfig for v7.1.  Please let me
know if anything is incorrect and not matching your standards.

All changes have been in -next, most for several cycles without reported
problems.

Thanks and kind regards,
Nicolas

---

The following changes since commit 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f:

  Linux 7.0-rc1 (2026-02-22 13:18:59 -0800)

are available in the Git repository at:

  ssh://git@gitolite.kernel.org/pub/scm/linux/kernel/git/kbuild/linux.git tags/kbuild-7.1-1

for you to fetch changes up to 404927758daac5ec4594071e033c1fa6ee9ca9b6:

  kbuild: expand inlining hints with -fdiagnostics-show-inlining-chain (2026-04-07 21:48:44 +0200)

----------------------------------------------------------------
Kbuild/Kconfig updates for 7.1

Kbuild changes
==============

  * tools/build: Reject unexpected values for LLVM=

  * kbuild: uapi: remove usage of toolchain headers

  * kbuild: Switch from '-fms-extensions' to '-fms-anonymous-structs'
    when available (currently: clang >= 23.0.0)

  * kbuild: Reduce the number of compiler-generated suffixes for clang
    thin-lto build

  * kbuild: reduce output spam ("GEN Makefile") when building out of tree

  * check-uapi: improve portability for testing headers

  * uapi: also test UAPI headers against C++ compilers

  * kbuild: vdso_install: drop build ID architecture allow-list

  * checksyscalls: only run when necessary

  * Documentation: kbuild: Update the debug information notes in
    reproducible-builds.rst

  * kconfig: forbid multiple entries with the same symbol in a choice

  * kbuild: expand inlining hints with -fdiagnostics-show-inlining-chain


Kconfig changes
===============

  * kconfig: Error out on duplicated kconfig inclusion


Cc: Alexander Coffin <alex@cyberialabs.net>
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Bill Wendling <morbo@google.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Dodji Seketeli <dodji@seketeli.org>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Helge Deller <deller@gmx.de>
Cc: John Moon <john@jmoon.dev>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Josh Poimboeuf <jpoimboe@kernel.org>
Cc: Justin Stitt <justinstitt@google.com>
Cc: Kees Cook <kees@kernel.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nick Desaulniers <nick.desaulniers+lkml@gmail.com>
Cc: Shuah Khan <skhan@linuxfoundation.org>
Cc: Song Liu <song@kernel.org>
Cc: Thomas Weißschuh <linux@weissschuh.net>
Cc: Yonghong Song <yonghong.song@linux.dev>
Cc: kernel-team@fb.com
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-efi@vger.kernel.org
Cc: linux-hexagon@vger.kernel.org
Cc: linux-kbuild@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-parisc@vger.kernel.org
Cc: linux-s390@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: llvm@lists.linux.dev
Cc: loongarch@lists.linux.dev

----------------------------------------------------------------
Arnd Bergmann (3):
      check-uapi: link into shared objects
      check-uapi: honor ${CROSS_COMPILE} setting
      check-uapi: use dummy libc includes

Justin Stitt (1):
      kbuild: expand inlining hints with -fdiagnostics-show-inlining-chain

Masahiro Yamada (1):
      kconfig: forbid multiple entries with the same symbol in a choice

Nathan Chancellor (3):
      kbuild: Consolidate C dialect options
      kbuild: Use '-fms-anonymous-structs' if it is available
      Documentation: kbuild: Update the debug information notes in reproducible-builds.rst

Nicolas Schier (1):
      kconfig: Error out on duplicated kconfig inclusion

Thomas Weißschuh (25):
      Documentation/llvm: drop note about LLVM=0
      tools/build: Reject unexpected values for LLVM=
      hexagon: uapi: Fix structure alignment attribute
      kbuild: uapi: test linux/bpf_perf_event.h on powerpc
      kbuild: uapi: deduplicate linux/bpf_perf_event.h exclusions
      kbuild: uapi: completely exclude linux/bpf_perf_event.h on nios2
      kbuild: uapi: only use dummy-include for headers which use libc
      kbuild: uapi: provide stub includes for some libc headers
      kbuild: uapi: use custom stub headers instead of libc ones
      kbuild: uapi: simplify libc dependency logic
      kbuild: uapi: remove now unneeded guard headers
      kbuild: reduce output spam when building out of tree
      kbuild: uapi: move some compiler arguments out of the command definition
      kbuild: uapi: move all include path flags together
      kbuild: uapi: handle UML in architecture-specific exclusion lists
      kbuild: uapi: provide a C++ compatible dummy definition of NULL
      kbuild: uapi: also test UAPI headers against C++ compilers
      kbuild: vdso_install: split out the readelf invocation
      kbuild: vdso_install: hide readelf warnings
      kbuild: vdso_install: gracefully handle images without build ID
      kbuild: vdso_install: drop build ID architecture allow-list
      checksyscalls: move path to reference table to a variable
      checksyscalls: fail on all intermediate errors
      checksyscalls: only run when necessary
      checksyscalls: move instance functionality into generic code

Yonghong Song (1):
      kbuild: Reduce the number of compiler-generated suffixes for clang thin-lto build

 Documentation/kbuild/llvm.rst                      |  4 --
 Documentation/kbuild/reproducible-builds.rst       |  7 ++-
 Kbuild                                             | 14 +++--
 Makefile                                           | 35 +++++++++---
 arch/arm64/kernel/vdso32/Makefile                  |  3 +-
 arch/hexagon/include/uapi/asm/sigcontext.h         |  2 +-
 arch/loongarch/vdso/Makefile                       |  2 +-
 arch/mips/Makefile                                 |  6 +-
 arch/parisc/boot/compressed/Makefile               |  2 +-
 arch/powerpc/boot/Makefile                         |  3 +-
 arch/s390/Makefile                                 |  3 +-
 arch/s390/purgatory/Makefile                       |  3 +-
 arch/x86/Makefile                                  |  6 +-
 arch/x86/boot/compressed/Makefile                  |  6 +-
 drivers/firmware/efi/libstub/Makefile              |  3 +-
 init/Kconfig                                       |  5 ++
 scripts/Makefile.vdsoinst                          |  7 ++-
 scripts/Makefile.warn                              |  5 --
 scripts/check-uapi.sh                              | 19 ++++---
 scripts/checksyscalls.sh                           | 11 +++-
 scripts/kconfig/lexer.l                            |  4 +-
 scripts/kconfig/lkc.h                              |  3 +-
 scripts/kconfig/parser.y                           | 15 ++---
 scripts/kconfig/tests/err_repeated_inc/Kconfig     |  3 +
 .../kconfig/tests/err_repeated_inc/Kconfig.inc1    |  4 ++
 .../kconfig/tests/err_repeated_inc/Kconfig.inc2    |  3 +
 .../kconfig/tests/err_repeated_inc/Kconfig.inc3    |  1 +
 scripts/kconfig/tests/err_repeated_inc/__init__.py | 10 ++++
 .../kconfig/tests/err_repeated_inc/expected_stderr |  2 +
 scripts/kconfig/util.c                             | 31 ++++++++++-
 tools/scripts/Makefile.include                     |  2 +
 usr/dummy-include/endian.h                         |  0
 usr/dummy-include/limits.h                         |  8 +++
 usr/dummy-include/netinet/if_ether.h               |  0
 usr/dummy-include/netinet/in.h                     |  0
 usr/dummy-include/stdbool.h                        |  7 ---
 usr/dummy-include/stddef.h                         | 13 +++++
 usr/dummy-include/stdint.h                         | 17 ++++++
 usr/dummy-include/stdlib.h                         |  7 ---
 usr/dummy-include/string.h                         | 12 ++++
 usr/dummy-include/sys/ioctl.h                      |  0
 usr/dummy-include/sys/socket.h                     | 12 ++++
 usr/dummy-include/sys/time.h                       |  3 +
 usr/dummy-include/sys/types.h                      |  0
 usr/dummy-include/time.h                           |  0
 usr/dummy-include/unistd.h                         |  0
 usr/include/Makefile                               | 65 ++++++++++++++--------
 47 files changed, 251 insertions(+), 117 deletions(-)
 create mode 100644 scripts/kconfig/tests/err_repeated_inc/Kconfig
 create mode 100644 scripts/kconfig/tests/err_repeated_inc/Kconfig.inc1
 create mode 100644 scripts/kconfig/tests/err_repeated_inc/Kconfig.inc2
 create mode 100644 scripts/kconfig/tests/err_repeated_inc/Kconfig.inc3
 create mode 100644 scripts/kconfig/tests/err_repeated_inc/__init__.py
 create mode 100644 scripts/kconfig/tests/err_repeated_inc/expected_stderr
 create mode 100644 usr/dummy-include/endian.h
 create mode 100644 usr/dummy-include/limits.h
 create mode 100644 usr/dummy-include/netinet/if_ether.h
 create mode 100644 usr/dummy-include/netinet/in.h
 delete mode 100644 usr/dummy-include/stdbool.h
 create mode 100644 usr/dummy-include/stddef.h
 create mode 100644 usr/dummy-include/stdint.h
 delete mode 100644 usr/dummy-include/stdlib.h
 create mode 100644 usr/dummy-include/string.h
 create mode 100644 usr/dummy-include/sys/ioctl.h
 create mode 100644 usr/dummy-include/sys/socket.h
 create mode 100644 usr/dummy-include/sys/time.h
 create mode 100644 usr/dummy-include/sys/types.h
 create mode 100644 usr/dummy-include/time.h
 create mode 100644 usr/dummy-include/unistd.h

-- 
Nicolas

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v2 4/5] coresight: etm3x: introduce struct etm_caps
From: Yeoreum Yun @ 2026-04-12 15:43 UTC (permalink / raw)
  To: Jie Gan
  Cc: coresight, linux-arm-kernel, linux-kernel, suzuki.poulose,
	mike.leach, james.clark, alexander.shishkin, leo.yan
In-Reply-To: <4feaf157-4015-471e-accf-d588e2345c13@oss.qualcomm.com>

Hi Jie,

>
>
> On 4/10/2026 3:43 PM, 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   | 40 +++++++++++--------
> >   .../coresight/coresight-etm3x-core.c          | 33 ++++++++-------
> >   .../coresight/coresight-etm3x-sysfs.c         | 14 ++++---
> >   3 files changed, 52 insertions(+), 35 deletions(-)
> >
> > diff --git a/drivers/hwtracing/coresight/coresight-etm.h b/drivers/hwtracing/coresight/coresight-etm.h
> > index 1d753cca2943..6fda26039db8 100644
> > --- a/drivers/hwtracing/coresight/coresight-etm.h
> > +++ b/drivers/hwtracing/coresight/coresight-etm.h
> > @@ -140,6 +140,28 @@
> >   				 ETM_ADD_COMP_0		|	\
> >   				 ETM_EVENT_NOT_A)
> > +/**
> > + * struct etmv4_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.
> > + */
> > +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;
> > +};
> > +
> >   /**
> >    * struct etm_config - configuration information related to an ETM
> >    * @mode:	controls various modes supported by this ETM/PTM.
> > @@ -212,19 +234,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.
> >    * @config:	structure holding configuration parameters.
> >    */
> > @@ -234,19 +249,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		config;
> >   };
> > diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
> > index a547a6d2e0bd..b7e977defb1c 100644
> > --- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
> > +++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
> > @@ -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->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);
> > @@ -572,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++)
>
> caps undeclared.
>
> Thanks,
> Jie

Sorry to mistake. I'll change.


>
> >   		config->cntr_val[i] = etm_readl(drvdata, ETMCNTVRn(i));
> >   	etm_set_pwrdwn(drvdata);
> > @@ -754,7 +755,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);
> > @@ -779,16 +782,18 @@ 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 = !!(drvdata->etmccer & ETMCCER_TIMESTAMP);
>
> caps->timestamp = !!(etmccer & ETMCCER_TIMESTAMP);
>
> > -	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 = !!(drvdata->etmccr & ETMCCR_FIFOFULL);
>
> 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 762109307b86..0d8dac29d055 100644
> > --- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
> > +++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
> > @@ -111,6 +111,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);
> > @@ -131,7 +132,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;
> > @@ -141,7 +142,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;
> > @@ -286,13 +287,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;
> >   	/*
> > @@ -589,13 +591,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
> > @@ -999,13 +1002,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;
> >   	/*
>

--
Sincerely,
Yeoreum Yun


^ permalink raw reply

* Re: [RFC net-next v5 0/3] Add RSS and LRO support
From: Jakub Kicinski @ 2026-04-12 14:54 UTC (permalink / raw)
  To: Frank Wunderlich
  Cc: linux, nbd, sean.wang, lorenzo, andrew+netdev, davem, edumazet,
	pabeni, matthias.bgg, angelogioacchino.delregno, linux, daniel,
	netdev, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <trinity-1304ecb5-9a3f-4e37-b2c6-bcd7f35c2921-1775995067670@trinity-msg-rest-gmx-gmx-live-579dcf886d-nkpds>

On Sun, 12 Apr 2026 11:57:47 +0000 Frank Wunderlich wrote:
> some time has passed without a single comment, so i just send a friendly reminder ;)

You have a lot of people in the To:
Could you clarify who you expect to action these patches?
Patches are an RFC and I suppose ain't nobody got much comments?


^ permalink raw reply

* Re: [PATCH v2 2/5] coresight: etm4x: exclude ss_status from drvdata->config
From: Jie Gan @ 2026-04-12 14:40 UTC (permalink / raw)
  To: Yeoreum Yun, coresight, linux-arm-kernel, linux-kernel
  Cc: suzuki.poulose, mike.leach, james.clark, alexander.shishkin,
	leo.yan
In-Reply-To: <20260410074310.2693385-3-yeoreum.yun@arm.com>



On 4/10/2026 3:43 PM, Yeoreum Yun wrote:
> 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, move it to etm4x_caps.
> This includes remove TRCSSCRn from configurable item and
> remove saving in etm4_disable_hw().
> 
> Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> ---
>   .../hwtracing/coresight/coresight-etm4x-cfg.c  |  1 -
>   .../hwtracing/coresight/coresight-etm4x-core.c | 18 +++++-------------
>   .../coresight/coresight-etm4x-sysfs.c          |  7 ++-----
>   drivers/hwtracing/coresight/coresight-etm4x.h  |  3 ++-
>   4 files changed, 9 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-cfg.c b/drivers/hwtracing/coresight/coresight-etm4x-cfg.c
> index c302072b293a..d14d7c8a23e5 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 6443f3717b37..b7abb171f523 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -91,7 +91,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 &&
> -	       (drvdata->config.ss_status[n] & TRCSSCSRn_PC);
> +	       (caps->ss_status[n] & TRCSSCSRn_PC);
>   }
>   
>   u64 etm4x_sysreg_read(u32 offset, bool _relaxed, bool _64bit)
> @@ -571,11 +571,9 @@ 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 */
> -		if (config->ss_ctrl[i] || config->ss_pe_cmp[i])
> -			config->ss_status[i] &= ~TRCSSCSRn_STATUS;
>   		etm4x_relaxed_write32(csa, config->ss_ctrl[i], TRCSSCCRn(i));
> -		etm4x_relaxed_write32(csa, config->ss_status[i], TRCSSCSRn(i));
> +		/* always clear status bit on restart if using single-shot */

the clear step for the status bit has been removed. but the comment 
still here.

I think we cannot remove the clear step. The hardware requires the 
STATUS bit to be cleared before re-arming a single-shot comparator; 
failing to do so means the comparator will not fire on the next trace 
session

Thanks,
Jie

> +		etm4x_relaxed_write32(csa, caps->ss_status[i], TRCSSCSRn(i));
>   		if (etm4x_sspcicrn_present(drvdata, i))
>   			etm4x_relaxed_write32(csa, config->ss_pe_cmp[i], TRCSSPCICRn(i));
>   	}
> @@ -1053,12 +1051,6 @@ 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 < 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 < caps->nr_cntr; i++) {
>   		config->cntr_val[i] =
> @@ -1501,8 +1493,8 @@ 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));
> +		caps->ss_status[i] = etm4x_relaxed_read32(csa, TRCSSCSRn(i));
> +		caps->ss_status[i] &= ~(TRCSSCSRn_STATUS | TRCSSCSRn_PENDING);
>   	}
>   	/* 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 3d5f343130bd..c794fc9de5b6 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> @@ -1832,8 +1832,6 @@ 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;
>   	raw_spin_unlock(&drvdata->spinlock);
>   	return size;
>   }
> @@ -1844,10 +1842,11 @@ static ssize_t sshot_status_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;
>   
>   	raw_spin_lock(&drvdata->spinlock);
> -	val = config->ss_status[config->ss_idx];
> +	val = caps->ss_status[config->ss_idx];
>   	raw_spin_unlock(&drvdata->spinlock);
>   	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
>   }
> @@ -1882,8 +1881,6 @@ 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;
>   	raw_spin_unlock(&drvdata->spinlock);
>   	return size;
>   }
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
> index 3e20561672dc..57508d301327 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.h
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.h
> @@ -213,6 +213,7 @@
>   #define TRCACATRn_EXLEVEL_MASK			GENMASK(14, 8)
>   
>   #define TRCSSCSRn_STATUS			BIT(31)
> +#define TRCSSCSRn_PENDING			BIT(30)
>   #define TRCSSCCRn_SAC_ARC_RST_MASK		GENMASK(24, 0)
>   
>   #define TRCSSPCICRn_PC_MASK			GENMASK(7, 0)
> @@ -898,6 +899,7 @@ struct etmv4_caps {
>   	bool	atbtrig : 1;
>   	bool	lpoverride : 1;
>   	bool	skip_power_up : 1;
> +	u32	ss_status[ETM_MAX_SS_CMP];
>   };
>   
>   /**
> @@ -976,7 +978,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];



^ permalink raw reply

* Re: [PATCH v2 1/5] coresight: etm4x: introduce struct etm4_caps
From: Jie Gan @ 2026-04-12 14:35 UTC (permalink / raw)
  To: Yeoreum Yun, coresight, linux-arm-kernel, linux-kernel
  Cc: suzuki.poulose, mike.leach, james.clark, alexander.shishkin,
	leo.yan
In-Reply-To: <20260410074310.2693385-2-yeoreum.yun@arm.com>



On 4/10/2026 3:43 PM, Yeoreum Yun wrote:
> introduce struct etm4_caps to describe ETMv4 capabilities
> and move capabilities information into it.
> 
> Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> ---
>   .../coresight/coresight-etm4x-core.c          | 234 +++++++++---------
>   .../coresight/coresight-etm4x-sysfs.c         | 185 ++++++++------
>   drivers/hwtracing/coresight/coresight-etm4x.h | 175 ++++++-------
>   3 files changed, 327 insertions(+), 267 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index d565a73f0042..6443f3717b37 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -88,8 +88,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 &&
> +	const struct etmv4_caps *caps = &drvdata->caps;
> +
> +	return (n < caps->nr_ss_cmp) && caps->nr_pe &&
>   	       (drvdata->config.ss_status[n] & TRCSSCSRn_PC);
>   }
>   
> @@ -160,17 +161,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;
> @@ -179,7 +183,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->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,17 +547,17 @@ 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->nrseqstate - 1; i++)
> +	for (i = 0; i < caps->nrseqstate - 1; 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));
> @@ -562,10 +567,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;
> @@ -574,23 +579,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);
>   
>   		/*
> @@ -666,19 +671,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->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;
>   	}
> @@ -694,11 +700,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;
> @@ -749,6 +755,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->config;
>   	struct perf_event_attr max_timestamp = {
>   		.ATTR_CFG_FLD_timestamp_CFG = U64_MAX,
> @@ -788,8 +795,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;
>   	}
>   
> @@ -837,7 +844,7 @@ 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;
>   
> @@ -853,7 +860,7 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
>   
>   	/* 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.
> @@ -1028,6 +1035,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->config;
>   	struct coresight_device *csdev = drvdata->csdev;
>   	struct csdev_access *csa = &csdev->access;
> @@ -1036,7 +1044,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;
> @@ -1046,13 +1054,13 @@ 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));
>   	}
> @@ -1350,7 +1358,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
> @@ -1360,8 +1368,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;
>   	}
>   }
>   
> @@ -1374,11 +1382,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;
>   
>   	/*
> @@ -1391,7 +1401,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);
> @@ -1406,71 +1416,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
> @@ -1481,41 +1491,41 @@ 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);
> +	caps->nrseqstate = FIELD_GET(TRCIDR5_NUMSEQSTATE_MASK, etmidr5);
>   	/* 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);
> @@ -1691,7 +1701,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) {
> @@ -1869,6 +1879,7 @@ static int etm4_dying_cpu(unsigned int cpu)
>   static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
>   {
>   	int i, ret = 0;
> +	const struct etmv4_caps *caps = &drvdata->caps;
>   	struct etmv4_save_state *state;
>   	struct coresight_device *csdev = drvdata->csdev;
>   	struct csdev_access *csa;
> @@ -1905,57 +1916,57 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
>   
>   	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->nrseqstate - 1; i++)
> +	for (i = 0; i < caps->nrseqstate - 1; 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));
>   	}
> @@ -1967,23 +1978,23 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
>   	 * 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->trcvmidcctlr0 = 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 */
> @@ -2000,7 +2011,7 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
>   	 * 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:
> @@ -2027,6 +2038,7 @@ static int etm4_cpu_save(struct etmv4_drvdata *drvdata)
>   static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata)
>   {
>   	int i;
> +	const struct etmv4_caps *caps = &drvdata->caps;
>   	struct etmv4_save_state *state = drvdata->save_state;
>   	struct csdev_access *csa = &drvdata->csdev->access;
>   
> @@ -2036,77 +2048,77 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata)
>   	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->nrseqstate - 1; i++)
> +	for (i = 0; i < caps->nrseqstate - 1; 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->trcvmidcctlr0, 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 e9eeea6240d5..3d5f343130bd 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 == false)
>   		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->nrseqstate-1; i++)
> +	for (i = 0; i < caps->nrseqstate-1; i++)

from checkpatch:
CHECK: spaces preferred around '-'
     coresight-etm4x-sysfs.c:236: caps->nrseqstate-1

>   		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 == true) {

find so many foo == true && foo == false formats from legacy codes.
I think it's worth to change all to if (foo) && if (!foo) ?

example here,

if (caps->instrp0)

>   		/* start by clearing instruction P0 field */
>   		config->cfg  &= ~TRCCONFIGR_INSTP0_LOAD_STORE;
>   		if (config->mode & ETM_MODE_LOAD)
> @@ -323,45 +334,45 @@ 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 == true))
>   		config->cfg |= TRCCONFIGR_BB;

<...>

> @@ -1037,46 +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_event;
> -	u8				nr_resource;
> -	u8				nr_ss_cmp;
> +	struct etmv4_caps 		caps;

reported by checkpatch:
WARNING: please, no space before tabs

Thanks,
Jie

>   	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		config;



^ permalink raw reply

* Re: [PATCH v2 4/5] coresight: etm3x: introduce struct etm_caps
From: Jie Gan @ 2026-04-12 14:24 UTC (permalink / raw)
  To: Yeoreum Yun, coresight, linux-arm-kernel, linux-kernel
  Cc: suzuki.poulose, mike.leach, james.clark, alexander.shishkin,
	leo.yan
In-Reply-To: <4feaf157-4015-471e-accf-d588e2345c13@oss.qualcomm.com>



On 4/12/2026 10:21 PM, Jie Gan wrote:
> 
> 
> On 4/10/2026 3:43 PM, 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   | 40 +++++++++++--------
>>   .../coresight/coresight-etm3x-core.c          | 33 ++++++++-------
>>   .../coresight/coresight-etm3x-sysfs.c         | 14 ++++---
>>   3 files changed, 52 insertions(+), 35 deletions(-)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-etm.h b/drivers/ 
>> hwtracing/coresight/coresight-etm.h
>> index 1d753cca2943..6fda26039db8 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm.h
>> +++ b/drivers/hwtracing/coresight/coresight-etm.h
>> @@ -140,6 +140,28 @@
>>                    ETM_ADD_COMP_0        |    \
>>                    ETM_EVENT_NOT_A)
>> +/**
>> + * struct etmv4_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.
>> + */
>> +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;
>> +};
>> +
>>   /**
>>    * struct etm_config - configuration information related to an ETM
>>    * @mode:    controls various modes supported by this ETM/PTM.
>> @@ -212,19 +234,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.
>>    * @config:    structure holding configuration parameters.
>>    */
>> @@ -234,19 +249,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        config;
>>   };
>> diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/ 
>> drivers/hwtracing/coresight/coresight-etm3x-core.c
>> index a547a6d2e0bd..b7e977defb1c 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
>> +++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
>> @@ -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->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);
>> @@ -572,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++)
> 
> caps undeclared.
> 
> Thanks,
> Jie

Have comments below in previous message... ignore the mistake to end the 
message...

> 
>>           config->cntr_val[i] = etm_readl(drvdata, ETMCNTVRn(i));
>>       etm_set_pwrdwn(drvdata);
>> @@ -754,7 +755,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);
>> @@ -779,16 +782,18 @@ 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 = !!(drvdata->etmccer & ETMCCER_TIMESTAMP);
> 
> caps->timestamp = !!(etmccer & ETMCCER_TIMESTAMP);
> 
>> -    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 = !!(drvdata->etmccr & ETMCCR_FIFOFULL);
> 
> 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 762109307b86..0d8dac29d055 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
>> +++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
>> @@ -111,6 +111,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);
>> @@ -131,7 +132,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;
>> @@ -141,7 +142,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;
>> @@ -286,13 +287,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;
>>       /*
>> @@ -589,13 +591,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
>> @@ -999,13 +1002,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;
>>       /*
> 



^ permalink raw reply

* Re: [PATCH net-next] net: stmmac: enable RPS and RBU interrupts
From: Russell King (Oracle) @ 2026-04-12 14:23 UTC (permalink / raw)
  To: Maxime Chevallier
  Cc: Andrew Lunn, Alexandre Torgue, Andrew Lunn, David S. Miller,
	Eric Dumazet, Jakub Kicinski, linux-arm-kernel, linux-stm32,
	netdev, Paolo Abeni, Sam Edwards
In-Reply-To: <266998d8-7e38-4bae-a4df-2f889538fe88@bootlin.com>

On Sun, Apr 12, 2026 at 04:01:59PM +0200, Maxime Chevallier wrote:
> Hi Russell,
> 
> On 10/04/2026 15:07, Russell King (Oracle) wrote:
> > Enable receive process stopped and receive buffer unavailable
> > interrupts, so that the statistic counters can be updated.
> > 
> > Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
> > ---
> > Since we are seeing receive buffer exhaustion on several platforms,
> > let's enable the interrupts so the statistics we publish via ethtool -S
> > actually work to aid diagnosis. I've been in two minds about whether
> > to send this patch, but given the problems with stmmac at the moment,
> > I think it should be merged.
> 
> Looks like my reply to your original RFC was lost in limbo as the review/test tags are missing.

Thanks. Unfortunately, I can't run iperf3 against stmmac on the Jetson
NX because stmmac just totally screws itself (at the first RBU, the
receive side irrevocably collapses.)

Against i.MX6 (which is limited to around 480Mbps,) it's recoverable by
taking the interface down and back up a couple of times.

Against x86 (which will saturate the link) its pretty much
irrecoverable without entire system reboot - if one tries the down+up,
we then get arm-smmu errors because it seems that, despite stmmac being
reset, it still attempts to access a previous receive buffer from
before the down/up sometime after the up. Moreover, transmit stops
working - packets get queued but they are never processed by the
hardware. This is a scenario that I can only rarely test myself (as
it depends on my physical location.)

As the dwmac 5.0 core receive path seems to lock up after the first
RBU, I never see more than one of those at a time.

Right now, I consider this pretty much unsolvable - I've spent quite
some time looking at it and trying various approaches, nothing seems
to fix it. However, adding dma_rmb() in the descriptor cleanup/refill
paths does seem to improve the situation a little with the 480Mbps
case, because I think it means that we're reading the descriptors in
a more timely manner after the hardware has updated them.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!


^ permalink raw reply

* [PATCH v2 3/4] KVM: arm64: sefltests: Add basic NV selftest
From: Wei-Lin Chang @ 2026-04-12 14:22 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm, kvm, linux-kselftest, linux-kernel
  Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Suzuki K Poulose,
	Zenghui Yu, Catalin Marinas, Will Deacon, Paolo Bonzini,
	Shuah Khan, Wei-Lin Chang
In-Reply-To: <20260412142216.3806482-1-weilin.chang@arm.com>

This selftest simply starts an L1, which starts its own guest (L2). L2
runs without stage-1 and 2 translations, it calls an HVC to jump back
to L1.

Signed-off-by: Wei-Lin Chang <weilin.chang@arm.com>
---
 tools/testing/selftests/kvm/Makefile.kvm      |   1 +
 .../selftests/kvm/arm64/hello_nested.c        | 103 ++++++++++++++++++
 2 files changed, 104 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/arm64/hello_nested.c

diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
index 3dc3e39f7025..e8c108e0c487 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -168,6 +168,7 @@ TEST_GEN_PROGS_arm64 += arm64/arch_timer_edge_cases
 TEST_GEN_PROGS_arm64 += arm64/at
 TEST_GEN_PROGS_arm64 += arm64/debug-exceptions
 TEST_GEN_PROGS_arm64 += arm64/hello_el2
+TEST_GEN_PROGS_arm64 += arm64/hello_nested
 TEST_GEN_PROGS_arm64 += arm64/host_sve
 TEST_GEN_PROGS_arm64 += arm64/hypercalls
 TEST_GEN_PROGS_arm64 += arm64/external_aborts
diff --git a/tools/testing/selftests/kvm/arm64/hello_nested.c b/tools/testing/selftests/kvm/arm64/hello_nested.c
new file mode 100644
index 000000000000..97387e4697b3
--- /dev/null
+++ b/tools/testing/selftests/kvm/arm64/hello_nested.c
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * hello_nested - Go from vEL2 to EL1 then back
+ */
+
+#include "nested.h"
+#include "processor.h"
+#include "test_util.h"
+#include "ucall.h"
+
+#define XLATE2GPA	(0xABCD)
+#define L2STACKSZ	(0x100)
+
+/*
+ * TPIDR_EL2 is used to store vcpu id, so save and restore it.
+ */
+static vm_paddr_t ucall_translate_to_gpa(void *gva)
+{
+	vm_paddr_t gpa;
+	u64 vcpu_id = read_sysreg(tpidr_el2);
+
+	GUEST_SYNC2(XLATE2GPA, gva);
+
+	/* get the result from userspace */
+	gpa = read_sysreg(tpidr_el2);
+
+	write_sysreg(vcpu_id, tpidr_el2);
+
+	return gpa;
+}
+
+static void l2_guest_code(void)
+{
+	do_hvc();
+}
+
+static void guest_code(void)
+{
+	struct vcpu vcpu;
+	struct hyp_data hyp_data;
+	int ret;
+	vm_paddr_t l2_pc, l2_stack_top;
+	/* force 16-byte alignment for the stack pointer */
+	u8 l2_stack[L2STACKSZ] __attribute__((aligned(16)));
+
+	GUEST_ASSERT_EQ(get_current_el(), 2);
+	GUEST_PRINTF("vEL2 entry\n");
+
+	l2_pc = ucall_translate_to_gpa(l2_guest_code);
+	l2_stack_top = ucall_translate_to_gpa(&l2_stack[L2STACKSZ]);
+
+	init_vcpu(&vcpu, l2_pc, l2_stack_top);
+	prepare_hyp();
+
+	ret = run_l2(&vcpu, &hyp_data);
+	GUEST_ASSERT_EQ(ret, ARM_EXCEPTION_TRAP);
+	GUEST_DONE();
+}
+
+int main(void)
+{
+	struct kvm_vcpu_init init;
+	struct kvm_vcpu *vcpu;
+	struct kvm_vm *vm;
+	struct ucall uc;
+	vm_paddr_t gpa;
+
+	TEST_REQUIRE(kvm_check_cap(KVM_CAP_ARM_EL2));
+	vm = vm_create(1);
+
+	kvm_get_default_vcpu_target(vm, &init);
+	init.features[0] |= BIT(KVM_ARM_VCPU_HAS_EL2);
+	vcpu = aarch64_vcpu_add(vm, 0, &init, guest_code);
+	kvm_arch_vm_finalize_vcpus(vm);
+
+	while (true) {
+		vcpu_run(vcpu);
+
+		switch (get_ucall(vcpu, &uc)) {
+		case UCALL_SYNC:
+			if (uc.args[0] == XLATE2GPA) {
+				gpa = addr_gva2gpa(vm, (vm_vaddr_t)uc.args[1]);
+				vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_TPIDR_EL2), gpa);
+			}
+			break;
+		case UCALL_PRINTF:
+			pr_info("%s", uc.buffer);
+			break;
+		case UCALL_DONE:
+			pr_info("DONE!\n");
+			goto end;
+		case UCALL_ABORT:
+			REPORT_GUEST_ASSERT(uc);
+			fallthrough;
+		default:
+			TEST_FAIL("Unhandled ucall: %ld\n", uc.cmd);
+		}
+	}
+
+end:
+	kvm_vm_free(vm);
+	return 0;
+}
-- 
2.43.0



^ permalink raw reply related

* [PATCH v2 4/4] KVM: arm64: selftests: Enhance hello_nested test
From: Wei-Lin Chang @ 2026-04-12 14:22 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm, kvm, linux-kselftest, linux-kernel
  Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Suzuki K Poulose,
	Zenghui Yu, Catalin Marinas, Will Deacon, Paolo Bonzini,
	Shuah Khan, Wei-Lin Chang
In-Reply-To: <20260412142216.3806482-1-weilin.chang@arm.com>

Handle an "add" hypercall in L1 to add 2 numbers passed by L2, and
return the result. This better tests our save/restore functionality.

Signed-off-by: Wei-Lin Chang <weilin.chang@arm.com>
---
 .../selftests/kvm/arm64/hello_nested.c        | 31 ++++++++++++++++++-
 .../selftests/kvm/include/arm64/nested.h      |  2 +-
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/kvm/arm64/hello_nested.c b/tools/testing/selftests/kvm/arm64/hello_nested.c
index 97387e4697b3..69f4d8e750e2 100644
--- a/tools/testing/selftests/kvm/arm64/hello_nested.c
+++ b/tools/testing/selftests/kvm/arm64/hello_nested.c
@@ -11,6 +11,10 @@
 #define XLATE2GPA	(0xABCD)
 #define L2STACKSZ	(0x100)
 
+#define L2SUCCESS	(0x0)
+#define L2FAILED	(0x1)
+#define L2ADD		(0x2)
+
 /*
  * TPIDR_EL2 is used to store vcpu id, so save and restore it.
  */
@@ -31,7 +35,14 @@ static vm_paddr_t ucall_translate_to_gpa(void *gva)
 
 static void l2_guest_code(void)
 {
-	do_hvc();
+	int ans = 0;
+
+	ans = do_hvc(L2ADD, 2, 3);
+
+	if (ans == 5)
+		do_hvc(L2SUCCESS, 0, 0);
+	else
+		do_hvc(L2FAILED, 0, 0);
 }
 
 static void guest_code(void)
@@ -42,6 +53,7 @@ static void guest_code(void)
 	vm_paddr_t l2_pc, l2_stack_top;
 	/* force 16-byte alignment for the stack pointer */
 	u8 l2_stack[L2STACKSZ] __attribute__((aligned(16)));
+	u64 arg1, arg2;
 
 	GUEST_ASSERT_EQ(get_current_el(), 2);
 	GUEST_PRINTF("vEL2 entry\n");
@@ -54,6 +66,23 @@ static void guest_code(void)
 
 	ret = run_l2(&vcpu, &hyp_data);
 	GUEST_ASSERT_EQ(ret, ARM_EXCEPTION_TRAP);
+
+	if (vcpu.context.regs.regs[0] == L2ADD) {
+		arg1 = vcpu.context.regs.regs[1];
+		arg2 = vcpu.context.regs.regs[2];
+		GUEST_PRINTF("L2 add request, arg1: %lx, arg2: %lx\n", arg1, arg2);
+		vcpu.context.regs.regs[0] = arg1 + arg2;
+	} else {
+		GUEST_FAIL("Unexpected hvc action\n");
+	}
+
+	ret = run_l2(&vcpu, &hyp_data);
+	GUEST_ASSERT_EQ(ret, ARM_EXCEPTION_TRAP);
+
+	if (vcpu.context.regs.regs[0] != L2SUCCESS)
+		GUEST_FAIL("L2 failed\n");
+
+	GUEST_PRINTF("L2 success!\n");
 	GUEST_DONE();
 }
 
diff --git a/tools/testing/selftests/kvm/include/arm64/nested.h b/tools/testing/selftests/kvm/include/arm64/nested.h
index 7928ef89494a..b16a72488858 100644
--- a/tools/testing/selftests/kvm/include/arm64/nested.h
+++ b/tools/testing/selftests/kvm/include/arm64/nested.h
@@ -50,7 +50,7 @@ void prepare_hyp(void);
 void init_vcpu(struct vcpu *vcpu, vm_paddr_t l2_pc, vm_paddr_t l2_stack_top);
 int run_l2(struct vcpu *vcpu, struct hyp_data *hyp_data);
 
-void do_hvc(void);
+u64 do_hvc(u64 action, u64 arg1, u64 arg2);
 u64 __guest_enter(struct vcpu *vcpu, struct cpu_context *hyp_context);
 void __hyp_exception(u64 type);
 
-- 
2.43.0



^ permalink raw reply related

* [PATCH v2 2/4] KVM: arm64: sefltests: Add helpers for guest hypervisors
From: Wei-Lin Chang @ 2026-04-12 14:22 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm, kvm, linux-kselftest, linux-kernel
  Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Suzuki K Poulose,
	Zenghui Yu, Catalin Marinas, Will Deacon, Paolo Bonzini,
	Shuah Khan, Wei-Lin Chang
In-Reply-To: <20260412142216.3806482-1-weilin.chang@arm.com>

Add helpers so that guest hypervisors can run nested guests. SP_EL1
save/restore is added to allow nested guests to use a stack.

Signed-off-by: Wei-Lin Chang <weilin.chang@arm.com>
---
 .../selftests/kvm/include/arm64/nested.h      | 17 +++++++
 tools/testing/selftests/kvm/lib/arm64/entry.S |  5 ++
 .../testing/selftests/kvm/lib/arm64/nested.c  | 46 +++++++++++++++++++
 3 files changed, 68 insertions(+)

diff --git a/tools/testing/selftests/kvm/include/arm64/nested.h b/tools/testing/selftests/kvm/include/arm64/nested.h
index 86d931facacb..7928ef89494a 100644
--- a/tools/testing/selftests/kvm/include/arm64/nested.h
+++ b/tools/testing/selftests/kvm/include/arm64/nested.h
@@ -21,8 +21,17 @@
 
 extern char hyp_vectors[];
 
+enum vcpu_sysreg {
+	__INVALID_SYSREG__,   /* 0 is reserved as an invalid value */
+
+	SP_EL1,
+
+	NR_SYS_REGS
+};
+
 struct cpu_context {
 	struct user_pt_regs regs;	/* sp = sp_el0 */
+	u64 sys_regs[NR_SYS_REGS];
 };
 
 struct vcpu {
@@ -37,9 +46,17 @@ struct hyp_data {
 	struct cpu_context hyp_context;
 };
 
+void prepare_hyp(void);
+void init_vcpu(struct vcpu *vcpu, vm_paddr_t l2_pc, vm_paddr_t l2_stack_top);
+int run_l2(struct vcpu *vcpu, struct hyp_data *hyp_data);
+
+void do_hvc(void);
 u64 __guest_enter(struct vcpu *vcpu, struct cpu_context *hyp_context);
 void __hyp_exception(u64 type);
 
+void __sysreg_save_el1_state(struct cpu_context *ctxt);
+void __sysreg_restore_el1_state(struct cpu_context *ctxt);
+
 #endif /* !__ASSEMBLER__ */
 
 #endif /* SELFTEST_KVM_NESTED_H */
diff --git a/tools/testing/selftests/kvm/lib/arm64/entry.S b/tools/testing/selftests/kvm/lib/arm64/entry.S
index 33bedf5e7fb2..df3af3463c6c 100644
--- a/tools/testing/selftests/kvm/lib/arm64/entry.S
+++ b/tools/testing/selftests/kvm/lib/arm64/entry.S
@@ -3,6 +3,11 @@
  * adapted from arch/arm64/kvm/hyp/entry.S
  */
 
+ .globl do_hvc
+ do_hvc:
+	hvc	#0
+	ret
+
 /*
  * Manually define these for now
  */
diff --git a/tools/testing/selftests/kvm/lib/arm64/nested.c b/tools/testing/selftests/kvm/lib/arm64/nested.c
index 06ddaab2436f..b30d20b101c4 100644
--- a/tools/testing/selftests/kvm/lib/arm64/nested.c
+++ b/tools/testing/selftests/kvm/lib/arm64/nested.c
@@ -4,7 +4,53 @@
  */
 
 #include "nested.h"
+#include "processor.h"
 #include "test_util.h"
+#include <asm/sysreg.h>
+
+void prepare_hyp(void)
+{
+	write_sysreg(HCR_EL2_E2H | HCR_EL2_RW, hcr_el2);
+	write_sysreg(hyp_vectors, vbar_el2);
+	isb();
+}
+
+void init_vcpu(struct vcpu *vcpu, vm_paddr_t l2_pc, vm_paddr_t l2_stack_top)
+{
+	memset(vcpu, 0, sizeof(*vcpu));
+	vcpu->context.regs.pc = l2_pc;
+	vcpu->context.regs.pstate = PSR_MODE_EL1h | PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT;
+	vcpu->context.sys_regs[SP_EL1] = l2_stack_top;
+}
+
+void __sysreg_save_el1_state(struct cpu_context *ctxt)
+{
+	ctxt->sys_regs[SP_EL1] = read_sysreg(sp_el1);
+}
+
+void __sysreg_restore_el1_state(struct cpu_context *ctxt)
+{
+	write_sysreg(ctxt->sys_regs[SP_EL1], sp_el1);
+}
+
+int run_l2(struct vcpu *vcpu, struct hyp_data *hyp_data)
+{
+	u64 ret;
+
+	__sysreg_restore_el1_state(&vcpu->context);
+
+	write_sysreg(vcpu->context.regs.pstate, spsr_el2);
+	write_sysreg(vcpu->context.regs.pc, elr_el2);
+
+	ret =  __guest_enter(vcpu, &hyp_data->hyp_context);
+
+	vcpu->context.regs.pc = read_sysreg(elr_el2);
+	vcpu->context.regs.pstate = read_sysreg(spsr_el2);
+
+	__sysreg_save_el1_state(&vcpu->context);
+
+	return ret;
+}
 
 void __hyp_exception(u64 type)
 {
-- 
2.43.0



^ permalink raw reply related

* [PATCH v2 0/4] KVM: arm64: selftests: Basic nested guest support
From: Wei-Lin Chang @ 2026-04-12 14:22 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm, kvm, linux-kselftest, linux-kernel
  Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Suzuki K Poulose,
	Zenghui Yu, Catalin Marinas, Will Deacon, Paolo Bonzini,
	Shuah Khan, Wei-Lin Chang

Hi,

This is v2 of adding basic support for running nested guests (L2) in
kselftest. After getting feedback from v1 [1], I mostly started over
from scratch. Therefore you won't lose any context if you start here.
Nonetheless, I still compiled the broad changes.

Patch 1 adds GPR save/restore code for guest, and vEL2 exception
vectors.

Patch 2 adds other hypervisor helpers.

Patch 3 adds the hello_nested selftest to jump from vEL2 -> EL1 -> vEL2.

Patch 4 enhances the hello_nested selftest so that vEL1 handles a
hypercall from EL1.

* Changes from v1 [1]:

  - Set HCR_EL2.E2H for the guest.

  - Pivoted from "userspace setting up everything" to "make L1 more like
    a proper hypervisor". Guest EL2 exception vectors, and GPR
    save/restore are added. There is also some infrastructure to
    save/restore system registers, right now only SP_EL1 is
    saved/restored to give L2 a stack. More system registers can be
    added in the future.

  - Removed the stage-2 page table generator. The stage-2 page table
    generator was bad, and the changes needed for the previous point
    alone is already making the series larger, so I decided to not add
    any guest stage-2 code in this iteration.

Thanks!

[1]: https://lore.kernel.org/kvmarm/20260325003620.2214766-1-weilin.chang@arm.com/

Wei-Lin Chang (4):
  KVM: arm64: selftests: Add GPR save/restore functions for NV
  KVM: arm64: sefltests: Add helpers for guest hypervisors
  KVM: arm64: sefltests: Add basic NV selftest
  KVM: arm64: selftests: Enhance hello_nested test

 tools/testing/selftests/kvm/Makefile.kvm      |   4 +
 .../selftests/kvm/arm64/hello_nested.c        | 132 +++++++++++++++++
 .../selftests/kvm/include/arm64/nested.h      |  62 ++++++++
 tools/testing/selftests/kvm/lib/arm64/entry.S | 137 ++++++++++++++++++
 .../selftests/kvm/lib/arm64/hyp-entry.S       |  77 ++++++++++
 .../testing/selftests/kvm/lib/arm64/nested.c  |  58 ++++++++
 6 files changed, 470 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/arm64/hello_nested.c
 create mode 100644 tools/testing/selftests/kvm/include/arm64/nested.h
 create mode 100644 tools/testing/selftests/kvm/lib/arm64/entry.S
 create mode 100644 tools/testing/selftests/kvm/lib/arm64/hyp-entry.S
 create mode 100644 tools/testing/selftests/kvm/lib/arm64/nested.c

-- 
2.43.0



^ permalink raw reply

* [PATCH v2 1/4] KVM: arm64: selftests: Add GPR save/restore functions for NV
From: Wei-Lin Chang @ 2026-04-12 14:22 UTC (permalink / raw)
  To: linux-arm-kernel, kvmarm, kvm, linux-kselftest, linux-kernel
  Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Suzuki K Poulose,
	Zenghui Yu, Catalin Marinas, Will Deacon, Paolo Bonzini,
	Shuah Khan, Wei-Lin Chang
In-Reply-To: <20260412142216.3806482-1-weilin.chang@arm.com>

Adapt entry.S and hyp-entry.S from arch/arm64/kvm/hyp so that guest
hypervisors can save and restore GPRs, and provide exception handlers
to regain control after the nested guest exits. Other system register
save/restore will be added later on demand.

Signed-off-by: Wei-Lin Chang <weilin.chang@arm.com>
---
 tools/testing/selftests/kvm/Makefile.kvm      |   3 +
 .../selftests/kvm/include/arm64/nested.h      |  45 ++++++
 tools/testing/selftests/kvm/lib/arm64/entry.S | 132 ++++++++++++++++++
 .../selftests/kvm/lib/arm64/hyp-entry.S       |  77 ++++++++++
 .../testing/selftests/kvm/lib/arm64/nested.c  |  12 ++
 5 files changed, 269 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/include/arm64/nested.h
 create mode 100644 tools/testing/selftests/kvm/lib/arm64/entry.S
 create mode 100644 tools/testing/selftests/kvm/lib/arm64/hyp-entry.S
 create mode 100644 tools/testing/selftests/kvm/lib/arm64/nested.c

diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
index 98da9fa4b8b7..3dc3e39f7025 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -30,10 +30,13 @@ LIBKVM_x86 += lib/x86/svm.c
 LIBKVM_x86 += lib/x86/ucall.c
 LIBKVM_x86 += lib/x86/vmx.c
 
+LIBKVM_arm64 += lib/arm64/entry.S
 LIBKVM_arm64 += lib/arm64/gic.c
 LIBKVM_arm64 += lib/arm64/gic_v3.c
 LIBKVM_arm64 += lib/arm64/gic_v3_its.c
 LIBKVM_arm64 += lib/arm64/handlers.S
+LIBKVM_arm64 += lib/arm64/hyp-entry.S
+LIBKVM_arm64 += lib/arm64/nested.c
 LIBKVM_arm64 += lib/arm64/processor.c
 LIBKVM_arm64 += lib/arm64/spinlock.c
 LIBKVM_arm64 += lib/arm64/ucall.c
diff --git a/tools/testing/selftests/kvm/include/arm64/nested.h b/tools/testing/selftests/kvm/include/arm64/nested.h
new file mode 100644
index 000000000000..86d931facacb
--- /dev/null
+++ b/tools/testing/selftests/kvm/include/arm64/nested.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * ARM64 Nested virtualization defines
+ */
+
+#ifndef SELFTEST_KVM_NESTED_H
+#define SELFTEST_KVM_NESTED_H
+
+#define ARM_EXCEPTION_IRQ	  0
+#define ARM_EXCEPTION_EL1_SERROR  1
+#define ARM_EXCEPTION_TRAP	  2
+#define ARM_EXCEPTION_IL	  3
+#define ARM_EXCEPTION_EL2_IRQ	  4
+#define ARM_EXCEPTION_EL2_SERROR  5
+#define ARM_EXCEPTION_EL2_TRAP	  6
+
+#ifndef __ASSEMBLER__
+
+#include <asm/ptrace.h>
+#include "kvm_util.h"
+
+extern char hyp_vectors[];
+
+struct cpu_context {
+	struct user_pt_regs regs;	/* sp = sp_el0 */
+};
+
+struct vcpu {
+	struct cpu_context context;
+};
+
+/*
+ * KVM has host_data and hyp_context, combine them because we're only doing
+ * hyp context.
+ */
+struct hyp_data {
+	struct cpu_context hyp_context;
+};
+
+u64 __guest_enter(struct vcpu *vcpu, struct cpu_context *hyp_context);
+void __hyp_exception(u64 type);
+
+#endif /* !__ASSEMBLER__ */
+
+#endif /* SELFTEST_KVM_NESTED_H */
diff --git a/tools/testing/selftests/kvm/lib/arm64/entry.S b/tools/testing/selftests/kvm/lib/arm64/entry.S
new file mode 100644
index 000000000000..33bedf5e7fb2
--- /dev/null
+++ b/tools/testing/selftests/kvm/lib/arm64/entry.S
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * adapted from arch/arm64/kvm/hyp/entry.S
+ */
+
+/*
+ * Manually define these for now
+ */
+// offsetof(struct vcpu, context)
+#define CPU_CONTEXT		0
+// offsetof(struct cpu_context, regs)
+#define CPU_USER_PT_REGS	0
+
+#define CPU_XREG_OFFSET(x)	(CPU_USER_PT_REGS + 8*x)
+#define CPU_LR_OFFSET		CPU_XREG_OFFSET(30)
+#define CPU_SP_EL0_OFFSET	(CPU_LR_OFFSET + 8)
+
+.macro save_callee_saved_regs ctxt
+	str	x18,      [\ctxt, #CPU_XREG_OFFSET(18)]
+	stp	x19, x20, [\ctxt, #CPU_XREG_OFFSET(19)]
+	stp	x21, x22, [\ctxt, #CPU_XREG_OFFSET(21)]
+	stp	x23, x24, [\ctxt, #CPU_XREG_OFFSET(23)]
+	stp	x25, x26, [\ctxt, #CPU_XREG_OFFSET(25)]
+	stp	x27, x28, [\ctxt, #CPU_XREG_OFFSET(27)]
+	stp	x29, lr,  [\ctxt, #CPU_XREG_OFFSET(29)]
+.endm
+
+.macro restore_callee_saved_regs ctxt
+	ldr	x18,      [\ctxt, #CPU_XREG_OFFSET(18)]
+	ldp	x19, x20, [\ctxt, #CPU_XREG_OFFSET(19)]
+	ldp	x21, x22, [\ctxt, #CPU_XREG_OFFSET(21)]
+	ldp	x23, x24, [\ctxt, #CPU_XREG_OFFSET(23)]
+	ldp	x25, x26, [\ctxt, #CPU_XREG_OFFSET(25)]
+	ldp	x27, x28, [\ctxt, #CPU_XREG_OFFSET(27)]
+	ldp	x29, lr,  [\ctxt, #CPU_XREG_OFFSET(29)]
+.endm
+
+.macro save_sp_el0 ctxt, tmp
+	mrs	\tmp,	sp_el0
+	str	\tmp,	[\ctxt, #CPU_SP_EL0_OFFSET]
+.endm
+
+.macro restore_sp_el0 ctxt, tmp
+	ldr	\tmp,	  [\ctxt, #CPU_SP_EL0_OFFSET]
+	msr	sp_el0, \tmp
+.endm
+
+/*
+ * u64 __guest_enter(struct vcpu *vcpu, struct cpu_context *hyp_context);
+ */
+.globl __guest_enter
+__guest_enter:
+	// x0: vcpu
+	// x1: hyp context
+
+	// Store vcpu and hyp context pointer on the stack
+	stp	x0, x1, [sp, #-16]!
+
+	// Store the hyp regs
+	save_callee_saved_regs x1
+
+	// Save hyp's sp_el0
+	save_sp_el0	x1, x2
+
+	// x29 = vCPU user pt regs
+	add	x29, x0, #CPU_CONTEXT
+
+	// Restore the guest's sp_el0
+	restore_sp_el0 x29, x0
+
+	// Restore guest regs x0-x17
+	ldp	x0, x1,   [x29, #CPU_XREG_OFFSET(0)]
+	ldp	x2, x3,   [x29, #CPU_XREG_OFFSET(2)]
+	ldp	x4, x5,   [x29, #CPU_XREG_OFFSET(4)]
+	ldp	x6, x7,   [x29, #CPU_XREG_OFFSET(6)]
+	ldp	x8, x9,   [x29, #CPU_XREG_OFFSET(8)]
+	ldp	x10, x11, [x29, #CPU_XREG_OFFSET(10)]
+	ldp	x12, x13, [x29, #CPU_XREG_OFFSET(12)]
+	ldp	x14, x15, [x29, #CPU_XREG_OFFSET(14)]
+	ldp	x16, x17, [x29, #CPU_XREG_OFFSET(16)]
+
+	// Restore guest regs x18-x29, lr
+	restore_callee_saved_regs x29
+
+	// Do not touch any register after this!
+	eret
+
+.globl __guest_exit
+__guest_exit:
+	// x0: return code
+	// x1: vcpu
+	// x2-x29,lr: vcpu regs
+	// vcpu x0-x1 on the stack
+
+	add	x1, x1, #CPU_CONTEXT
+
+	// Store the guest regs x2 and x3
+	stp	x2, x3,   [x1, #CPU_XREG_OFFSET(2)]
+
+	// Retrieve the guest regs x0-x1 from the stack
+	ldp	x2, x3, [sp], #16	// x0, x1
+
+	// Store the guest regs x0-x1 and x4-x17
+	stp	x2, x3,   [x1, #CPU_XREG_OFFSET(0)]
+	stp	x4, x5,   [x1, #CPU_XREG_OFFSET(4)]
+	stp	x6, x7,   [x1, #CPU_XREG_OFFSET(6)]
+	stp	x8, x9,   [x1, #CPU_XREG_OFFSET(8)]
+	stp	x10, x11, [x1, #CPU_XREG_OFFSET(10)]
+	stp	x12, x13, [x1, #CPU_XREG_OFFSET(12)]
+	stp	x14, x15, [x1, #CPU_XREG_OFFSET(14)]
+	stp	x16, x17, [x1, #CPU_XREG_OFFSET(16)]
+
+	// Store the guest regs x18-x29, lr
+	save_callee_saved_regs x1
+
+	// Store the guest's sp_el0
+	save_sp_el0	x1, x2
+
+	// At this point x0 and x1 on the stack is popped, so next is vCPU
+	// pointer, then hyp_context pointer
+	// *sp == vCPU, *(sp + 8) == hyp_context
+	// load x2 = hyp_context, x3 is just for ldp and popping sp
+	ldp	x3, x2, [sp], #16
+
+	// Restore hyp's sp_el0
+	restore_sp_el0 x2, x3
+
+	// Now restore the hyp regs
+	restore_callee_saved_regs x2
+
+	dsb	sy		// Synchronize against in-flight ld/st
+	ret
diff --git a/tools/testing/selftests/kvm/lib/arm64/hyp-entry.S b/tools/testing/selftests/kvm/lib/arm64/hyp-entry.S
new file mode 100644
index 000000000000..6341f6e05c90
--- /dev/null
+++ b/tools/testing/selftests/kvm/lib/arm64/hyp-entry.S
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * adapted from arch/arm64/kvm/hyp/hyp-entry.S
+ */
+
+#include "nested.h"
+
+// skip over x0, x1 saved on entry, must be used only before the stack is modified
+.macro get_vcpu_ptr vcpu
+	ldr	\vcpu, [sp, #16]
+.endm
+
+	.text
+
+el1_sync:	// Guest trapped into EL2
+
+	get_vcpu_ptr	x1
+	mov	x0, #ARM_EXCEPTION_TRAP
+	b	__guest_exit
+
+el1_irq:
+el1_fiq:
+	get_vcpu_ptr	x1
+	mov	x0, #ARM_EXCEPTION_IRQ
+	b	__guest_exit
+
+el1_error:
+	get_vcpu_ptr	x1
+	mov	x0, #ARM_EXCEPTION_EL1_SERROR
+	b	__guest_exit
+
+el2_sync:
+	mov	x0, #ARM_EXCEPTION_EL2_TRAP
+	b	__hyp_exception
+
+el2_irq:
+el2_fiq:
+	mov	x0, #ARM_EXCEPTION_EL2_IRQ
+	b	__hyp_exception
+
+el2_error:
+	mov	x0, #ARM_EXCEPTION_EL2_SERROR
+	b	__hyp_exception
+
+
+	.ltorg
+
+	.align 11
+
+.globl hyp_vectors
+hyp_vectors:
+
+.macro exception_vector target
+	.align 7
+	stp	x0, x1, [sp, #-16]!
+	b	\target
+.endm
+
+	exception_vector	el2_sync	// Synchronous EL2t
+	exception_vector	el2_irq		// IRQ EL2t
+	exception_vector	el2_fiq		// FIQ EL2t
+	exception_vector	el2_error	// Error EL2t
+
+	exception_vector	el2_sync	// Synchronous EL2h
+	exception_vector	el2_irq		// IRQ EL2h
+	exception_vector	el2_fiq		// FIQ EL2h
+	exception_vector	el2_error	// Error EL2h
+
+	exception_vector	el1_sync	// Synchronous 64-bit EL1
+	exception_vector	el1_irq		// IRQ 64-bit EL1
+	exception_vector	el1_fiq		// FIQ 64-bit EL1
+	exception_vector	el1_error	// Error 64-bit EL1
+
+	exception_vector	el1_sync	// Synchronous 32-bit EL1
+	exception_vector	el1_irq		// IRQ 32-bit EL1
+	exception_vector	el1_fiq		// FIQ 32-bit EL1
+	exception_vector	el1_error	// Error 32-bit EL1
diff --git a/tools/testing/selftests/kvm/lib/arm64/nested.c b/tools/testing/selftests/kvm/lib/arm64/nested.c
new file mode 100644
index 000000000000..06ddaab2436f
--- /dev/null
+++ b/tools/testing/selftests/kvm/lib/arm64/nested.c
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ARM64 Nested virtualization helpers
+ */
+
+#include "nested.h"
+#include "test_util.h"
+
+void __hyp_exception(u64 type)
+{
+	GUEST_FAIL("Unexpected hyp exception! type: %lx\n", type);
+}
-- 
2.43.0



^ permalink raw reply related

* Re: [PATCH v2 4/5] coresight: etm3x: introduce struct etm_caps
From: Jie Gan @ 2026-04-12 14:21 UTC (permalink / raw)
  To: Yeoreum Yun, coresight, linux-arm-kernel, linux-kernel
  Cc: suzuki.poulose, mike.leach, james.clark, alexander.shishkin,
	leo.yan
In-Reply-To: <20260410074310.2693385-5-yeoreum.yun@arm.com>



On 4/10/2026 3:43 PM, 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   | 40 +++++++++++--------
>   .../coresight/coresight-etm3x-core.c          | 33 ++++++++-------
>   .../coresight/coresight-etm3x-sysfs.c         | 14 ++++---
>   3 files changed, 52 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-etm.h b/drivers/hwtracing/coresight/coresight-etm.h
> index 1d753cca2943..6fda26039db8 100644
> --- a/drivers/hwtracing/coresight/coresight-etm.h
> +++ b/drivers/hwtracing/coresight/coresight-etm.h
> @@ -140,6 +140,28 @@
>   				 ETM_ADD_COMP_0		|	\
>   				 ETM_EVENT_NOT_A)
>   
> +/**
> + * struct etmv4_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.
> + */
> +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;
> +};
> +
>   /**
>    * struct etm_config - configuration information related to an ETM
>    * @mode:	controls various modes supported by this ETM/PTM.
> @@ -212,19 +234,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.
>    * @config:	structure holding configuration parameters.
>    */
> @@ -234,19 +249,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		config;
>   };
> diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c
> index a547a6d2e0bd..b7e977defb1c 100644
> --- a/drivers/hwtracing/coresight/coresight-etm3x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c
> @@ -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->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);
> @@ -572,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++)

caps undeclared.

Thanks,
Jie

>   		config->cntr_val[i] = etm_readl(drvdata, ETMCNTVRn(i));
>   
>   	etm_set_pwrdwn(drvdata);
> @@ -754,7 +755,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);
> @@ -779,16 +782,18 @@ 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 = !!(drvdata->etmccer & ETMCCER_TIMESTAMP);

caps->timestamp = !!(etmccer & ETMCCER_TIMESTAMP);

>   
> -	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 = !!(drvdata->etmccr & ETMCCR_FIFOFULL);

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 762109307b86..0d8dac29d055 100644
> --- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
> +++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
> @@ -111,6 +111,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);
> @@ -131,7 +132,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;
> @@ -141,7 +142,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;
> @@ -286,13 +287,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;
>   
>   	/*
> @@ -589,13 +591,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
> @@ -999,13 +1002,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;
>   
>   	/*



^ permalink raw reply

* Re: [PATCH net-next] net: stmmac: enable RPS and RBU interrupts
From: Maxime Chevallier @ 2026-04-12 14:01 UTC (permalink / raw)
  To: Russell King (Oracle), Andrew Lunn
  Cc: Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, linux-arm-kernel, linux-stm32, netdev,
	Paolo Abeni, Sam Edwards
In-Reply-To: <E1wBBaR-0000000GZHR-1dbM@rmk-PC.armlinux.org.uk>

Hi Russell,

On 10/04/2026 15:07, Russell King (Oracle) wrote:
> Enable receive process stopped and receive buffer unavailable
> interrupts, so that the statistic counters can be updated.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
> ---
> Since we are seeing receive buffer exhaustion on several platforms,
> let's enable the interrupts so the statistics we publish via ethtool -S
> actually work to aid diagnosis. I've been in two minds about whether
> to send this patch, but given the problems with stmmac at the moment,
> I think it should be merged.

Looks like my reply to your original RFC was lost in limbo as the review/test tags are missing.

Here's my original answer :


It works, I can indeed see the stats get properly updated on imx8mp 🙂

There's one downside to it though, which is that as soon as we hit a situation
where we don't have RX bufs available, this patchs has a tendancy to make things
worse as we'll trigger interrupts for each packet we receive and that we can't
process, making it even longer for queues to be refilled.

It shows on iperf3 with small packets :

---- Before patch, 17% packet loss on UDP 56 bytes packets -----------------

# iperf3 -u -b 0 -l 56 -c 192.168.2.1 -R
Connecting to host 192.168.2.1, port 5201
Reverse mode, remote host 192.168.2.1 is sending
[  5] local 192.168.2.18 port 47851 connected to 192.168.2.1 port 5201
[ ID] Interval           Transfer     Bitrate         Jitter    Lost/Total Datagrams
[  5]   0.00-1.00   sec  10.7 MBytes  90.0 Mbits/sec  0.003 ms  48550/249650 (19%)  
[  5]   1.00-2.00   sec  11.3 MBytes  95.0 Mbits/sec  0.003 ms  41881/253832 (16%)  
[  5]   2.00-3.00   sec  11.3 MBytes  94.9 Mbits/sec  0.002 ms  42060/253913 (17%)  
[  5]   3.00-4.00   sec  11.3 MBytes  95.1 Mbits/sec  0.003 ms  41499/253785 (16%)  
[  5]   4.00-5.00   sec  11.3 MBytes  94.6 Mbits/sec  0.003 ms  42663/253787 (17%)  
[  5]   5.00-6.00   sec  11.3 MBytes  94.9 Mbits/sec  0.006 ms  41976/253719 (17%)  
[  5]   6.00-7.00   sec  11.3 MBytes  94.5 Mbits/sec  0.003 ms  43133/253999 (17%)  
[  5]   7.00-8.00   sec  11.3 MBytes  95.0 Mbits/sec  0.004 ms  41442/253579 (16%)  
[  5]   8.00-9.00   sec  11.4 MBytes  95.2 Mbits/sec  0.004 ms  41518/254131 (16%)  
[  5]   9.00-10.00  sec  11.2 MBytes  94.3 Mbits/sec  0.006 ms  43580/254143 (17%)  
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Jitter    Lost/Total Datagrams
[  5]   0.00-10.00  sec   135 MBytes   114 Mbits/sec  0.000 ms  0/0 (0%)  sender
[  5]   0.00-10.00  sec   112 MBytes  94.3 Mbits/sec  0.006 ms  428302/2534538 (17%)  receiver

iperf Done.
# ethtool -S eth1 | grep rx_buf_unav_irq
     rx_buf_unav_irq: 0

---- After patch, 22% packet loss on UDP 56 bytes packets ----------------------

# iperf3 -u -b 0 -l 56 -c 192.168.2.1 -R
Connecting to host 192.168.2.1, port 5201
Reverse mode, remote host 192.168.2.1 is sending
[  5] local 192.168.2.18 port 42121 connected to 192.168.2.1 port 5201
[ ID] Interval           Transfer     Bitrate         Jitter    Lost/Total Datagrams
[  5]   0.00-1.00   sec  10.3 MBytes  85.8 Mbits/sec  0.004 ms  55146/247172 (22%)  
[  5]   1.00-2.00   sec  10.6 MBytes  89.1 Mbits/sec  0.003 ms  54699/253355 (22%)  
[  5]   2.00-3.00   sec  10.6 MBytes  89.0 Mbits/sec  0.003 ms  55231/253887 (22%)  
[  5]   3.00-4.00   sec  10.6 MBytes  88.9 Mbits/sec  0.003 ms  55138/253602 (22%)  
[  5]   4.00-5.00   sec  10.6 MBytes  89.0 Mbits/sec  0.003 ms  54938/253722 (22%)  
[  5]   5.00-6.00   sec  10.6 MBytes  88.9 Mbits/sec  0.003 ms  55273/253580 (22%)  
[  5]   6.00-7.00   sec  10.6 MBytes  89.0 Mbits/sec  0.003 ms  55202/253986 (22%)  
[  5]   7.00-8.00   sec  10.6 MBytes  89.1 Mbits/sec  0.003 ms  55047/253958 (22%)  
[  5]   8.00-9.00   sec  10.6 MBytes  88.9 Mbits/sec  0.003 ms  55612/254140 (22%)  
[  5]   9.00-10.00  sec  10.6 MBytes  89.0 Mbits/sec  0.003 ms  55683/254403 (22%)  
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Jitter    Lost/Total Datagrams
[  5]   0.00-10.00  sec   135 MBytes   113 Mbits/sec  0.000 ms  0/0 (0%)  sender
[  5]   0.00-10.00  sec   106 MBytes  88.7 Mbits/sec  0.003 ms  551969/2531805 (22%)  receiver

iperf Done.
# ethtool -S eth1 | grep rx_buf_unav_irq
     rx_buf_unav_irq: 30624


So clearly there are pros and cons with this, but I don't want to fall into the
"let's not break microbenchmarks" pitfall.

I personnaly find the stat useful, and that having the stat visible to user
but stuck at 0 is misleading so,

Tested-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>


Maxime

> 
>  drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
> index af6580332d49..43b036d4e95b 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
> @@ -99,6 +99,8 @@ static inline u32 dma_chanx_base_addr(const struct dwmac4_addrs *addrs,
>  #define DMA_CHAN_INTR_ENA_NIE_4_10	BIT(15)
>  #define DMA_CHAN_INTR_ENA_AIE_4_10	BIT(14)
>  #define DMA_CHAN_INTR_ENA_FBE		BIT(12)
> +#define DMA_CHAN_INTR_ENA_RPS		BIT(8)
> +#define DMA_CHAN_INTR_ENA_RBU		BIT(7)
>  #define DMA_CHAN_INTR_ENA_RIE		BIT(6)
>  #define DMA_CHAN_INTR_ENA_TIE		BIT(0)
>  
> @@ -107,6 +109,8 @@ static inline u32 dma_chanx_base_addr(const struct dwmac4_addrs *addrs,
>  					 DMA_CHAN_INTR_ENA_TIE)
>  
>  #define DMA_CHAN_INTR_ABNORMAL		(DMA_CHAN_INTR_ENA_AIE | \
> +					 DMA_CHAN_INTR_ENA_RPS | \
> +					 DMA_CHAN_INTR_ENA_RBU | \
>  					 DMA_CHAN_INTR_ENA_FBE)
>  /* DMA default interrupt mask for 4.00 */
>  #define DMA_CHAN_INTR_DEFAULT_MASK	(DMA_CHAN_INTR_NORMAL | \
> @@ -117,6 +121,8 @@ static inline u32 dma_chanx_base_addr(const struct dwmac4_addrs *addrs,
>  					 DMA_CHAN_INTR_ENA_TIE)
>  
>  #define DMA_CHAN_INTR_ABNORMAL_4_10	(DMA_CHAN_INTR_ENA_AIE_4_10 | \
> +					 DMA_CHAN_INTR_ENA_RPS | \
> +					 DMA_CHAN_INTR_ENA_RBU | \
>  					 DMA_CHAN_INTR_ENA_FBE)
>  /* DMA default interrupt mask for 4.10a */
>  #define DMA_CHAN_INTR_DEFAULT_MASK_4_10	(DMA_CHAN_INTR_NORMAL_4_10 | \



^ permalink raw reply

* Re: [PATCH v2] iio: adc: xilinx-xadc: Fix sequencer mode in postdisable for dual mux
From: Jonathan Cameron @ 2026-04-12 13:48 UTC (permalink / raw)
  To: Erim, Salih
  Cc: Christofer Jonason, Simek, Michal, O'Griofa, Conall,
	lars@metafoo.de, dlechner@baylibre.com, nuno.sa@analog.com,
	andy@kernel.org, Victor Jonsson, linux-iio@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, stable@vger.kernel.org
In-Reply-To: <IA1PR12MB7736D5B150CA36406ED7384A9F5AA@IA1PR12MB7736.namprd12.prod.outlook.com>

On Tue, 7 Apr 2026 14:30:57 +0000
"Erim, Salih" <Salih.Erim@amd.com> wrote:

> Hi Christofer,
> 
> Thanks for the details. That confirms it.
> 
> Jonathan - this one is good to go from our side.
> 
> 
Applied to the fixes-togreg branch of iio.git
Very unlikely I'll do another pull request before rebasing that tree
on rc1 though, so it will be a few weeks.

> Thanks,
> Salih.
> 



^ permalink raw reply

* Re: [patch 23/38] alpha: Select ARCH_HAS_RANDOM_ENTROPY
From: Magnus Lindholm @ 2026-04-12 13:22 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: LKML, Richard Henderson, linux-alpha, Arnd Bergmann, x86,
	Lu Baolu, iommu, Michael Grzeschik, netdev, linux-wireless,
	Herbert Xu, linux-crypto, Vlastimil Babka, linux-mm,
	David Woodhouse, Bernie Thompson, linux-fbdev, Theodore Tso,
	linux-ext4, Andrew Morton, Uladzislau Rezki, Marco Elver,
	Dmitry Vyukov, kasan-dev, Andrey Ryabinin, Thomas Sailer,
	linux-hams, Jason A. Donenfeld, Russell King, linux-arm-kernel,
	Catalin Marinas, Huacai Chen, loongarch, Geert Uytterhoeven,
	linux-m68k, Dinh Nguyen, Jonas Bonn, linux-openrisc, Helge Deller,
	linux-parisc, Michael Ellerman, linuxppc-dev, Paul Walmsley,
	linux-riscv, Heiko Carstens, linux-s390, David S. Miller,
	sparclinux
In-Reply-To: <20260410120319.131582521@kernel.org>

On Fri, Apr 10, 2026 at 2:36 PM Thomas Gleixner <tglx@kernel.org> wrote:
>
> The only remaining usage of get_cycles() is to provide
> random_get_entropy().
>
> Switch alpha over to the new scheme of selecting ARCH_HAS_RANDOM_ENTROPY
> and providing random_get_entropy() in asm/random.h.
>
> Remove asm/timex.h as it has no functionality anymore.
>
> Signed-off-by: Thomas Gleixner <tglx@kernel.org>
> Cc: Richard Henderson <richard.henderson@linaro.org>
> Cc: linux-alpha@vger.kernel.org
> ---
>  arch/alpha/Kconfig              |    1 +
>  arch/alpha/include/asm/random.h |   14 ++++++++++++++
>  arch/alpha/include/asm/timex.h  |   26 --------------------------
>  3 files changed, 15 insertions(+), 26 deletions(-)

Hi,

The Alpha side looks fine to me.

I've applied this patch on top of v7.0-rc7, built a kernel successfully,
boot-tested it on an Alpha UP2000+ (SMP) without issues.

Acked-by: Magnus Lindholm <linmag7@gmail.com>
Tested-by: Magnus Lindholm <linmag7@gmail.com>


^ permalink raw reply

* Aw: [RFC net-next v5 0/3] Add RSS and LRO support
From: Frank Wunderlich @ 2026-04-12 11:57 UTC (permalink / raw)
  To: linux, nbd, sean.wang, lorenzo, andrew+netdev, davem, edumazet,
	kuba, pabeni, matthias.bgg, angelogioacchino.delregno, linux
  Cc: daniel, netdev, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <20251219151219.77115-1-linux@fw-web.de>

Hi,

some time has passed without a single comment, so i just send a friendly reminder ;)

regards Frank


> Gesendet: Freitag, 19. Dezember 2025 um 16:12
> Von: "Frank Wunderlich" <linux@fw-web.de>
> An: "Felix Fietkau" <nbd@nbd.name>, "Sean Wang" <sean.wang@mediatek.com>, "Lorenzo Bianconi" <lorenzo@kernel.org>, "Andrew Lunn" <andrew+netdev@lunn.ch>, "David S. Miller" <davem@davemloft.net>, "Eric Dumazet" <edumazet@google.com>, "Jakub Kicinski" <kuba@kernel.org>, "Paolo Abeni" <pabeni@redhat.com>, "Matthias Brugger" <matthias.bgg@gmail.com>, "AngeloGioacchino Del Regno" <angelogioacchino.delregno@collabora.com>, "Russell King" <linux@armlinux.org.uk>
> CC: "Frank Wunderlich" <frank-w@public-files.de>, "Daniel Golle" <daniel@makrotopia.org>, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org
> Betreff: [RFC net-next v5 0/3] Add RSS and LRO support
>
> From: Frank Wunderlich <frank-w@public-files.de>
> 
> This series add RSS and LRO hardware acceleration for terminating
> traffic on MT798x.
> 
> It is currently only for discussion to get the upported SDK driver
> changes in a good shape.
> 
> patches are upported from mtk SDK:
> - https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/refs/heads/master/master/files/target/linux/mediatek/patches-6.12/999-eth-08-mtk_eth_soc-add-register-definitions-for-rss-lro-reg.patch
> - https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/refs/heads/master/master/files/target/linux/mediatek/patches-6.12/999-eth-09-mtk_eth_soc-add-rss-support.patch
> - https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/refs/heads/master/master/files/target/linux/mediatek/patches-6.12/999-eth-10-mtk_eth_soc-add-hw-lro-support.patch
> with additional fixes
> 
> changes:
> v5:
> - fix too long lines after macro changes reported by checkpatch
> 
> v4:
> - drop unrelated file
> - rss-changes suggested by andrew
>   - fix MTK_HW_LRO_RING_NUM macro (add eth)
>   - fix MTK_LRO_CTRL_DW[123]_CFG (add reg_map param)
>   - fix MTK_RX_DONE_INT (add eth param)
> - fix lro reverse christmas tree and LRO params suggested by andrew
> - drop mtk_hwlro_stats_ebl and unused IS_HW_LRO_RING (only used in
>   properitary debugfs)
> 
> v3:
> - readded the change dropped in v2 because it was a fix
>   for getting RSS working on mt7986
> - changes requested by jakub
> - reworked coverletter (dropped instructions for configuration)
> - name all PDMA-IRQ the same way
> - retested on
>   - BPI-R3/mt7986 (RSS needs to be enabled)
>   - BPI-R4/mt7988
>   - BPI-R64/mt7622 and BPI-R2/mt7623 for not breaking network functionality
> 
> v2:
> - drop wrong change (MTK_CDMP_IG_CTRL is only netsys v1)
> - Fix immutable string IRQ setup (thx to Emilia Schotte)
> - drop links to 6.6 patches/commits in sdk in comments
> 
> Mason Chang (3):
>   net: ethernet: mtk_eth_soc: Add register definitions for RSS and LRO
>   net: ethernet: mtk_eth_soc: Add RSS support
>   net: ethernet: mtk_eth_soc: Add LRO support
> 
>  drivers/net/ethernet/mediatek/mtk_eth_soc.c | 812 ++++++++++++++++----
>  drivers/net/ethernet/mediatek/mtk_eth_soc.h | 173 +++--
>  2 files changed, 778 insertions(+), 207 deletions(-)
> 
> -- 
> 2.43.0</frank-w@public-files.de>


^ permalink raw reply

* Re: [PATCH 3/8] firmware: meson: sm: Add thermal calibration SMC call
From: Krzysztof Kozlowski @ 2026-04-12 10:47 UTC (permalink / raw)
  To: Ronald Claveau, Guillaume La Roque, Rafael J. Wysocki,
	Daniel Lezcano, Zhang Rui, Lukasz Luba, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Neil Armstrong, Kevin Hilman,
	Jerome Brunet, Martin Blumenstingl
  Cc: linux-pm, linux-amlogic, devicetree, linux-kernel,
	linux-arm-kernel
In-Reply-To: <20260410-add-thermal-t7-vim4-v1-3-19f2b8da74d7@aliel.fr>

On 10/04/2026 18:48, Ronald Claveau wrote:
> @@ -245,6 +246,14 @@ struct meson_sm_firmware *meson_sm_get(struct device_node *sm_node)
>  }
>  EXPORT_SYMBOL_GPL(meson_sm_get);
>  
> +int meson_sm_get_thermal_calib(struct meson_sm_firmware *fw, u32 *trim_info,

Exported functions should have kerneldoc.

> +			       u32 tsensor_id)
> +{
> +	return meson_sm_call(fw, SM_THERMAL_CALIB_READ, trim_info, tsensor_id,
> +			     0, 0, 0, 0);

Best regards,
Krzysztof


^ permalink raw reply

* Re: [PATCH 1/8] dt-bindings: thermal: amlogic: Add support for T7
From: Krzysztof Kozlowski @ 2026-04-12  9:58 UTC (permalink / raw)
  To: Ronald Claveau
  Cc: Guillaume La Roque, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
	Lukasz Luba, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
	linux-pm, linux-amlogic, devicetree, linux-kernel,
	linux-arm-kernel
In-Reply-To: <20260410-add-thermal-t7-vim4-v1-1-19f2b8da74d7@aliel.fr>

On Fri, Apr 10, 2026 at 06:48:02PM +0200, Ronald Claveau wrote:
> Add the amlogic,t7-thermal compatible for the Amlogic T7 thermal sensor.
> 
> Unlike existing variants which use a phandle to the ao-secure syscon,
> the T7 relies on a secure monitor interface described by a phandle and
> a sensor index argument.
> 
> Introduce the amlogic,secure-monitor property as a phandle-array and
> make amlogic,ao-secure or amlogic,secure-monitor conditionally required
> depending on the compatible.
> 
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
>  .../bindings/thermal/amlogic,thermal.yaml          | 40 +++++++++++++++++++++-
>  1 file changed, 39 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml b/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml
> index 70b273271754b..85ee73c6e1161 100644
> --- a/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml
> +++ b/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml
> @@ -22,6 +22,7 @@ properties:
>                - amlogic,g12a-ddr-thermal
>            - const: amlogic,g12a-thermal
>        - const: amlogic,a1-cpu-thermal
> +      - const: amlogic,t7-thermal

So these two entries are enum.

>  
>    reg:
>      maxItems: 1
> @@ -42,12 +43,40 @@ properties:
>    '#thermal-sensor-cells':
>      const: 0
>  
> +  amlogic,secure-monitor:
> +    description: phandle to the secure monitor
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    items:
> +      - items:
> +          - description: phandle to the secure monitor
> +          - description: sensor index

For what exactly this sensor index is needed? commit msg explained me
nothing, instead repeated what you did. That's pointless, explain why
you did it.

> +
>  required:
>    - compatible
>    - reg
>    - interrupts
>    - clocks
> -  - amlogic,ao-secure
> +
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - amlogic,g12a-cpu-thermal
> +              - amlogic,g12a-ddr-thermal

Drop both, you need only fallback.

> +              - amlogic,a1-cpu-thermal

And list is sorted alphabetically.

> +    then:
> +      required:
> +        - amlogic,ao-secure

Best regards,
Krzysztof



^ permalink raw reply

* [PATCH RESEND 1/2] crypto: atmel-ecc - add support for atecc608b
From: Thorsten Blum @ 2026-04-12  9:56 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller, Nicolas Ferre, Alexandre Belloni,
	Claudiu Beznea
  Cc: Thorsten Blum, linux-crypto, linux-arm-kernel, linux-kernel

Tested on hardware with an ATECC608B at 0x60. The device binds
successfully, passes the driver's sanity check, and registers the
ecdh-nist-p256 KPP algorithm.

The hardware ECDH path was also exercised using a minimal KPP test
module, covering private key generation, public key derivation, and
shared secret computation.

Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
---
Resending to include linux-crypto in patch 2/2.
---
 drivers/crypto/atmel-ecc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/crypto/atmel-ecc.c b/drivers/crypto/atmel-ecc.c
index b6a77c8d439c..5793e0c44113 100644
--- a/drivers/crypto/atmel-ecc.c
+++ b/drivers/crypto/atmel-ecc.c
@@ -371,6 +371,8 @@ static void atmel_ecc_remove(struct i2c_client *client)
 static const struct of_device_id atmel_ecc_dt_ids[] = {
 	{
 		.compatible = "atmel,atecc508a",
+	}, {
+		.compatible = "atmel,atecc608b",
 	}, {
 		/* sentinel */
 	}
@@ -380,6 +382,7 @@ MODULE_DEVICE_TABLE(of, atmel_ecc_dt_ids);
 
 static const struct i2c_device_id atmel_ecc_id[] = {
 	{ "atecc508a" },
+	{ "atecc608b" },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, atmel_ecc_id);


^ permalink raw reply related

* [PATCH net-next] net: airoha: Remove PCE_MC_EN_MASK bit in REG_FE_PCE_CFG configuration
From: Lorenzo Bianconi @ 2026-04-12  9:56 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Lorenzo Bianconi
  Cc: linux-arm-kernel, linux-mediatek, netdev

PCE_MC_EN_MASK bit in REG_FE_PCE_CFG configuration performed in
airoha_fe_init() is used to duplicate multicast packets and send a copy
to the CPU when the traffic is offloaded. This is necessary just if
it is requested by the user. Disable multicast packets duplication by
default.

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/ethernet/airoha/airoha_eth.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 8e4b043af4bc..9b5b677a7071 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -458,9 +458,8 @@ static int airoha_fe_init(struct airoha_eth *eth)
 		      FIELD_PREP(PSE_IQ_RES2_P5_MASK, 0x40) |
 		      FIELD_PREP(PSE_IQ_RES2_P4_MASK, 0x34));
 
-	/* enable FE copy engine for MC/KA/DPI */
-	airoha_fe_wr(eth, REG_FE_PCE_CFG,
-		     PCE_DPI_EN_MASK | PCE_KA_EN_MASK | PCE_MC_EN_MASK);
+	/* enable FE copy engine for KA/DPI */
+	airoha_fe_wr(eth, REG_FE_PCE_CFG, PCE_DPI_EN_MASK | PCE_KA_EN_MASK);
 	/* set vip queue selection to ring 1 */
 	airoha_fe_rmw(eth, REG_CDM_FWD_CFG(1), CDM_VIP_QSEL_MASK,
 		      FIELD_PREP(CDM_VIP_QSEL_MASK, 0x4));

---
base-commit: 3f3a2aefbc661b837c8e344f944982d61c2ae037
change-id: 20260412-airoha_fe_init_remove_mc_en_bit-a89d7fcc5fc6

Best regards,
-- 
Lorenzo Bianconi <lorenzo@kernel.org>



^ permalink raw reply related

* Re: [PATCH 2/4] soc: amlogic: clk-measure: Add A1 and T7 support
From: Krzysztof Kozlowski @ 2026-04-12  9:55 UTC (permalink / raw)
  To: Jian Hu, Neil Armstrong, Jerome Brunet, Kevin Hilman,
	Michael Turquette, Martin Blumenstingl, robh+dt, Rob Herring
  Cc: devicetree, linux-amlogic, linux-kernel, linux-arm-kernel
In-Reply-To: <20260410100329.3167482-3-jian.hu@amlogic.com>

On 10/04/2026 12:03, Jian Hu wrote:
> Add support for the A1 and T7 SoC family in amlogic clk measure.
> 
> Signed-off-by: Jian Hu <jian.hu@amlogic.com>
> ---
>  drivers/soc/amlogic/meson-clk-measure.c | 272 ++++++++++++++++++++++++
>  1 file changed, 272 insertions(+)
> 
> diff --git a/drivers/soc/amlogic/meson-clk-measure.c b/drivers/soc/amlogic/meson-clk-measure.c
> index d862e30a244e..083524671b76 100644
> --- a/drivers/soc/amlogic/meson-clk-measure.c
> +++ b/drivers/soc/amlogic/meson-clk-measure.c
> @@ -787,6 +787,258 @@ static const struct meson_msr_id clk_msr_s4[] = {
>  
>  };
>  
> +static struct meson_msr_id clk_msr_a1[] = {

And existing code uses what sort of array? Seems you send us obsolete or
downstream code.

Best regards,
Krzysztof


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox