From 39eced7f19cb1c040781fafad418aad611f1345a Mon Sep 17 00:00:00 2001 From: Mathieu Poirier Date: Mon, 15 May 2017 09:05:41 -0600 Subject: coresight: Correct buffer lost increment Many conditions may cause synchronisation to be lost when updating the perf ring buffer but the end result is still the same: synchronisation is lost. As such there is no need to increment the lost count for each condition, just once will suffice. Signed-off-by: Mathieu Poirier --- drivers/hwtracing/coresight/coresight-etb10.c | 10 +++++++--- drivers/hwtracing/coresight/coresight-tmc-etf.c | 8 ++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index d5b96423e1a5..d9c233135d6d 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -353,6 +353,7 @@ static void etb_update_buffer(struct coresight_device *csdev, struct perf_output_handle *handle, void *sink_config) { + bool lost = false; int i, cur; u8 *buf_ptr; u32 read_ptr, write_ptr, capacity; @@ -384,7 +385,7 @@ static void etb_update_buffer(struct coresight_device *csdev, (unsigned long)write_ptr); write_ptr &= ~(ETB_FRAME_SIZE_WORDS - 1); - perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); + lost = true; } /* @@ -395,7 +396,7 @@ static void etb_update_buffer(struct coresight_device *csdev, */ status = readl_relaxed(drvdata->base + ETB_STATUS_REG); if (status & ETB_STATUS_RAM_FULL) { - perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); + lost = true; to_read = capacity; read_ptr = write_ptr; } else { @@ -428,9 +429,12 @@ static void etb_update_buffer(struct coresight_device *csdev, if (read_ptr > (drvdata->buffer_depth - 1)) read_ptr -= drvdata->buffer_depth; /* let the decoder know we've skipped ahead */ - perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); + lost = true; } + if (lost) + perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); + /* finally tell HW where we want to start reading from */ writel_relaxed(read_ptr, drvdata->base + ETB_RAM_READ_POINTER); diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c index e3b9fb82eb8d..2e0fb5b9372c 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c @@ -369,6 +369,7 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev, struct perf_output_handle *handle, void *sink_config) { + bool lost = false; int i, cur; u32 *buf_ptr; u32 read_ptr, write_ptr; @@ -397,7 +398,7 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev, */ status = readl_relaxed(drvdata->base + TMC_STS); if (status & TMC_STS_FULL) { - perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); + lost = true; to_read = drvdata->size; } else { to_read = CIRC_CNT(write_ptr, read_ptr, drvdata->size); @@ -442,9 +443,12 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev, read_ptr -= drvdata->size; /* Tell the HW */ writel_relaxed(read_ptr, drvdata->base + TMC_RRP); - perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); + lost = true; } + if (lost) + perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); + cur = buf->cur; offset = buf->offset; -- cgit v1.2.3 From d7e589c7f2cd25e25a19ed921b667bc9c66daefe Mon Sep 17 00:00:00 2001 From: Mathieu Poirier Date: Mon, 29 May 2017 11:49:51 -0600 Subject: coresight: etb10: Remove useless conversion to LE Internal CoreSight components are rendering trace data in little-endian format. As such there is no need to convert the data once more, hence removing the extra step. Signed-off-by: Mathieu Poirier --- drivers/hwtracing/coresight/coresight-etb10.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index d9c233135d6d..50f4846e6271 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -233,10 +233,8 @@ static void etb_dump_hw(struct etb_drvdata *drvdata) for (i = 0; i < depth; i++) { read_data = readl_relaxed(drvdata->base + ETB_RAM_READ_DATA_REG); - *buf_ptr++ = read_data >> 0; - *buf_ptr++ = read_data >> 8; - *buf_ptr++ = read_data >> 16; - *buf_ptr++ = read_data >> 24; + *(u32 *)buf_ptr = read_data; + buf_ptr += 4; } if (frame_off) { @@ -444,10 +442,8 @@ static void etb_update_buffer(struct coresight_device *csdev, buf_ptr = buf->data_pages[cur] + offset; read_data = readl_relaxed(drvdata->base + ETB_RAM_READ_DATA_REG); - *buf_ptr++ = read_data >> 0; - *buf_ptr++ = read_data >> 8; - *buf_ptr++ = read_data >> 16; - *buf_ptr++ = read_data >> 24; + *(u32 *)buf_ptr = read_data; + buf_ptr += 4; offset += 4; if (offset >= PAGE_SIZE) { -- cgit v1.2.3 From 784c3af24a6f0cfc81351bccfdd5985cc583d997 Mon Sep 17 00:00:00 2001 From: Mathieu Poirier Date: Thu, 29 Jun 2017 11:28:29 -0600 Subject: coresight: Add barrier packet for synchronisation When a buffer overflow happens the synchronisation patckets usually present at the beginning of the buffer are lost, a situation that prevents the decoder from knowing the context of the traces being decoded. This patch adds a barrier packet to be used by sink IPs when a buffer overflow condition is detected. These barrier packets are then used by the decoding library as markers to force re-synchronisation. Signed-off-by: Mathieu Poirier --- drivers/hwtracing/coresight/coresight-etb10.c | 22 +++++++++++++++++++-- drivers/hwtracing/coresight/coresight-priv.h | 2 ++ drivers/hwtracing/coresight/coresight-tmc-etf.c | 26 ++++++++++++++++++++++++- drivers/hwtracing/coresight/coresight-tmc-etr.c | 12 ++++++++++++ drivers/hwtracing/coresight/coresight.c | 8 ++++++++ 5 files changed, 67 insertions(+), 3 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index 50f4846e6271..42360306f049 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -200,8 +200,10 @@ static void etb_disable_hw(struct etb_drvdata *drvdata) static void etb_dump_hw(struct etb_drvdata *drvdata) { + bool lost = false; int i; u8 *buf_ptr; + const u32 *barrier; u32 read_data, depth; u32 read_ptr, write_ptr; u32 frame_off, frame_endoff; @@ -223,16 +225,24 @@ static void etb_dump_hw(struct etb_drvdata *drvdata) } if ((readl_relaxed(drvdata->base + ETB_STATUS_REG) - & ETB_STATUS_RAM_FULL) == 0) + & ETB_STATUS_RAM_FULL) == 0) { writel_relaxed(0x0, drvdata->base + ETB_RAM_READ_POINTER); - else + } else { writel_relaxed(write_ptr, drvdata->base + ETB_RAM_READ_POINTER); + lost = true; + } depth = drvdata->buffer_depth; buf_ptr = drvdata->buf; + barrier = barrier_pkt; for (i = 0; i < depth; i++) { read_data = readl_relaxed(drvdata->base + ETB_RAM_READ_DATA_REG); + if (lost && *barrier) { + read_data = *barrier; + barrier++; + } + *(u32 *)buf_ptr = read_data; buf_ptr += 4; } @@ -354,6 +364,7 @@ static void etb_update_buffer(struct coresight_device *csdev, bool lost = false; int i, cur; u8 *buf_ptr; + const u32 *barrier; u32 read_ptr, write_ptr, capacity; u32 status, read_data, to_read; unsigned long offset; @@ -438,10 +449,17 @@ static void etb_update_buffer(struct coresight_device *csdev, cur = buf->cur; offset = buf->offset; + barrier = barrier_pkt; + for (i = 0; i < to_read; i += 4) { buf_ptr = buf->data_pages[cur] + offset; read_data = readl_relaxed(drvdata->base + ETB_RAM_READ_DATA_REG); + if (lost && *barrier) { + read_data = *barrier; + barrier++; + } + *(u32 *)buf_ptr = read_data; buf_ptr += 4; diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h index 5f662d82052c..3e25b1dd1a1a 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -56,6 +56,8 @@ static ssize_t name##_show(struct device *_dev, \ } \ static DEVICE_ATTR_RO(name) +extern const u32 barrier_pkt[5]; + enum etm_addr_type { ETM_ADDR_TYPE_NONE, ETM_ADDR_TYPE_SINGLE, diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c index 2e0fb5b9372c..d189b28bd5c4 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c @@ -43,17 +43,34 @@ static void tmc_etb_enable_hw(struct tmc_drvdata *drvdata) static void tmc_etb_dump_hw(struct tmc_drvdata *drvdata) { + bool lost = false; char *bufp; - u32 read_data; + const u32 *barrier; + u32 read_data, status; int i; + /* + * Get a hold of the status register and see if a wrap around + * has occurred. + */ + status = readl_relaxed(drvdata->base + TMC_STS); + if (status & TMC_STS_FULL) + lost = true; + bufp = drvdata->buf; drvdata->len = 0; + barrier = barrier_pkt; while (1) { for (i = 0; i < drvdata->memwidth; i++) { read_data = readl_relaxed(drvdata->base + TMC_RRD); if (read_data == 0xFFFFFFFF) return; + + if (lost && *barrier) { + read_data = *barrier; + barrier++; + } + memcpy(bufp, &read_data, 4); bufp += 4; drvdata->len += 4; @@ -371,6 +388,7 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev, { bool lost = false; int i, cur; + const u32 *barrier; u32 *buf_ptr; u32 read_ptr, write_ptr; u32 status, to_read; @@ -451,12 +469,18 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev, cur = buf->cur; offset = buf->offset; + barrier = barrier_pkt; /* for every byte to read */ for (i = 0; i < to_read; i += 4) { buf_ptr = buf->data_pages[cur] + offset; *buf_ptr = readl_relaxed(drvdata->base + TMC_RRD); + if (lost && *barrier) { + *buf_ptr = *barrier; + barrier++; + } + offset += 4; if (offset >= PAGE_SIZE) { offset = 0; diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index 5d312699b3b9..b8fb981de7b6 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -59,6 +59,8 @@ static void tmc_etr_enable_hw(struct tmc_drvdata *drvdata) static void tmc_etr_dump_hw(struct tmc_drvdata *drvdata) { + const u32 *barrier; + u32 *temp; u32 rwp, val; rwp = readl_relaxed(drvdata->base + TMC_RWP); @@ -71,6 +73,16 @@ static void tmc_etr_dump_hw(struct tmc_drvdata *drvdata) if (val & TMC_STS_FULL) { drvdata->buf = drvdata->vaddr + rwp - drvdata->paddr; drvdata->len = drvdata->size; + + barrier = barrier_pkt; + temp = (u32 *)drvdata->buf; + + while (*barrier) { + *temp = *barrier; + temp++; + barrier++; + } + } else { drvdata->buf = drvdata->vaddr; drvdata->len = rwp - drvdata->paddr; diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 6a0202b7384f..b8091bef21dc 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -53,6 +53,14 @@ static DEFINE_PER_CPU(struct list_head *, tracer_path); */ static struct list_head *stm_path; +/* + * When losing synchronisation a new barrier packet needs to be inserted at the + * beginning of the data collected in a buffer. That way the decoder knows that + * it needs to look for another sync sequence. + */ +const u32 barrier_pkt[5] = {0x7fffffff, 0x7fffffff, + 0x7fffffff, 0x7fffffff, 0x0}; + static int coresight_id_match(struct device *dev, void *data) { int trace_id, i_trace_id; -- cgit v1.2.3 From b7446cc5d5b9ae4e7b34d852f682b9f3a73220c7 Mon Sep 17 00:00:00 2001 From: Mathieu Poirier Date: Fri, 16 Jun 2017 11:20:24 -0600 Subject: coresight: etb10: Move etb_disable_hw() outside of lock Function etb_disable_hw() is already taking care of unlocking and locking the coresight access register and as such doesn't need to be placed within the unlock/lock of function etb_update_buffer(). Signed-off-by: Mathieu Poirier --- drivers/hwtracing/coresight/coresight-etb10.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c index 42360306f049..d0d186575c5d 100644 --- a/drivers/hwtracing/coresight/coresight-etb10.c +++ b/drivers/hwtracing/coresight/coresight-etb10.c @@ -376,8 +376,8 @@ static void etb_update_buffer(struct coresight_device *csdev, capacity = drvdata->buffer_depth * ETB_FRAME_SIZE_WORDS; - CS_UNLOCK(drvdata->base); etb_disable_hw(drvdata); + CS_UNLOCK(drvdata->base); /* unit is in words, not bytes */ read_ptr = readl_relaxed(drvdata->base + ETB_RAM_READ_POINTER); -- cgit v1.2.3 From 2f46bc9781cda2f73fefa5e78f0c4413a0338340 Mon Sep 17 00:00:00 2001 From: Mathieu Poirier Date: Wed, 21 Jun 2017 09:54:14 -0600 Subject: coresight: etm3x: Set synchronisation frequencty to TRM default Register ETMSYNCFR holds the number of by that need to be generated before periodic synchronisation packets are inserted in the trace stream. By zeroing out the config structure, the current code effectively disable periodic synchronization. This patch simply initialise the recommended value for this register as specified in the technical reference manual. Signed-off-by: Mathieu Poirier --- drivers/hwtracing/coresight/coresight-etm3x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c index 93ee8fc539be..9d8bd4e36b32 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x.c +++ b/drivers/hwtracing/coresight/coresight-etm3x.c @@ -243,6 +243,8 @@ void etm_set_default(struct etm_config *config) } config->ctxid_mask = 0x0; + /* Setting default to 1024 as per TRM recommendation */ + config->sync_freq = 0x400; } void etm_config_trace_mode(struct etm_config *config) -- cgit v1.2.3 From 0c4ab62d8f874d8932f9dcf744ebd6f1ecf31f50 Mon Sep 17 00:00:00 2001 From: Arvind Yadav Date: Wed, 5 Jul 2017 11:19:24 +0530 Subject: hwtracing: coresight: constify attribute_group structures. attribute_groups are not supposed to change at runtime. All functions working with attribute_groups provided by work with const attribute_group. So mark the non-const structs as const. File size before: text data bss dec hex filename 2573 288 296 3157 c55 coresight-etm-perf.o File size After adding 'const': text data bss dec hex filename 2613 224 296 3133 c3d coresight-etm-perf.o Signed-off-by: Arvind Yadav Signed-off-by: Mathieu Poirier --- drivers/hwtracing/coresight/coresight-etm-perf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index 8f546f59a3fd..ad01dfeb2d68 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -60,7 +60,7 @@ static struct attribute *etm_config_formats_attr[] = { NULL, }; -static struct attribute_group etm_pmu_format_group = { +static const struct attribute_group etm_pmu_format_group = { .name = "format", .attrs = etm_config_formats_attr, }; -- cgit v1.2.3 From ecb0ff64a0c79ab3aa3ed6de7e790807ccfc1c36 Mon Sep 17 00:00:00 2001 From: Mike Leach Date: Tue, 11 Jul 2017 12:25:49 +0100 Subject: coresight: pmu: Adds return stack option to perf coresight pmu Return stack is a programmable option on some ETM and PTM hardware. Adds the option flags to enable this from the perf event command line. Signed-off-by: Mike Leach Signed-off-by: Mathieu Poirier --- drivers/hwtracing/coresight/coresight-etm-perf.c | 2 ++ include/linux/coresight-pmu.h | 1 + tools/include/linux/coresight-pmu.h | 1 + 3 files changed, 4 insertions(+) diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index ad01dfeb2d68..8a0ad77574e7 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -53,10 +53,12 @@ static DEFINE_PER_CPU(struct coresight_device *, csdev_src); /* ETMv3.5/PTM's ETMCR is 'config' */ PMU_FORMAT_ATTR(cycacc, "config:" __stringify(ETM_OPT_CYCACC)); PMU_FORMAT_ATTR(timestamp, "config:" __stringify(ETM_OPT_TS)); +PMU_FORMAT_ATTR(retstack, "config:" __stringify(ETM_OPT_RETSTK)); static struct attribute *etm_config_formats_attr[] = { &format_attr_cycacc.attr, &format_attr_timestamp.attr, + &format_attr_retstack.attr, NULL, }; diff --git a/include/linux/coresight-pmu.h b/include/linux/coresight-pmu.h index 7d410260661b..45852c2cd096 100644 --- a/include/linux/coresight-pmu.h +++ b/include/linux/coresight-pmu.h @@ -24,6 +24,7 @@ /* ETMv3.5/PTM's ETMCR config bit */ #define ETM_OPT_CYCACC 12 #define ETM_OPT_TS 28 +#define ETM_OPT_RETSTK 29 static inline int coresight_get_trace_id(int cpu) { diff --git a/tools/include/linux/coresight-pmu.h b/tools/include/linux/coresight-pmu.h index 7d410260661b..45852c2cd096 100644 --- a/tools/include/linux/coresight-pmu.h +++ b/tools/include/linux/coresight-pmu.h @@ -24,6 +24,7 @@ /* ETMv3.5/PTM's ETMCR config bit */ #define ETM_OPT_CYCACC 12 #define ETM_OPT_TS 28 +#define ETM_OPT_RETSTK 29 static inline int coresight_get_trace_id(int cpu) { -- cgit v1.2.3 From 02f74d25fe09c92c5da7adda6c474e4947b1ac96 Mon Sep 17 00:00:00 2001 From: Mike Leach Date: Tue, 11 Jul 2017 12:25:50 +0100 Subject: coresight: ptm: Adds trace return stack option programming for PTM. Adds handling to program the return stack option into PTM hardware if specified in the perf command line. If option is not supported by the hardware then it will be ignored. This allows capture to move between core/ETM combinations that have the hardware support to those that do not. Signed-off-by: Mike Leach Signed-off-by: Mathieu Poirier --- drivers/hwtracing/coresight/coresight-etm.h | 1 + drivers/hwtracing/coresight/coresight-etm3x.c | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etm.h b/drivers/hwtracing/coresight/coresight-etm.h index ad063d7444e1..70b0a248c321 100644 --- a/drivers/hwtracing/coresight/coresight-etm.h +++ b/drivers/hwtracing/coresight/coresight-etm.h @@ -106,6 +106,7 @@ #define ETMTECR1_START_STOP BIT(25) /* ETMCCER - 0x1E8 */ #define ETMCCER_TIMESTAMP BIT(22) +#define ETMCCER_RETSTACK BIT(23) #define ETM_MODE_EXCLUDE BIT(0) #define ETM_MODE_CYCACC BIT(1) diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c index 9d8bd4e36b32..9c010eb9497f 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x.c +++ b/drivers/hwtracing/coresight/coresight-etm3x.c @@ -310,7 +310,9 @@ void etm_config_trace_mode(struct etm_config *config) config->addr_type[1] = ETM_ADDR_TYPE_RANGE; } -#define ETM3X_SUPPORTED_OPTIONS (ETMCR_CYC_ACC | ETMCR_TIMESTAMP_EN) +#define ETM3X_SUPPORTED_OPTIONS (ETMCR_CYC_ACC | \ + ETMCR_TIMESTAMP_EN | \ + ETMCR_RETURN_STACK) static int etm_parse_event_config(struct etm_drvdata *drvdata, struct perf_event *event) @@ -341,14 +343,24 @@ static int etm_parse_event_config(struct etm_drvdata *drvdata, etm_config_trace_mode(config); /* - * At this time only cycle accurate and timestamp options are - * available. + * At this time only cycle accurate, return stack and timestamp + * options are available. */ if (attr->config & ~ETM3X_SUPPORTED_OPTIONS) return -EINVAL; config->ctrl = attr->config; + /* + * Possible to have cores with PTM (supports ret stack) and ETM + * (never has ret stack) on the same SoC. So if we have a request + * for return stack that can't be honoured on this core then + * clear the bit - trace will still continue normally + */ + if ((config->ctrl & ETMCR_RETURN_STACK) && + !(drvdata->etmccer & ETMCCER_RETSTACK)) + config->ctrl &= ~ETMCR_RETURN_STACK; + return 0; } -- cgit v1.2.3 From a627ed2ecdea97f645f8c719d9b22f8b4b64198a Mon Sep 17 00:00:00 2001 From: Mike Leach Date: Tue, 11 Jul 2017 12:25:51 +0100 Subject: coresight: etm4x: Adds trace return stack option programming for ETMv4. Adds handling to program the return stack option into ETMv4 hardware if specified in the perf command line. If option is not supported by the hardware then it will be ignored. This allows capture to move between core/ETM combinations that have the hardware support to those that do not. Signed-off-by: Mike Leach Signed-off-by: Mathieu Poirier --- drivers/hwtracing/coresight/coresight-etm4x.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 532adc9dd32a..ac77b4c973d8 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -224,6 +224,10 @@ static int etm4_parse_event_config(struct etmv4_drvdata *drvdata, if (attr->config & BIT(ETM_OPT_TS)) /* bit[11], Global timestamp tracing bit */ config->cfg |= BIT(11); + /* return stack - enable if selected and supported */ + if ((attr->config & BIT(ETM_OPT_RETSTK)) && drvdata->retstack) + /* bit[12], Return stack enable bit */ + config->cfg |= BIT(12); out: return ret; -- cgit v1.2.3