coresight: Updates for Linux v7.3

This is relatively smaller update for CoreSight/hwtracing subsystem updates.
  - MAINTAINERS update for HiSilicon PCI Trace & Tune drivers
  - Minor fixes to hisi_ptt driver
  - Various fixes to the coresight etm4x dirvers
 
 Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEuFy0byloRoXZHaWBxcXRZPKyBqEFAmp18fwACgkQxcXRZPKy
 BqEXARAAln7ZWpWOsmhiNlHPHWSsY0ezUYLrKSsmR80EZkvX6Wk75Ju5r1fH8v/o
 vG8Dqr8ryIPPDN4JGeXLsymfbctap/3jXFl/Y+ZQeq8BWo6Weriof3/08KR2P1kG
 bVT8FgcHjY15WzNaTrI10enMfXu8CR9GCqPNI0R72EnKKN0f3kgYin67YE9lS2YO
 25Dtl3+PtVD0qN9VxIGPCoh2Njwjre9DCKw+SwlDO97Km+s5uHXI06QJpj7rC27V
 YEKEFaXiMk8ZrSidXyBE78QOZRjmJ5jNWxOXs8tquw40ootZNLoJ1blx8GOWEukL
 ppUGYALkzelM6uewxy4W+v66eYQf6xCbIHBRUUa/4zqngJjqmuTbvyDW9bZ1mCCE
 nd8VuuskMrcM+mxYvBBbiqD/RJyH7eT7IPuXZN0u+wvNV6uiosoRB4VrElwC0NEE
 gB/DkF1ChBddKCD3xJ1U4oAYRmkEqJ9StzpNz+Jr54Gg62RiWjoxEqhBBULwI3vO
 gpDgjV9LvVLr2BC2GIk5o2BFE7skJppaP4evKKZSG5uuDc/h7YZvSdl81nYscSG+
 kWgFC5MQc0HXBhVw7C+DIJPwsCRN//30wo7wrA8+GiLJ+UffKhsqjH9+jRnEPSkf
 XKNSpRoP5IeDNWdR5/6I1Kotf0dmF6RYXUOlPs7de2tWFNDIyS8=
 =iRuU
 -----END PGP SIGNATURE-----

Merge tag 'coresight-next-v7.3' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/coresight/linux into char-misc-next

Suzuki writes:

coresight: Updates for Linux v7.3

This is relatively smaller update for CoreSight/hwtracing subsystem updates.
 - MAINTAINERS update for HiSilicon PCI Trace & Tune drivers
 - Minor fixes to hisi_ptt driver
 - Various fixes to the coresight etm4x dirvers

Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>

* tag 'coresight-next-v7.3' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/coresight/linux:
  coresight: etm4x: remove redundant fields in etmv4_save_state
  coresight: etm4x: missing cscfg_csdev_disable_active_config() in perf enable
  coresight: etm4x: fix leaked trace id
  coresight: etm4x: fix underflow for usage of (nrseqstate - 1)
  coresight: etm4x: fix wrong check of etm4x_sspcicrn_present()
  hwtracing: hisi_ptt: Remove unnecessary trace buffer zeroing in trace_start()
  hwtracing: hisi_ptt: Propagate DMA reset timeout in trace_start()
  MAINTAINERS: Update HiSilicon PCI Trace and Tune maintainer
  coresight: etm3x: Fix cntr_val_show() to match cntr_val_store() behavior
This commit is contained in:
Greg Kroah-Hartman 2026-08-19 09:57:51 +02:00
commit 8992f32c57
7 changed files with 63 additions and 59 deletions

View File

@ -11770,8 +11770,7 @@ F: drivers/perf/hisilicon
F: tools/perf/pmu-events/arch/arm64/hisilicon/
HISILICON PTT DRIVER
M: Yicong Yang <yangyicong@hisilicon.com>
M: Jonathan Cameron <jonathan.cameron@huawei.com>
M: Sizhe Liu <liusizhe5@huawei.com>
L: linux-kernel@vger.kernel.org
S: Maintained
F: Documentation/ABI/testing/sysfs-bus-event_source-devices-hisi_ptt

View File

@ -717,26 +717,19 @@ static DEVICE_ATTR_RW(cntr_rld_event);
static ssize_t cntr_val_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int i, ret = 0;
u32 val;
struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
struct etm_config *config = &drvdata->config;
if (!coresight_get_mode(drvdata->csdev)) {
spin_lock(&drvdata->spinlock);
for (i = 0; i < drvdata->nr_cntr; i++)
ret += sprintf(buf, "counter %d: %x\n",
i, config->cntr_val[i]);
val = config->cntr_val[config->cntr_idx];
spin_unlock(&drvdata->spinlock);
return ret;
} else {
val = etm_readl(drvdata, ETMCNTVRn(config->cntr_idx));
}
for (i = 0; i < drvdata->nr_cntr; i++) {
val = etm_readl(drvdata, ETMCNTVRn(i));
ret += sprintf(buf, "counter %d: %x\n", i, val);
}
return ret;
return sysfs_emit(buf, "%#x\n", val);
}
static ssize_t cntr_val_store(struct device *dev,

View File

@ -76,7 +76,7 @@ static int etm4_cfg_map_reg_offset(struct etmv4_drvdata *drvdata,
} else if ((offset & GENMASK(11, 4)) == TRCSEQEVRn(0)) {
/* sequencer state control registers */
idx = (offset & GENMASK(3, 0)) / 4;
if (idx < ETM_MAX_SEQ_STATES) {
if (idx < ETM_MAX_SEQ_TRANSITIONS) {
reg_csdev->driver_regval = &drvcfg->seq_ctrl[idx];
err = 0;
}

View File

@ -93,7 +93,7 @@ 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 &&
drvdata->nr_pe_cmp &&
(drvdata->config.ss_status[n] & TRCSSCSRn_PC);
}
@ -542,7 +542,8 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
etm4x_relaxed_write32(csa, config->vissctlr, TRCVISSCTLR);
if (drvdata->nr_pe_cmp)
etm4x_relaxed_write32(csa, config->vipcssctlr, TRCVIPCSSCTLR);
for (i = 0; i < drvdata->nrseqstate - 1; i++)
for (i = 0; i < drvdata->nr_seq_ctrls; i++)
etm4x_relaxed_write32(csa, config->seq_ctrl[i], TRCSEQEVRn(i));
if (drvdata->nrseqstate) {
etm4x_relaxed_write32(csa, config->seq_rst, TRCSEQRSTEVR);
@ -756,8 +757,7 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
.ATTR_CFG_FLD_timestamp_CFG = U64_MAX,
};
struct perf_event_attr *attr = &event->attr;
unsigned long cfg_hash;
int preset, cc_threshold;
int cc_threshold;
u8 ts_level;
/* Clear configuration from previous run */
@ -843,16 +843,6 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
/* bit[12], Return stack enable bit */
config->cfg |= TRCCONFIGR_RS;
/*
* Set any selected configuration and preset. A zero configid means no
* configuration active, preset = 0 means no preset selected.
*/
cfg_hash = ATTR_CFG_GET_FLD(attr, configid);
if (cfg_hash) {
preset = ATTR_CFG_GET_FLD(attr, preset);
ret = cscfg_csdev_enable_active_config(csdev, cfg_hash, preset);
}
/* branch broadcast - enable if selected and supported */
if (ATTR_CFG_GET_FLD(attr, branch_broadcast)) {
if (!drvdata->trcbb) {
@ -876,7 +866,9 @@ static int etm4_enable_perf(struct coresight_device *csdev,
struct coresight_path *path)
{
struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
int ret;
struct perf_event_attr *attr = &event->attr;
unsigned long cfg_hash;
int ret, preset;
if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id()))
return -EINVAL;
@ -887,7 +879,19 @@ static int etm4_enable_perf(struct coresight_device *csdev,
/* Configure the tracer based on the session's specifics */
ret = etm4_parse_event_config(csdev, event);
if (ret)
goto out;
goto err;
/*
* Set any selected configuration and preset. A zero configid means no
* configuration active, preset = 0 means no preset selected.
*/
cfg_hash = ATTR_CFG_GET_FLD(attr, configid);
if (cfg_hash) {
preset = ATTR_CFG_GET_FLD(attr, preset);
ret = cscfg_csdev_enable_active_config(csdev, cfg_hash, preset);
if (ret)
goto err;
}
drvdata->trcid = path->trace_id;
@ -896,16 +900,19 @@ static int etm4_enable_perf(struct coresight_device *csdev,
/* And enable it */
ret = etm4_enable_hw(drvdata);
out:
/* Failed to start tracer; roll back to DISABLED mode */
if (ret) {
coresight_set_mode(csdev, CS_MODE_DISABLED);
return ret;
if (cfg_hash)
cscfg_csdev_disable_active_config(csdev);
goto err;
}
csdev->path = path;
return 0;
err:
/* Failed to start tracer; roll back to DISABLED mode */
coresight_set_mode(csdev, CS_MODE_DISABLED);
return ret;
}
static int etm4_enable_sysfs(struct coresight_device *csdev, struct coresight_path *path)
@ -919,8 +926,10 @@ static int etm4_enable_sysfs(struct coresight_device *csdev, struct coresight_pa
cscfg_config_sysfs_get_active_cfg(&cfg_hash, &preset);
if (cfg_hash) {
ret = cscfg_csdev_enable_active_config(csdev, cfg_hash, preset);
if (ret)
if (ret) {
etm4_release_trace_id(drvdata);
return ret;
}
}
raw_spin_lock(&drvdata->spinlock);
@ -1508,6 +1517,8 @@ static void etm4_init_arch_data(void *info)
drvdata->lpoverride = (etmidr5 & TRCIDR5_LPOVERRIDE) && (!drvdata->skip_power_up);
/* NUMSEQSTATE, bits[27:25] number of sequencer states implemented */
drvdata->nrseqstate = FIELD_GET(TRCIDR5_NUMSEQSTATE_MASK, etmidr5);
if (drvdata->nrseqstate)
drvdata->nr_seq_ctrls = ETM_MAX_SEQ_TRANSITIONS;
/* NUMCNTR, bits[30:28] number of counters available for tracing */
drvdata->nr_cntr = FIELD_GET(TRCIDR5_NUMCNTR_MASK, etmidr5);
@ -1896,7 +1907,7 @@ static int etm4_cpu_save(struct coresight_device *csdev)
if (drvdata->nr_pe_cmp)
state->trcvipcssctlr = etm4x_read32(csa, TRCVIPCSSCTLR);
for (i = 0; i < drvdata->nrseqstate - 1; i++)
for (i = 0; i < drvdata->nr_seq_ctrls; i++)
state->trcseqevr[i] = etm4x_read32(csa, TRCSEQEVRn(i));
if (drvdata->nrseqstate) {
@ -2009,7 +2020,7 @@ static void etm4_cpu_restore(struct coresight_device *csdev)
if (drvdata->nr_pe_cmp)
etm4x_relaxed_write32(csa, state->trcvipcssctlr, TRCVIPCSSCTLR);
for (i = 0; i < drvdata->nrseqstate - 1; i++)
for (i = 0; i < drvdata->nr_seq_ctrls; i++)
etm4x_relaxed_write32(csa, state->trcseqevr[i], TRCSEQEVRn(i));
if (drvdata->nrseqstate) {

View File

@ -223,7 +223,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 < drvdata->nr_seq_ctrls; i++)
config->seq_ctrl[i] = 0x0;
config->seq_rst = 0x0;
config->seq_state = 0x0;
@ -1395,9 +1395,11 @@ static ssize_t seq_idx_store(struct device *dev,
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
struct etmv4_config *config = &drvdata->config;
if (!drvdata->nr_seq_ctrls)
return -ENOTSUPP;
if (kstrtoul(buf, 16, &val))
return -EINVAL;
if (val >= drvdata->nrseqstate - 1)
if (val >= drvdata->nr_seq_ctrls)
return -EINVAL;
/*

View File

@ -614,6 +614,7 @@ static inline u32 etm4_res_sel_pair(u8 res_sel_idx)
#define ETM_MAX_NR_PE 8
#define ETMv4_MAX_CNTR 4
#define ETM_MAX_SEQ_STATES 4
#define ETM_MAX_SEQ_TRANSITIONS 3
#define ETM_MAX_EXT_INP_SEL 4
#define ETM_MAX_EXT_INP 256
#define ETM_MAX_EXT_OUT 4
@ -877,7 +878,7 @@ struct etmv4_config {
u32 vipcssctlr;
u8 seq_idx;
u8 syncfreq;
u32 seq_ctrl[ETM_MAX_SEQ_STATES];
u32 seq_ctrl[ETM_MAX_SEQ_TRANSITIONS];
u32 seq_rst;
u32 seq_state;
u8 cntr_idx;
@ -928,7 +929,7 @@ struct etmv4_save_state {
u32 trcvissctlr;
u32 trcvipcssctlr;
u32 trcseqevr[ETM_MAX_SEQ_STATES];
u32 trcseqevr[ETM_MAX_SEQ_TRANSITIONS];
u32 trcseqrstevr;
u32 trcseqstr;
u32 trcextinselr;
@ -953,11 +954,6 @@ struct etmv4_save_state {
u32 trcclaimset;
u32 cntr_val[ETMv4_MAX_CNTR];
u32 seq_state;
u32 vinst_ctrl;
u32 ss_status[ETM_MAX_SS_CMP];
u32 trcpdcr;
};
@ -981,6 +977,7 @@ struct etmv4_save_state {
* @numcidc: Number of contextID comparators.
* @numvmidc: Number of VMID comparators.
* @nrseqstate: The number of sequencer states that are implemented.
* @nr_seq_ctrls: The number of sequence state transition control registers.
* @nr_event: Indicates how many events the trace unit support.
* @nr_resource:The number of resource selection pairs available for tracing.
* @nr_ss_cmp: Number of single-shot comparator controls that are available.
@ -1046,6 +1043,7 @@ struct etmv4_drvdata {
u8 numextinsel;
u8 numvmidc;
u8 nrseqstate;
u8 nr_seq_ctrls;
u8 nr_event;
u8 nr_resource;
u8 nr_ss_cmp;

View File

@ -171,13 +171,13 @@ static bool hisi_ptt_wait_trace_hw_idle(struct hisi_ptt *hisi_ptt)
HISI_PTT_WAIT_TRACE_TIMEOUT_US);
}
static void hisi_ptt_wait_dma_reset_done(struct hisi_ptt *hisi_ptt)
static bool hisi_ptt_wait_dma_reset_done(struct hisi_ptt *hisi_ptt)
{
u32 val;
readl_poll_timeout_atomic(hisi_ptt->iobase + HISI_PTT_TRACE_WR_STS,
val, !val, HISI_PTT_RESET_POLL_INTERVAL_US,
HISI_PTT_RESET_TIMEOUT_US);
return !readl_poll_timeout_atomic(hisi_ptt->iobase + HISI_PTT_TRACE_WR_STS,
val, !val, HISI_PTT_RESET_POLL_INTERVAL_US,
HISI_PTT_RESET_TIMEOUT_US);
}
static void hisi_ptt_trace_end(struct hisi_ptt *hisi_ptt)
@ -194,7 +194,6 @@ static int hisi_ptt_trace_start(struct hisi_ptt *hisi_ptt)
{
struct hisi_ptt_trace_ctrl *ctrl = &hisi_ptt->trace_ctrl;
u32 val;
int i;
/* Check device idle before start trace */
if (!hisi_ptt_wait_trace_hw_idle(hisi_ptt)) {
@ -202,14 +201,18 @@ static int hisi_ptt_trace_start(struct hisi_ptt *hisi_ptt)
return -EBUSY;
}
ctrl->started = true;
/* Reset the DMA before start tracing */
val = readl(hisi_ptt->iobase + HISI_PTT_TRACE_CTRL);
val |= HISI_PTT_TRACE_CTRL_RST;
writel(val, hisi_ptt->iobase + HISI_PTT_TRACE_CTRL);
hisi_ptt_wait_dma_reset_done(hisi_ptt);
if (!hisi_ptt_wait_dma_reset_done(hisi_ptt)) {
pci_err(hisi_ptt->pdev, "timed out waiting for DMA reset\n");
val = readl(hisi_ptt->iobase + HISI_PTT_TRACE_CTRL);
val &= ~HISI_PTT_TRACE_CTRL_RST;
writel(val, hisi_ptt->iobase + HISI_PTT_TRACE_CTRL);
return -ETIMEDOUT;
}
val = readl(hisi_ptt->iobase + HISI_PTT_TRACE_CTRL);
val &= ~HISI_PTT_TRACE_CTRL_RST;
@ -218,10 +221,6 @@ static int hisi_ptt_trace_start(struct hisi_ptt *hisi_ptt)
/* Reset the index of current buffer */
hisi_ptt->trace_ctrl.buf_index = 0;
/* Zero the trace buffers */
for (i = 0; i < HISI_PTT_TRACE_BUF_CNT; i++)
memset(ctrl->trace_buf[i].addr, 0, HISI_PTT_TRACE_BUF_SIZE);
/* Clear the interrupt status */
writel(HISI_PTT_TRACE_INT_STAT_MASK, hisi_ptt->iobase + HISI_PTT_TRACE_INT_STAT);
writel(0, hisi_ptt->iobase + HISI_PTT_TRACE_INT_MASK);
@ -234,6 +233,8 @@ static int hisi_ptt_trace_start(struct hisi_ptt *hisi_ptt)
if (!hisi_ptt->trace_ctrl.is_port)
val |= HISI_PTT_TRACE_CTRL_FILTER_MODE;
ctrl->started = true;
/* Start the Trace */
val |= HISI_PTT_TRACE_CTRL_EN;
writel(val, hisi_ptt->iobase + HISI_PTT_TRACE_CTRL);