]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
coresight: tmc: Stop trace capture on FlIn
authorLinu Cherian <lcherian@marvell.com>
Wed, 12 Feb 2025 11:49:16 +0000 (17:19 +0530)
committerSuzuki K Poulose <suzuki.poulose@arm.com>
Fri, 21 Feb 2025 16:17:30 +0000 (16:17 +0000)
Configure TMC ETR and ETF to flush and stop trace capture
on FlIn event based on sysfs attribute,
/sys/bus/coresight/devices/tmc_etXn/stop_on_flush.

Signed-off-by: Linu Cherian <lcherian@marvell.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20250212114918.548431-7-lcherian@marvell.com
drivers/hwtracing/coresight/coresight-tmc-core.c
drivers/hwtracing/coresight/coresight-tmc-etf.c
drivers/hwtracing/coresight/coresight-tmc-etr.c
drivers/hwtracing/coresight/coresight-tmc.h

index 045d3760675028053d34d1ae14ae9c75b3bf6e7e..d5122e12daa7e7652efb7d2ca141bdc8354f4ebc 100644 (file)
@@ -532,9 +532,40 @@ static ssize_t buffer_size_store(struct device *dev,
 
 static DEVICE_ATTR_RW(buffer_size);
 
+static ssize_t stop_on_flush_show(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+       return sprintf(buf, "%#x\n", drvdata->stop_on_flush);
+}
+
+static ssize_t stop_on_flush_store(struct device *dev,
+                                struct device_attribute *attr,
+                                const char *buf, size_t size)
+{
+       int ret;
+       u8 val;
+       struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+       ret = kstrtou8(buf, 0, &val);
+       if (ret)
+               return ret;
+       if (val)
+               drvdata->stop_on_flush = true;
+       else
+               drvdata->stop_on_flush = false;
+
+       return size;
+}
+
+static DEVICE_ATTR_RW(stop_on_flush);
+
+
 static struct attribute *coresight_tmc_attrs[] = {
        &dev_attr_trigger_cntr.attr,
        &dev_attr_buffer_size.attr,
+       &dev_attr_stop_on_flush.attr,
        NULL,
 };
 
index 0f9155a10ac28688e1f3a86887816d2e1ace5a97..bdc3a7e9ba06b3caeda67124b986b262aec7f1a7 100644 (file)
@@ -19,6 +19,7 @@ static int tmc_set_etf_buffer(struct coresight_device *csdev,
 static int __tmc_etb_enable_hw(struct tmc_drvdata *drvdata)
 {
        int rc = 0;
+       u32 ffcr;
 
        CS_UNLOCK(drvdata->base);
 
@@ -32,10 +33,12 @@ static int __tmc_etb_enable_hw(struct tmc_drvdata *drvdata)
        }
 
        writel_relaxed(TMC_MODE_CIRCULAR_BUFFER, drvdata->base + TMC_MODE);
-       writel_relaxed(TMC_FFCR_EN_FMT | TMC_FFCR_EN_TI |
-                      TMC_FFCR_FON_FLIN | TMC_FFCR_FON_TRIG_EVT |
-                      TMC_FFCR_TRIGON_TRIGIN,
-                      drvdata->base + TMC_FFCR);
+
+       ffcr = TMC_FFCR_EN_FMT | TMC_FFCR_EN_TI | TMC_FFCR_FON_FLIN |
+               TMC_FFCR_FON_TRIG_EVT | TMC_FFCR_TRIGON_TRIGIN;
+       if (drvdata->stop_on_flush)
+               ffcr |= TMC_FFCR_STOP_ON_FLUSH;
+       writel_relaxed(ffcr, drvdata->base + TMC_FFCR);
 
        writel_relaxed(drvdata->trigger_cntr, drvdata->base + TMC_TRG);
        tmc_enable_hw(drvdata);
@@ -225,7 +228,6 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
                used = true;
                drvdata->buf = buf;
        }
-
        ret = tmc_etb_enable_hw(drvdata);
        if (!ret) {
                coresight_set_mode(csdev, CS_MODE_SYSFS);
index c92556e1b4dbbcaf66adade740c79433fb5b41de..eda7cdad0e2bd447574473759596e199cac8ba99 100644 (file)
@@ -1060,7 +1060,7 @@ static void tmc_sync_etr_buf(struct tmc_drvdata *drvdata)
 
 static int __tmc_etr_enable_hw(struct tmc_drvdata *drvdata)
 {
-       u32 axictl, sts;
+       u32 axictl, sts, ffcr;
        struct etr_buf *etr_buf = drvdata->etr_buf;
        int rc = 0;
 
@@ -1106,10 +1106,12 @@ static int __tmc_etr_enable_hw(struct tmc_drvdata *drvdata)
                writel_relaxed(sts, drvdata->base + TMC_STS);
        }
 
-       writel_relaxed(TMC_FFCR_EN_FMT | TMC_FFCR_EN_TI |
-                      TMC_FFCR_FON_FLIN | TMC_FFCR_FON_TRIG_EVT |
-                      TMC_FFCR_TRIGON_TRIGIN,
-                      drvdata->base + TMC_FFCR);
+       ffcr = TMC_FFCR_EN_FMT | TMC_FFCR_EN_TI | TMC_FFCR_FON_FLIN |
+               TMC_FFCR_FON_TRIG_EVT | TMC_FFCR_TRIGON_TRIGIN;
+       if (drvdata->stop_on_flush)
+               ffcr |= TMC_FFCR_STOP_ON_FLUSH;
+       writel_relaxed(ffcr, drvdata->base + TMC_FFCR);
+
        writel_relaxed(drvdata->trigger_cntr, drvdata->base + TMC_TRG);
        tmc_enable_hw(drvdata);
 
index 3e2744af7e15a69600103656ec3c7d06ecfc049e..b48bc9a01cc026ed36f2d3c01bbd191c119aead8 100644 (file)
@@ -220,6 +220,7 @@ struct tmc_resrv_buf {
  * @pid:       Process ID of the process that owns the session that is using
  *             this component. For example this would be the pid of the Perf
  *             process.
+ * @stop_on_flush: Stop on flush trigger user configuration.
  * @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.
@@ -251,6 +252,7 @@ struct tmc_drvdata {
        spinlock_t              spinlock;
        pid_t                   pid;
        bool                    reading;
+       bool                    stop_on_flush;
        union {
                char            *buf;           /* TMC ETB */
                struct etr_buf  *etr_buf;       /* TMC ETR */