coresight: Move mode to struct coresight_device
authorJames Clark <james.clark@arm.com>
Mon, 29 Jan 2024 15:40:35 +0000 (15:40 +0000)
committerSuzuki K Poulose <suzuki.poulose@arm.com>
Mon, 12 Feb 2024 10:21:38 +0000 (10:21 +0000)
Most devices use mode, so move the mode definition out of the individual
devices and up to the Coresight device. This will allow the core code to
also know the mode which will be useful in a later commit.

This also fixes the inconsistency of the documentation of the mode field
on the individual device types. For example ETB10 had "this ETB is being
used".

Two devices didn't require an atomic mode type, so these usages have
been converted to atomic_get() and atomic_set() only to make it compile,
but the documentation of the field in struct coresight_device explains
this type of usage.

In the future, manipulation of the mode could be completely moved out of
the individual devices and into the core code because it's almost all
duplicate code, and this change is a step towards that.

Signed-off-by: James Clark <james.clark@arm.com>
Link: https://lore.kernel.org/r/20240129154050.569566-5-james.clark@arm.com
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
14 files changed:
drivers/hwtracing/coresight/coresight-etb10.c
drivers/hwtracing/coresight/coresight-etm.h
drivers/hwtracing/coresight/coresight-etm3x-core.c
drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
drivers/hwtracing/coresight/coresight-etm4x-core.c
drivers/hwtracing/coresight/coresight-etm4x.h
drivers/hwtracing/coresight/coresight-stm.c
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
drivers/hwtracing/coresight/ultrasoc-smb.c
drivers/hwtracing/coresight/ultrasoc-smb.h
include/linux/coresight.h

index 05e21cf..145fb81 100644 (file)
@@ -76,7 +76,6 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "etb");
  * @pid:       Process ID of the process being monitored by the session
  *             that is using this component.
  * @buf:       area of memory where ETB buffer content gets sent.
- * @mode:      this ETB is being used.
  * @buffer_depth: size of @buf.
  * @trigger_cntr: amount of words to store after a trigger.
  */
@@ -89,7 +88,6 @@ struct etb_drvdata {
        local_t                 reading;
        pid_t                   pid;
        u8                      *buf;
-       u32                     mode;
        u32                     buffer_depth;
        u32                     trigger_cntr;
 };
@@ -150,17 +148,17 @@ static int etb_enable_sysfs(struct coresight_device *csdev)
        spin_lock_irqsave(&drvdata->spinlock, flags);
 
        /* Don't messup with perf sessions. */
-       if (drvdata->mode == CS_MODE_PERF) {
+       if (local_read(&csdev->mode) == CS_MODE_PERF) {
                ret = -EBUSY;
                goto out;
        }
 
-       if (drvdata->mode == CS_MODE_DISABLED) {
+       if (local_read(&csdev->mode) == CS_MODE_DISABLED) {
                ret = etb_enable_hw(drvdata);
                if (ret)
                        goto out;
 
-               drvdata->mode = CS_MODE_SYSFS;
+               local_set(&csdev->mode, CS_MODE_SYSFS);
        }
 
        atomic_inc(&csdev->refcnt);
@@ -181,7 +179,7 @@ static int etb_enable_perf(struct coresight_device *csdev, void *data)
        spin_lock_irqsave(&drvdata->spinlock, flags);
 
        /* No need to continue if the component is already in used by sysFS. */
-       if (drvdata->mode == CS_MODE_SYSFS) {
+       if (local_read(&drvdata->csdev->mode) == CS_MODE_SYSFS) {
                ret = -EBUSY;
                goto out;
        }
@@ -216,7 +214,7 @@ static int etb_enable_perf(struct coresight_device *csdev, void *data)
        if (!ret) {
                /* Associate with monitored process. */
                drvdata->pid = pid;
-               drvdata->mode = CS_MODE_PERF;
+               local_set(&drvdata->csdev->mode, CS_MODE_PERF);
                atomic_inc(&csdev->refcnt);
        }
 
@@ -362,11 +360,11 @@ static int etb_disable(struct coresight_device *csdev)
        }
 
        /* Complain if we (somehow) got out of sync */
-       WARN_ON_ONCE(drvdata->mode == CS_MODE_DISABLED);
+       WARN_ON_ONCE(local_read(&csdev->mode) == CS_MODE_DISABLED);
        etb_disable_hw(drvdata);
        /* Dissociate from monitored process. */
        drvdata->pid = -1;
-       drvdata->mode = CS_MODE_DISABLED;
+       local_set(&csdev->mode, CS_MODE_DISABLED);
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
        dev_dbg(&csdev->dev, "ETB disabled\n");
@@ -589,7 +587,7 @@ static void etb_dump(struct etb_drvdata *drvdata)
        unsigned long flags;
 
        spin_lock_irqsave(&drvdata->spinlock, flags);
-       if (drvdata->mode == CS_MODE_SYSFS) {
+       if (local_read(&drvdata->csdev->mode) == CS_MODE_SYSFS) {
                __etb_disable_hw(drvdata);
                etb_dump_hw(drvdata);
                __etb_enable_hw(drvdata);
index 9a0d08b..e02c3ea 100644 (file)
@@ -215,7 +215,6 @@ struct etm_config {
  * @port_size: port size as reported by ETMCR bit 4-6 and 21.
  * @arch:      ETM/PTM version number.
  * @use_cpu14: true if management registers need to be accessed via CP14.
- * @mode:      this tracer's mode, i.e sysFS, Perf or disabled.
  * @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.
@@ -238,7 +237,6 @@ struct etm_drvdata {
        int                             port_size;
        u8                              arch;
        bool                            use_cp14;
-       local_t                         mode;
        bool                            sticky_enable;
        bool                            boot_enable;
        bool                            os_unlock;
index 74ae269..333d0a3 100644 (file)
@@ -559,7 +559,7 @@ static int etm_enable(struct coresight_device *csdev, struct perf_event *event,
        u32 val;
        struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
-       val = local_cmpxchg(&drvdata->mode, CS_MODE_DISABLED, mode);
+       val = local_cmpxchg(&drvdata->csdev->mode, CS_MODE_DISABLED, mode);
 
        /* Someone is already using the tracer */
        if (val)
@@ -578,7 +578,7 @@ static int etm_enable(struct coresight_device *csdev, struct perf_event *event,
 
        /* The tracer didn't start */
        if (ret)
-               local_set(&drvdata->mode, CS_MODE_DISABLED);
+               local_set(&drvdata->csdev->mode, CS_MODE_DISABLED);
 
        return ret;
 }
@@ -672,14 +672,13 @@ static void etm_disable(struct coresight_device *csdev,
                        struct perf_event *event)
 {
        enum cs_mode mode;
-       struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
        /*
         * For as long as the tracer isn't disabled another entity can't
         * change its status.  As such we can read the status here without
         * fearing it will change under us.
         */
-       mode = local_read(&drvdata->mode);
+       mode = local_read(&csdev->mode);
 
        switch (mode) {
        case CS_MODE_DISABLED:
@@ -696,7 +695,7 @@ static void etm_disable(struct coresight_device *csdev,
        }
 
        if (mode)
-               local_set(&drvdata->mode, CS_MODE_DISABLED);
+               local_set(&csdev->mode, CS_MODE_DISABLED);
 }
 
 static const struct coresight_ops_source etm_source_ops = {
@@ -730,7 +729,7 @@ static int etm_starting_cpu(unsigned int cpu)
                etmdrvdata[cpu]->os_unlock = true;
        }
 
-       if (local_read(&etmdrvdata[cpu]->mode))
+       if (local_read(&etmdrvdata[cpu]->csdev->mode))
                etm_enable_hw(etmdrvdata[cpu]);
        spin_unlock(&etmdrvdata[cpu]->spinlock);
        return 0;
@@ -742,7 +741,7 @@ static int etm_dying_cpu(unsigned int cpu)
                return 0;
 
        spin_lock(&etmdrvdata[cpu]->spinlock);
-       if (local_read(&etmdrvdata[cpu]->mode))
+       if (local_read(&etmdrvdata[cpu]->csdev->mode))
                etm_disable_hw(etmdrvdata[cpu]);
        spin_unlock(&etmdrvdata[cpu]->spinlock);
        return 0;
index 2f271b7..6c8429c 100644 (file)
@@ -722,7 +722,7 @@ static ssize_t cntr_val_show(struct device *dev,
        struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
        struct etm_config *config = &drvdata->config;
 
-       if (!local_read(&drvdata->mode)) {
+       if (!local_read(&drvdata->csdev->mode)) {
                spin_lock(&drvdata->spinlock);
                for (i = 0; i < drvdata->nr_cntr; i++)
                        ret += sprintf(buf, "counter %d: %x\n",
@@ -941,7 +941,7 @@ static ssize_t seq_curr_state_show(struct device *dev,
        struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
        struct etm_config *config = &drvdata->config;
 
-       if (!local_read(&drvdata->mode)) {
+       if (!local_read(&drvdata->csdev->mode)) {
                val = config->seq_curr_state;
                goto out;
        }
index c5ea808..7ceff62 100644 (file)
@@ -841,9 +841,8 @@ static int etm4_enable(struct coresight_device *csdev, struct perf_event *event,
 {
        int ret;
        u32 val;
-       struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
-       val = local_cmpxchg(&drvdata->mode, CS_MODE_DISABLED, mode);
+       val = local_cmpxchg(&csdev->mode, CS_MODE_DISABLED, mode);
 
        /* Someone is already using the tracer */
        if (val)
@@ -862,7 +861,7 @@ static int etm4_enable(struct coresight_device *csdev, struct perf_event *event,
 
        /* The tracer didn't start */
        if (ret)
-               local_set(&drvdata->mode, CS_MODE_DISABLED);
+               local_set(&csdev->mode, CS_MODE_DISABLED);
 
        return ret;
 }
@@ -1004,14 +1003,13 @@ static void etm4_disable(struct coresight_device *csdev,
                         struct perf_event *event)
 {
        enum cs_mode mode;
-       struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
        /*
         * For as long as the tracer isn't disabled another entity can't
         * change its status.  As such we can read the status here without
         * fearing it will change under us.
         */
-       mode = local_read(&drvdata->mode);
+       mode = local_read(&csdev->mode);
 
        switch (mode) {
        case CS_MODE_DISABLED:
@@ -1025,7 +1023,7 @@ static void etm4_disable(struct coresight_device *csdev,
        }
 
        if (mode)
-               local_set(&drvdata->mode, CS_MODE_DISABLED);
+               local_set(&csdev->mode, CS_MODE_DISABLED);
 }
 
 static const struct coresight_ops_source etm4_source_ops = {
@@ -1663,7 +1661,7 @@ static int etm4_starting_cpu(unsigned int cpu)
        if (!etmdrvdata[cpu]->os_unlock)
                etm4_os_unlock(etmdrvdata[cpu]);
 
-       if (local_read(&etmdrvdata[cpu]->mode))
+       if (local_read(&etmdrvdata[cpu]->csdev->mode))
                etm4_enable_hw(etmdrvdata[cpu]);
        spin_unlock(&etmdrvdata[cpu]->spinlock);
        return 0;
@@ -1675,7 +1673,7 @@ static int etm4_dying_cpu(unsigned int cpu)
                return 0;
 
        spin_lock(&etmdrvdata[cpu]->spinlock);
-       if (local_read(&etmdrvdata[cpu]->mode))
+       if (local_read(&etmdrvdata[cpu]->csdev->mode))
                etm4_disable_hw(etmdrvdata[cpu]);
        spin_unlock(&etmdrvdata[cpu]->spinlock);
        return 0;
@@ -1833,7 +1831,7 @@ static int etm4_cpu_save(struct etmv4_drvdata *drvdata)
         * Save and restore the ETM Trace registers only if
         * the ETM is active.
         */
-       if (local_read(&drvdata->mode) && drvdata->save_state)
+       if (local_read(&drvdata->csdev->mode) && drvdata->save_state)
                ret = __etm4_cpu_save(drvdata);
        return ret;
 }
index da17b6c..9ea678b 100644 (file)
@@ -1016,7 +1016,6 @@ struct etmv4_drvdata {
        void __iomem                    *base;
        struct coresight_device         *csdev;
        spinlock_t                      spinlock;
-       local_t                         mode;
        int                             cpu;
        u8                              arch;
        u8                              nr_pe;
index 891ee64..f7fc645 100644 (file)
@@ -119,7 +119,6 @@ DEFINE_CORESIGHT_DEVLIST(stm_devs, "stm");
  * @spinlock:          only one at a time pls.
  * @chs:               the channels accociated to this STM.
  * @stm:               structure associated to the generic STM interface.
- * @mode:              this tracer's mode (enum cs_mode), i.e sysFS, or disabled.
  * @traceid:           value of the current ID for this component.
  * @write_bytes:       Maximus bytes this STM can write at a time.
  * @stmsper:           settings for register STMSPER.
@@ -136,7 +135,6 @@ struct stm_drvdata {
        spinlock_t              spinlock;
        struct channel_space    chs;
        struct stm_data         stm;
-       local_t                 mode;
        u8                      traceid;
        u32                     write_bytes;
        u32                     stmsper;
@@ -201,7 +199,7 @@ static int stm_enable(struct coresight_device *csdev, struct perf_event *event,
        if (mode != CS_MODE_SYSFS)
                return -EINVAL;
 
-       val = local_cmpxchg(&drvdata->mode, CS_MODE_DISABLED, mode);
+       val = local_cmpxchg(&csdev->mode, CS_MODE_DISABLED, mode);
 
        /* Someone is already using the tracer */
        if (val)
@@ -266,7 +264,7 @@ static void stm_disable(struct coresight_device *csdev,
         * change its status.  As such we can read the status here without
         * fearing it will change under us.
         */
-       if (local_read(&drvdata->mode) == CS_MODE_SYSFS) {
+       if (local_read(&csdev->mode) == CS_MODE_SYSFS) {
                spin_lock(&drvdata->spinlock);
                stm_disable_hw(drvdata);
                spin_unlock(&drvdata->spinlock);
@@ -276,7 +274,7 @@ static void stm_disable(struct coresight_device *csdev,
 
                pm_runtime_put(csdev->dev.parent);
 
-               local_set(&drvdata->mode, CS_MODE_DISABLED);
+               local_set(&csdev->mode, CS_MODE_DISABLED);
                dev_dbg(&csdev->dev, "STM tracing disabled\n");
        }
 }
@@ -373,7 +371,7 @@ static long stm_generic_set_options(struct stm_data *stm_data,
 {
        struct stm_drvdata *drvdata = container_of(stm_data,
                                                   struct stm_drvdata, stm);
-       if (!(drvdata && local_read(&drvdata->mode)))
+       if (!(drvdata && local_read(&drvdata->csdev->mode)))
                return -EINVAL;
 
        if (channel >= drvdata->numsp)
@@ -408,7 +406,7 @@ static ssize_t notrace stm_generic_packet(struct stm_data *stm_data,
                                                   struct stm_drvdata, stm);
        unsigned int stm_flags;
 
-       if (!(drvdata && local_read(&drvdata->mode)))
+       if (!(drvdata && local_read(&drvdata->csdev->mode)))
                return -EACCES;
 
        if (channel >= drvdata->numsp)
@@ -515,7 +513,7 @@ static ssize_t port_select_show(struct device *dev,
        struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
        unsigned long val;
 
-       if (!local_read(&drvdata->mode)) {
+       if (!local_read(&drvdata->csdev->mode)) {
                val = drvdata->stmspscr;
        } else {
                spin_lock(&drvdata->spinlock);
@@ -541,7 +539,7 @@ static ssize_t port_select_store(struct device *dev,
        spin_lock(&drvdata->spinlock);
        drvdata->stmspscr = val;
 
-       if (local_read(&drvdata->mode)) {
+       if (local_read(&drvdata->csdev->mode)) {
                CS_UNLOCK(drvdata->base);
                /* Process as per ARM's TRM recommendation */
                stmsper = readl_relaxed(drvdata->base + STMSPER);
@@ -562,7 +560,7 @@ static ssize_t port_enable_show(struct device *dev,
        struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
        unsigned long val;
 
-       if (!local_read(&drvdata->mode)) {
+       if (!local_read(&drvdata->csdev->mode)) {
                val = drvdata->stmsper;
        } else {
                spin_lock(&drvdata->spinlock);
@@ -588,7 +586,7 @@ static ssize_t port_enable_store(struct device *dev,
        spin_lock(&drvdata->spinlock);
        drvdata->stmsper = val;
 
-       if (local_read(&drvdata->mode)) {
+       if (local_read(&drvdata->csdev->mode)) {
                CS_UNLOCK(drvdata->base);
                writel_relaxed(drvdata->stmsper, drvdata->base + STMSPER);
                CS_LOCK(drvdata->base);
index 39bae35..e8b2bbe 100644 (file)
@@ -558,7 +558,7 @@ static void tmc_shutdown(struct amba_device *adev)
 
        spin_lock_irqsave(&drvdata->spinlock, flags);
 
-       if (drvdata->mode == CS_MODE_DISABLED)
+       if (local_read(&drvdata->csdev->mode) == CS_MODE_DISABLED)
                goto out;
 
        if (drvdata->config_type == TMC_CONFIG_TYPE_ETR)
index 7406b65..2a7e516 100644 (file)
@@ -89,7 +89,7 @@ static void __tmc_etb_disable_hw(struct tmc_drvdata *drvdata)
         * When operating in sysFS mode the content of the buffer needs to be
         * read before the TMC is disabled.
         */
-       if (drvdata->mode == CS_MODE_SYSFS)
+       if (local_read(&drvdata->csdev->mode) == CS_MODE_SYSFS)
                tmc_etb_dump_hw(drvdata);
        tmc_disable_hw(drvdata);
 
@@ -205,7 +205,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
         * sink is already enabled no memory is needed and the HW need not be
         * touched.
         */
-       if (drvdata->mode == CS_MODE_SYSFS) {
+       if (local_read(&csdev->mode) == CS_MODE_SYSFS) {
                atomic_inc(&csdev->refcnt);
                goto out;
        }
@@ -228,7 +228,7 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
 
        ret = tmc_etb_enable_hw(drvdata);
        if (!ret) {
-               drvdata->mode = CS_MODE_SYSFS;
+               local_set(&csdev->mode, CS_MODE_SYSFS);
                atomic_inc(&csdev->refcnt);
        } else {
                /* Free up the buffer if we failed to enable */
@@ -262,7 +262,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
                 * No need to continue if the ETB/ETF is already operated
                 * from sysFS.
                 */
-               if (drvdata->mode == CS_MODE_SYSFS) {
+               if (local_read(&csdev->mode) == CS_MODE_SYSFS) {
                        ret = -EBUSY;
                        break;
                }
@@ -292,7 +292,7 @@ static int tmc_enable_etf_sink_perf(struct coresight_device *csdev, void *data)
                if (!ret) {
                        /* Associate with monitored process. */
                        drvdata->pid = pid;
-                       drvdata->mode = CS_MODE_PERF;
+                       local_set(&csdev->mode, CS_MODE_PERF);
                        atomic_inc(&csdev->refcnt);
                }
        } while (0);
@@ -344,11 +344,11 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev)
        }
 
        /* Complain if we (somehow) got out of sync */
-       WARN_ON_ONCE(drvdata->mode == CS_MODE_DISABLED);
+       WARN_ON_ONCE(local_read(&csdev->mode) == CS_MODE_DISABLED);
        tmc_etb_disable_hw(drvdata);
        /* Dissociate from monitored process. */
        drvdata->pid = -1;
-       drvdata->mode = CS_MODE_DISABLED;
+       local_set(&csdev->mode, CS_MODE_DISABLED);
 
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
@@ -374,7 +374,7 @@ static int tmc_enable_etf_link(struct coresight_device *csdev,
        if (atomic_read(&csdev->refcnt) == 0) {
                ret = tmc_etf_enable_hw(drvdata);
                if (!ret) {
-                       drvdata->mode = CS_MODE_SYSFS;
+                       local_set(&csdev->mode, CS_MODE_SYSFS);
                        first_enable = true;
                }
        }
@@ -403,7 +403,7 @@ static void tmc_disable_etf_link(struct coresight_device *csdev,
 
        if (atomic_dec_return(&csdev->refcnt) == 0) {
                tmc_etf_disable_hw(drvdata);
-               drvdata->mode = CS_MODE_DISABLED;
+               local_set(&csdev->mode, CS_MODE_DISABLED);
                last_disable = true;
        }
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
@@ -483,7 +483,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
                return 0;
 
        /* This shouldn't happen */
-       if (WARN_ON_ONCE(drvdata->mode != CS_MODE_PERF))
+       if (WARN_ON_ONCE(local_read(&csdev->mode) != CS_MODE_PERF))
                return 0;
 
        spin_lock_irqsave(&drvdata->spinlock, flags);
@@ -629,7 +629,7 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata)
        }
 
        /* Don't interfere if operated from Perf */
-       if (drvdata->mode == CS_MODE_PERF) {
+       if (local_read(&drvdata->csdev->mode) == CS_MODE_PERF) {
                ret = -EINVAL;
                goto out;
        }
@@ -641,7 +641,7 @@ int tmc_read_prepare_etb(struct tmc_drvdata *drvdata)
        }
 
        /* Disable the TMC if need be */
-       if (drvdata->mode == CS_MODE_SYSFS) {
+       if (local_read(&drvdata->csdev->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) {
@@ -673,7 +673,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
        spin_lock_irqsave(&drvdata->spinlock, flags);
 
        /* Re-enable the TMC if need be */
-       if (drvdata->mode == CS_MODE_SYSFS) {
+       if (local_read(&drvdata->csdev->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) {
index af02ba5..3dc989d 100644 (file)
@@ -1143,7 +1143,7 @@ static void __tmc_etr_disable_hw(struct tmc_drvdata *drvdata)
         * When operating in sysFS mode the content of the buffer needs to be
         * read before the TMC is disabled.
         */
-       if (drvdata->mode == CS_MODE_SYSFS)
+       if (local_read(&drvdata->csdev->mode) == CS_MODE_SYSFS)
                tmc_etr_sync_sysfs_buf(drvdata);
 
        tmc_disable_hw(drvdata);
@@ -1189,7 +1189,7 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev)
                spin_lock_irqsave(&drvdata->spinlock, flags);
        }
 
-       if (drvdata->reading || drvdata->mode == CS_MODE_PERF) {
+       if (drvdata->reading || local_read(&csdev->mode) == CS_MODE_PERF) {
                ret = -EBUSY;
                goto out;
        }
@@ -1230,14 +1230,14 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
         * sink is already enabled no memory is needed and the HW need not be
         * touched, even if the buffer size has changed.
         */
-       if (drvdata->mode == CS_MODE_SYSFS) {
+       if (local_read(&csdev->mode) == CS_MODE_SYSFS) {
                atomic_inc(&csdev->refcnt);
                goto out;
        }
 
        ret = tmc_etr_enable_hw(drvdata, sysfs_buf);
        if (!ret) {
-               drvdata->mode = CS_MODE_SYSFS;
+               local_set(&csdev->mode, CS_MODE_SYSFS);
                atomic_inc(&csdev->refcnt);
        }
 
@@ -1652,7 +1652,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
 
        spin_lock_irqsave(&drvdata->spinlock, flags);
         /* Don't use this sink if it is already claimed by sysFS */
-       if (drvdata->mode == CS_MODE_SYSFS) {
+       if (local_read(&csdev->mode) == CS_MODE_SYSFS) {
                rc = -EBUSY;
                goto unlock_out;
        }
@@ -1684,7 +1684,7 @@ static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, void *data)
        if (!rc) {
                /* Associate with monitored process. */
                drvdata->pid = pid;
-               drvdata->mode = CS_MODE_PERF;
+               local_set(&csdev->mode, CS_MODE_PERF);
                drvdata->perf_buf = etr_perf->etr_buf;
                atomic_inc(&csdev->refcnt);
        }
@@ -1725,11 +1725,11 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev)
        }
 
        /* Complain if we (somehow) got out of sync */
-       WARN_ON_ONCE(drvdata->mode == CS_MODE_DISABLED);
+       WARN_ON_ONCE(local_read(&csdev->mode) == CS_MODE_DISABLED);
        tmc_etr_disable_hw(drvdata);
        /* Dissociate from monitored process. */
        drvdata->pid = -1;
-       drvdata->mode = CS_MODE_DISABLED;
+       local_set(&csdev->mode, CS_MODE_DISABLED);
        /* Reset perf specific data */
        drvdata->perf_buf = NULL;
 
@@ -1777,7 +1777,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
        }
 
        /* Disable the TMC if we are trying to read from a running session. */
-       if (drvdata->mode == CS_MODE_SYSFS)
+       if (local_read(&drvdata->csdev->mode) == CS_MODE_SYSFS)
                __tmc_etr_disable_hw(drvdata);
 
        drvdata->reading = true;
@@ -1799,7 +1799,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
        spin_lock_irqsave(&drvdata->spinlock, flags);
 
        /* RE-enable the TMC if need be */
-       if (drvdata->mode == CS_MODE_SYSFS) {
+       if (local_read(&drvdata->csdev->mode) == CS_MODE_SYSFS) {
                /*
                 * The trace run will continue with the same allocated trace
                 * buffer. Since the tracer is still enabled drvdata::buf can't
index 8dcb426..cef979c 100644 (file)
@@ -178,7 +178,6 @@ struct etr_buf {
  * @size:      trace buffer size for this TMC (common for all modes).
  * @max_burst_size: The maximum burst size that can be initiated by
  *             TMC-ETR on AXI bus.
- * @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.
  * @trigger_cntr: amount of words to store after a trigger.
@@ -203,7 +202,6 @@ struct tmc_drvdata {
        u32                     len;
        u32                     size;
        u32                     max_burst_size;
-       u32                     mode;
        enum tmc_config_type    config_type;
        enum tmc_mem_intf_width memwidth;
        u32                     trigger_cntr;
index f0b6806..bef6339 100644 (file)
@@ -207,11 +207,11 @@ static void smb_enable_sysfs(struct coresight_device *csdev)
 {
        struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
 
-       if (drvdata->mode != CS_MODE_DISABLED)
+       if (local_read(&csdev->mode) != CS_MODE_DISABLED)
                return;
 
        smb_enable_hw(drvdata);
-       drvdata->mode = CS_MODE_SYSFS;
+       local_set(&csdev->mode, CS_MODE_SYSFS);
 }
 
 static int smb_enable_perf(struct coresight_device *csdev, void *data)
@@ -234,7 +234,7 @@ static int smb_enable_perf(struct coresight_device *csdev, void *data)
        if (drvdata->pid == -1) {
                smb_enable_hw(drvdata);
                drvdata->pid = pid;
-               drvdata->mode = CS_MODE_PERF;
+               local_set(&csdev->mode, CS_MODE_PERF);
        }
 
        return 0;
@@ -253,7 +253,8 @@ static int smb_enable(struct coresight_device *csdev, enum cs_mode mode,
                return -EBUSY;
 
        /* Do nothing, the SMB is already enabled as other mode */
-       if (drvdata->mode != CS_MODE_DISABLED && drvdata->mode != mode)
+       if (local_read(&csdev->mode) != CS_MODE_DISABLED &&
+           local_read(&csdev->mode) != mode)
                return -EBUSY;
 
        switch (mode) {
@@ -289,13 +290,13 @@ static int smb_disable(struct coresight_device *csdev)
                return -EBUSY;
 
        /* Complain if we (somehow) got out of sync */
-       WARN_ON_ONCE(drvdata->mode == CS_MODE_DISABLED);
+       WARN_ON_ONCE(local_read(&csdev->mode) == CS_MODE_DISABLED);
 
        smb_disable_hw(drvdata);
 
        /* Dissociate from the target process. */
        drvdata->pid = -1;
-       drvdata->mode = CS_MODE_DISABLED;
+       local_set(&csdev->mode, CS_MODE_DISABLED);
        dev_dbg(&csdev->dev, "Ultrasoc SMB disabled\n");
 
        return 0;
index 82a44c1..a91d39c 100644 (file)
@@ -109,7 +109,6 @@ struct smb_data_buffer {
  * @reading:   Synchronise user space access to SMB buffer.
  * @pid:       Process ID of the process being monitored by the
  *             session that is using this component.
- * @mode:      How this SMB is being used, perf mode or sysfs mode.
  */
 struct smb_drv_data {
        void __iomem *base;
@@ -119,7 +118,6 @@ struct smb_drv_data {
        spinlock_t spinlock;
        bool reading;
        pid_t pid;
-       enum cs_mode mode;
 };
 
 #endif
index 516ab45..01f6786 100644 (file)
@@ -226,6 +226,11 @@ struct coresight_sysfs_link {
  *             by @coresight_ops.
  * @access:    Device i/o access abstraction for this device.
  * @dev:       The device entity associated to this component.
+ * @mode:      This tracer's mode, i.e sysFS, Perf or disabled. This is
+ *             actually an 'enum cs_mode', but is stored in an atomic type.
+ *             This is always accessed through local_read() and local_set(),
+ *             but wherever it's done from within the Coresight device's lock,
+ *             a non-atomic read would also work.
  * @refcnt:    keep track of what is in use.
  * @orphan:    true if the component has connections that haven't been linked.
  * @enable:    'true' if component is currently part of an active path.
@@ -252,6 +257,7 @@ struct coresight_device {
        const struct coresight_ops *ops;
        struct csdev_access access;
        struct device dev;
+       local_t mode;
        atomic_t refcnt;
        bool orphan;
        bool enable;