diff options
Diffstat (limited to 'drivers/hwtracing/coresight')
-rw-r--r-- | drivers/hwtracing/coresight/coresight-etm-perf.c | 2 | ||||
-rw-r--r-- | drivers/hwtracing/coresight/coresight-etm4x-sysfs.c | 21 | ||||
-rw-r--r-- | drivers/hwtracing/coresight/coresight-etm4x.c | 1 | ||||
-rw-r--r-- | drivers/hwtracing/coresight/coresight-priv.h | 3 | ||||
-rw-r--r-- | drivers/hwtracing/coresight/coresight-tmc-etf.c | 29 | ||||
-rw-r--r-- | drivers/hwtracing/coresight/coresight-tmc-etr.c | 80 | ||||
-rw-r--r-- | drivers/hwtracing/coresight/coresight-tmc.c | 21 | ||||
-rw-r--r-- | drivers/hwtracing/coresight/coresight-tmc.h | 99 | ||||
-rw-r--r-- | drivers/hwtracing/coresight/coresight.c | 25 |
9 files changed, 244 insertions, 37 deletions
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index 1ef098ff27c3..6558dd7652a5 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -223,7 +223,7 @@ static void *etm_setup_aux(struct perf_event *event, void **pages, id = (u32)event->attr.config2; sink = coresight_get_sink_by_id(id); } else { - sink = coresight_get_enabled_sink(true); + sink = coresight_get_enabled_sink(NULL, true); } if (!sink) diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c index a0365e23678e..f5fb1e7a9c17 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c @@ -655,10 +655,13 @@ static ssize_t cyc_threshold_store(struct device *dev, if (kstrtoul(buf, 16, &val)) return -EINVAL; + + /* mask off max threshold before checking min value */ + val &= ETM_CYC_THRESHOLD_MASK; if (val < drvdata->ccitmin) return -EINVAL; - config->ccctlr = val & ETM_CYC_THRESHOLD_MASK; + config->ccctlr = val; return size; } static DEVICE_ATTR_RW(cyc_threshold); @@ -689,14 +692,16 @@ static ssize_t bb_ctrl_store(struct device *dev, return -EINVAL; if (!drvdata->nr_addr_cmp) return -EINVAL; + /* - * Bit[7:0] selects which address range comparator is used for - * branch broadcast control. + * Bit[8] controls include(1) / exclude(0), bits[0-7] select + * individual range comparators. If include then at least 1 + * range must be selected. */ - if (BMVAL(val, 0, 7) > drvdata->nr_addr_cmp) + if ((val & BIT(8)) && (BMVAL(val, 0, 7) == 0)) return -EINVAL; - config->bb_ctrl = val; + config->bb_ctrl = val & GENMASK(8, 0); return size; } static DEVICE_ATTR_RW(bb_ctrl); @@ -1329,8 +1334,8 @@ static ssize_t seq_event_store(struct device *dev, spin_lock(&drvdata->spinlock); idx = config->seq_idx; - /* RST, bits[7:0] */ - config->seq_ctrl[idx] = val & 0xFF; + /* Seq control has two masks B[15:8] F[7:0] */ + config->seq_ctrl[idx] = val & 0xFFFF; spin_unlock(&drvdata->spinlock); return size; } @@ -1585,7 +1590,7 @@ static ssize_t res_ctrl_store(struct device *dev, if (idx % 2 != 0) /* PAIRINV, bit[21] */ val &= ~BIT(21); - config->res_ctrl[idx] = val; + config->res_ctrl[idx] = val & GENMASK(21, 0); spin_unlock(&drvdata->spinlock); return size; } diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 27e047ebb0ba..af4dfa955f7d 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -1202,6 +1202,7 @@ static const struct amba_id etm4_ids[] = { CS_AMBA_ID(0x000bb95a), /* Cortex-A72 */ CS_AMBA_ID(0x000bb959), /* Cortex-A73 */ CS_AMBA_UCI_ID(0x000bb9da, uci_id_etm4), /* Cortex-A35 */ + CS_AMBA_ID(0x000cc210), /* Marvell-OcteonTx-CN9xxx */ {}, }; diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h index e0684d06e9ee..83325b0f86f0 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -147,7 +147,8 @@ static inline void coresight_write_reg_pair(void __iomem *addr, u64 val, void coresight_disable_path(struct list_head *path); int coresight_enable_path(struct list_head *path, u32 mode, void *sink_data); struct coresight_device *coresight_get_sink(struct list_head *path); -struct coresight_device *coresight_get_enabled_sink(bool reset); +struct coresight_device *coresight_get_enabled_sink(struct coresight_device *cs, + bool reset); struct coresight_device *coresight_get_sink_by_id(u32 id); struct list_head *coresight_build_path(struct coresight_device *csdev, struct coresight_device *sink); diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c index 8de109de171f..e43e9ef0617c 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c @@ -592,13 +592,6 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata) goto out; } - /* There is no point in reading a TMC in HW FIFO mode */ - mode = readl_relaxed(drvdata->base + TMC_MODE); - if (mode != TMC_MODE_CIRCULAR_BUFFER) { - ret = -EINVAL; - goto out; - } - /* Don't interfere if operated from Perf */ if (drvdata->mode == CS_MODE_PERF) { ret = -EINVAL; @@ -612,8 +605,15 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata) } /* Disable the TMC if need be */ - if (drvdata->mode == CS_MODE_SYSFS) + if (drvdata->mode == CS_MODE_SYSFS) { + /* There is no point in reading a TMC in HW FIFO mode */ + mode = readl_relaxed(drvdata->base + TMC_MODE); + if (mode != TMC_MODE_CIRCULAR_BUFFER) { + ret = -EINVAL; + goto out; + } __tmc_etb_disable_hw(drvdata); + } drvdata->reading = true; out: @@ -635,15 +635,14 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata) spin_lock_irqsave(&drvdata->spinlock, flags); - /* There is no point in reading a TMC in HW FIFO mode */ - mode = readl_relaxed(drvdata->base + TMC_MODE); - if (mode != TMC_MODE_CIRCULAR_BUFFER) { - spin_unlock_irqrestore(&drvdata->spinlock, flags); - return -EINVAL; - } - /* Re-enable the TMC if need be */ if (drvdata->mode == CS_MODE_SYSFS) { + /* There is no point in reading a TMC in HW FIFO mode */ + mode = readl_relaxed(drvdata->base + TMC_MODE); + if (mode != TMC_MODE_CIRCULAR_BUFFER) { + spin_unlock_irqrestore(&drvdata->spinlock, flags); + return -EINVAL; + } /* * The trace run will continue with the same allocated trace * buffer. As such zero-out the buffer so that we don't end diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index 9f293b9dce8c..1ed2ea51f222 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -16,6 +16,7 @@ #include <linux/vmalloc.h> #include "coresight-catu.h" #include "coresight-etm-perf.h" +#include <linux/arm-smccc.h> #include "coresight-priv.h" #include "coresight-tmc.h" @@ -590,6 +591,9 @@ static int tmc_etr_alloc_flat_buf(struct tmc_drvdata *drvdata, void **pages) { struct etr_flat_buf *flat_buf; + dma_addr_t s_paddr = 0; + int buff_sec_mapped = 0; + int ret; /* We cannot reuse existing pages for flat buf */ if (pages) @@ -606,12 +610,44 @@ static int tmc_etr_alloc_flat_buf(struct tmc_drvdata *drvdata, return -ENOMEM; } + if (!(drvdata->etr_options & CORESIGHT_OPTS_SECURE_BUFF)) + goto skip_secure_buffer; + + /* Register driver allocated dma buffer for necessary + * mapping in the secure world + */ + if (tmc_register_drvbuf(drvdata, flat_buf->daddr, etr_buf->size)) { + ret = -ENOMEM; + goto err; + } + buff_sec_mapped = 1; + + /* Allocate secure trace buffer */ + if (tmc_alloc_secbuf(drvdata, etr_buf->size, &s_paddr)) { + ret = -ENOMEM; + goto err; + } + +skip_secure_buffer: flat_buf->size = etr_buf->size; flat_buf->dev = drvdata->dev; etr_buf->hwaddr = flat_buf->daddr; + etr_buf->s_paddr= s_paddr; etr_buf->mode = ETR_MODE_FLAT; etr_buf->private = flat_buf; return 0; + +err: + kfree(flat_buf); + dma_free_coherent(drvdata->dev, etr_buf->size, flat_buf->vaddr, + flat_buf->daddr); + if (buff_sec_mapped) + tmc_unregister_drvbuf(drvdata, flat_buf->daddr, + etr_buf->size); + if (s_paddr) + tmc_free_secbuf(drvdata, s_paddr, etr_buf->size); + + return ret; } static void tmc_etr_free_flat_buf(struct etr_buf *etr_buf) @@ -937,10 +973,17 @@ static void __tmc_etr_enable_hw(struct tmc_drvdata *drvdata) CS_UNLOCK(drvdata->base); + if (drvdata->etr_options & CORESIGHT_OPTS_RESET_CTL_REG) + tmc_disable_hw(drvdata); + /* Wait for TMCSReady bit to be set */ tmc_wait_for_tmcready(drvdata); writel_relaxed(etr_buf->size / 4, drvdata->base + TMC_RSZ); + if (drvdata && CORESIGHT_OPTS_BUFFSIZE_8BX) + writel_relaxed(etr_buf->size / 8, drvdata->base + TMC_RSZ); + else + writel_relaxed(etr_buf->size / 4, drvdata->base + TMC_RSZ); writel_relaxed(TMC_MODE_CIRCULAR_BUFFER, drvdata->base + TMC_MODE); axictl = readl_relaxed(drvdata->base + TMC_AXICTL); @@ -957,7 +1000,10 @@ static void __tmc_etr_enable_hw(struct tmc_drvdata *drvdata) axictl |= TMC_AXICTL_SCT_GAT_MODE; writel_relaxed(axictl, drvdata->base + TMC_AXICTL); - tmc_write_dba(drvdata, etr_buf->hwaddr); + if (drvdata->etr_options & CORESIGHT_OPTS_SECURE_BUFF) + tmc_write_dba(drvdata, etr_buf->s_paddr); + else + tmc_write_dba(drvdata, etr_buf->hwaddr); /* * If the TMC pointers must be programmed before the session, * we have to set it properly (i.e, RRP/RWP to base address and @@ -965,7 +1011,10 @@ static void __tmc_etr_enable_hw(struct tmc_drvdata *drvdata) */ if (tmc_etr_has_cap(drvdata, TMC_ETR_SAVE_RESTORE)) { tmc_write_rrp(drvdata, etr_buf->hwaddr); - tmc_write_rwp(drvdata, etr_buf->hwaddr); + if (drvdata->etr_options & CORESIGHT_OPTS_SECURE_BUFF) + tmc_write_rwp(drvdata, etr_buf->s_paddr); + else + tmc_write_rwp(drvdata, etr_buf->hwaddr); sts = readl_relaxed(drvdata->base + TMC_STS) & ~TMC_STS_FULL; writel_relaxed(sts, drvdata->base + TMC_STS); } @@ -1476,7 +1525,7 @@ tmc_update_etr_buffer(struct coresight_device *csdev, goto out; } - if (WARN_ON(drvdata->perf_data != etr_perf)) { + if (WARN_ON(drvdata->perf_buf != etr_buf)) { lost = true; spin_unlock_irqrestore(&drvdata->spinlock, flags); goto out; @@ -1488,8 +1537,6 @@ tmc_update_etr_buffer(struct coresight_device *csdev, tmc_sync_etr_buf(drvdata); CS_LOCK(drvdata->base); - /* Reset perf specific data */ - drvdata->perf_data = NULL; spin_unlock_irqrestore(&drvdata->spinlock, flags); size = etr_buf->len; @@ -1543,7 +1590,6 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data) } etr_perf->head = PERF_IDX2OFF(handle->head, etr_perf); - drvdata->perf_data = etr_perf; /* * No HW configuration is needed if the sink is already in @@ -1559,6 +1605,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data) /* Associate with monitored process. */ drvdata->pid = pid; drvdata->mode = CS_MODE_PERF; + drvdata->perf_buf = etr_perf->etr_buf; atomic_inc(csdev->refcnt); } @@ -1604,6 +1651,8 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev) /* Dissociate from monitored process. */ drvdata->pid = -1; drvdata->mode = CS_MODE_DISABLED; + /* Reset perf specific data */ + drvdata->perf_buf = NULL; spin_unlock_irqrestore(&drvdata->spinlock, flags); @@ -1696,3 +1745,22 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata) return 0; } + +int tmc_copy_secure_buffer(struct tmc_drvdata *drvdata, + char *bufp, size_t len) +{ + struct arm_smccc_res res; + uint64_t offset; + char *vaddr; + struct etr_buf *etr_buf = drvdata->etr_buf; + + tmc_etr_buf_get_data(etr_buf, 0, 0, &vaddr); + offset = bufp - vaddr; + + arm_smccc_smc(OCTEONTX_TRC_COPY_TO_DRVBUF, etr_buf->hwaddr + offset, + etr_buf->s_paddr + offset, len, 0, 0, 0, 0, &res); + if (res.a0 != SMCCC_RET_SUCCESS) + return -EFAULT; + + return 0; +} diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 3f718729d741..17759762abdc 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -151,6 +151,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len, if (actual <= 0) return 0; + if ((drvdata->etr_options & CORESIGHT_OPTS_SECURE_BUFF) && + tmc_copy_secure_buffer(drvdata, bufp, len)) + return -EFAULT; + if (copy_to_user(data, bufp, actual)) { dev_dbg(drvdata->dev, "%s: copy_to_user failed\n", __func__); return -EFAULT; @@ -419,11 +423,21 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) spin_lock_init(&drvdata->spinlock); + drvdata->cpu = pdata ? pdata->cpu : 0; + + /* Enable options for Silicon issues */ + if (id->id == OCTEONTX_CN9XXX_ETR) + drvdata->etr_options = CORESIGHT_OPTS_BUFFSIZE_8BX | + CORESIGHT_OPTS_SECURE_BUFF | + CORESIGHT_OPTS_RESET_CTL_REG; + devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID); drvdata->config_type = BMVAL(devid, 6, 7); drvdata->memwidth = tmc_get_memwidth(devid); /* This device is not associated with a session */ drvdata->pid = -1; + drvdata->formatter_en = !(readl_relaxed(drvdata->base + TMC_FFSR) & + TMC_FFSR_FT_NOT_PRESENT); if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) { if (np) @@ -432,6 +446,11 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) &drvdata->size); if (ret) drvdata->size = SZ_1M; + + /* Cache locked buffer */ + if (np) + drvdata->cache_lock_en = of_property_read_bool(np, + "cache-lock"); } else { drvdata->size = readl_relaxed(drvdata->base + TMC_RSZ) * 4; } @@ -494,6 +513,8 @@ static const struct amba_id tmc_ids[] = { CS_AMBA_ID(0x000bb9e9), /* Coresight SoC 600 TMC-ETF */ CS_AMBA_ID(0x000bb9ea), + /* Marvell OcteonTx CN9xxx */ + CS_AMBA_ID_DATA(OCTEONTX_CN9XXX_ETR, (unsigned long)OCTEONTX_CN9XXX_ETR_CAPS), { 0, 0}, }; diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index 503f1b3a3741..46118e93f1a9 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -12,6 +12,7 @@ #include <linux/miscdevice.h> #include <linux/mutex.h> #include <linux/refcount.h> +#include <linux/arm-smccc.h> #define TMC_RSZ 0x004 #define TMC_STS 0x00c @@ -73,6 +74,9 @@ #define TMC_AXICTL_AXCACHE_OS (0xf << 2) #define TMC_AXICTL_ARCACHE_OS (0xf << 16) +/* TMC_FFSR - 0x300 */ +#define TMC_FFSR_FT_NOT_PRESENT BIT(4) + /* TMC_FFCR - 0x304 */ #define TMC_FFCR_FLUSHMAN_BIT 6 #define TMC_FFCR_EN_FMT BIT(0) @@ -126,6 +130,33 @@ enum tmc_mem_intf_width { #define CORESIGHT_SOC_600_ETR_CAPS \ (TMC_ETR_SAVE_RESTORE | TMC_ETR_AXI_ARCACHE) +/* Marvell OcteonTx CN9xxx TMC-ETR unadvertised capabilities */ +#define OCTEONTX_CN9XXX_ETR_CAPS \ + (TMC_ETR_SAVE_RESTORE) + +/* Marvell OcteonTx CN9xxx device */ +#define OCTEONTX_CN9XXX_ETR 0x000cc213 + +/* Marvell OcteonTx CN9xxx HW issues */ +#define CORESIGHT_OPTS_BUFFSIZE_8BX (0x1U << 0) /* 8 byte size multiplier */ +#define CORESIGHT_OPTS_SECURE_BUFF (0x1U << 1) /* Trace buffer is Secure */ +#define CORESIGHT_OPTS_RESET_CTL_REG (0x1U << 2) /* Reset CTL on reset */ + +/* SMC call ids for managing the secure trace buffer */ + +/* Args: x1 - size, x2 - cpu, x3 - llc lock flag + * Returns: x0 - status, x1 - secure buffer address + */ +#define OCTEONTX_TRC_ALLOC_SBUF 0xc2000c05 +/* Args: x1 - non secure buffer address, x2 - size */ +#define OCTEONTX_TRC_REGISTER_DRVBUF 0xc2000c06 +/* Args: x1 - dst(non secure), x2 - src(secure), x3 - size */ +#define OCTEONTX_TRC_COPY_TO_DRVBUF 0xc2000c07 +/* Args: x1 - secure buffer address, x2 - size */ +#define OCTEONTX_TRC_FREE_SBUF 0xc2000c08 +/* Args: x1 - non secure buffer address, x2 - size */ +#define OCTEONTX_TRC_UNREGISTER_DRVBUF 0xc2000c09 + enum etr_mode { ETR_MODE_FLAT, /* Uses contiguous flat buffer */ ETR_MODE_ETR_SG, /* Uses in-built TMC ETR SG mechanism */ @@ -141,6 +172,7 @@ struct etr_buf_operations; * @full : Trace data overflow * @size : Size of the buffer. * @hwaddr : Address to be programmed in the TMC:DBA{LO,HI} + * @s_paddr : Secure trace buffer * @offset : Offset of the trace data in the buffer for consumption. * @len : Available trace data @buf (may round up to the beginning). * @ops : ETR buffer operations for the mode. @@ -152,6 +184,7 @@ struct etr_buf { bool full; ssize_t size; dma_addr_t hwaddr; + dma_addr_t s_paddr; unsigned long offset; s64 len; const struct etr_buf_operations *ops; @@ -164,13 +197,14 @@ struct etr_buf { * @dev: the device entity associated to this component. * @csdev: component vitals needed by the framework. * @miscdev: specifics to handle "/dev/xyz.tmc" entry. - * @spinlock: only one at a time pls. - * @pid: Process ID of the process being monitored by the session + * @spinlock: only one at a time pls. * @pid: Process ID of the process being monitored by the session * that is using this component. * @buf: Snapshot of the trace data for ETF/ETB. * @etr_buf: details of buffer used in TMC-ETR * @len: size of the available trace for ETF/ETB. * @size: trace buffer size for this TMC (common for all modes). + * @formatter_en: Formatter enable/disable status + * @cache_lock_en: Cache lock status * @mode: how this TMC is being used. * @config_type: TMC variant, must be of type @tmc_config_type. * @memwidth: width of the memory interface databus, in bytes. @@ -179,8 +213,10 @@ struct etr_buf { * device configuration register (DEVID) * @idr: Holds etr_bufs allocated for this ETR. * @idr_mutex: Access serialisation for idr. - * @perf_data: PERF buffer for ETR. - * @sysfs_data: SYSFS buffer for ETR. + * @sysfs_buf: SYSFS buffer for ETR. + * @perf_buf: PERF buffer for ETR. + * @etr_options: Bitmask of options to manage Silicon issues + * @cpu: CPU id this component is associated with */ struct tmc_drvdata { void __iomem *base; @@ -194,6 +230,8 @@ struct tmc_drvdata { char *buf; /* TMC ETB */ struct etr_buf *etr_buf; /* TMC ETR */ }; + bool formatter_en; + bool cache_lock_en; u32 len; u32 size; u32 mode; @@ -205,6 +243,9 @@ struct tmc_drvdata { struct mutex idr_mutex; struct etr_buf *sysfs_buf; void *perf_data; + u32 etr_options; + int cpu; + struct etr_buf *perf_buf; }; struct etr_buf_operations { @@ -322,4 +363,54 @@ tmc_sg_table_buf_size(struct tmc_sg_table *sg_table) struct coresight_device *tmc_etr_get_catu_device(struct tmc_drvdata *drvdata); +static inline int tmc_alloc_secbuf(struct tmc_drvdata *drvdata, + size_t len, dma_addr_t *s_paddr) +{ + struct arm_smccc_res res; + + arm_smccc_smc(OCTEONTX_TRC_ALLOC_SBUF, len, drvdata->cpu, + drvdata->cache_lock_en, 0, 0, 0, 0, &res); + if (res.a0 != SMCCC_RET_SUCCESS) + return -EFAULT; + + *s_paddr = res.a1; + return 0; +} + +static inline int tmc_free_secbuf(struct tmc_drvdata *drvdata, + dma_addr_t s_paddr, size_t len) +{ + struct arm_smccc_res res; + + arm_smccc_smc(OCTEONTX_TRC_FREE_SBUF, s_paddr, len, + 0, 0, 0, 0, 0, &res); + return 0; +} + +static inline int tmc_register_drvbuf(struct tmc_drvdata *drvdata, + dma_addr_t paddr, size_t len) +{ + struct arm_smccc_res res; + + arm_smccc_smc(OCTEONTX_TRC_REGISTER_DRVBUF, paddr, len, + 0, 0, 0, 0, 0, &res); + if (res.a0 != SMCCC_RET_SUCCESS) + return -EFAULT; + + return 0; +} + +static inline int tmc_unregister_drvbuf(struct tmc_drvdata *drvdata, + dma_addr_t paddr, size_t len) +{ + struct arm_smccc_res res; + + arm_smccc_smc(OCTEONTX_TRC_UNREGISTER_DRVBUF, paddr, len, + 0, 0, 0, 0, 0, &res); + return 0; + +} + +int tmc_copy_secure_buffer(struct tmc_drvdata *drvdata, + char *bufp, size_t len); #endif diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 4b130281236a..1fbf7e125b23 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -524,6 +524,7 @@ static int coresight_enabled_sink(struct device *dev, void *data) /** * coresight_get_enabled_sink - returns the first enabled sink found on the bus + * In case the child port is a single source ETR, returns the child port as sink * @deactivate: Whether the 'enable_sink' flag should be reset * * When operated from perf the deactivate parameter should be set to 'true'. @@ -534,10 +535,30 @@ static int coresight_enabled_sink(struct device *dev, void *data) * parameter should be set to 'false', hence mandating users to explicitly * clear the flag. */ -struct coresight_device *coresight_get_enabled_sink(bool deactivate) +struct coresight_device *coresight_get_enabled_sink(struct coresight_device *s, + bool deactivate) { + struct coresight_device *child; struct device *dev = NULL; + if (s == NULL) + goto skip_single_source; + + /* If the connected port is an ETR with single trace source, + * nothing to search further. + */ + child = s->conns[0].child_dev; + if (s->nr_outport == 1 && + child->type == CORESIGHT_DEV_TYPE_SINK && + child->subtype.sink_subtype == CORESIGHT_DEV_SUBTYPE_SINK_BUFFER && + child->nr_inport == 1 && + child->activated) { + if (deactivate) + child->activated = false; + return child; + } + +skip_single_source: dev = bus_find_device(&coresight_bustype, NULL, &deactivate, coresight_enabled_sink); @@ -782,7 +803,7 @@ int coresight_enable(struct coresight_device *csdev) * Search for a valid sink for this session but don't reset the * "enable_sink" flag in sysFS. Users get to do that explicitly. */ - sink = coresight_get_enabled_sink(false); + sink = coresight_get_enabled_sink(csdev, false); if (!sink) { ret = -EINVAL; goto out; |