]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - drivers/hwtracing/coresight/coresight-tmc-etr.c
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux...
[mirror_ubuntu-zesty-kernel.git] / drivers / hwtracing / coresight / coresight-tmc-etr.c
index 886ea83c68e0cf2233398f46cb00edbe188c56b6..5d312699b3b9d3a27e3039459d0c5f13097f548c 100644 (file)
@@ -86,26 +86,22 @@ 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 (local_read(&drvdata->mode) == CS_MODE_SYSFS)
+       if (drvdata->mode == CS_MODE_SYSFS)
                tmc_etr_dump_hw(drvdata);
        tmc_disable_hw(drvdata);
 
        CS_LOCK(drvdata->base);
 }
 
-static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev, u32 mode)
+static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
 {
        int ret = 0;
        bool used = false;
-       long val;
        unsigned long flags;
        void __iomem *vaddr = NULL;
        dma_addr_t paddr;
        struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
-        /* This shouldn't be happening */
-       if (WARN_ON(mode != CS_MODE_SYSFS))
-               return -EINVAL;
 
        /*
         * If we don't have a buffer release the lock and allocate memory.
@@ -134,13 +130,12 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev, u32 mode)
                goto out;
        }
 
-       val = local_xchg(&drvdata->mode, mode);
        /*
         * In sysFS mode we can have multiple writers per sink.  Since this
         * sink is already enabled no memory is needed and the HW need not be
         * touched.
         */
-       if (val == CS_MODE_SYSFS)
+       if (drvdata->mode == CS_MODE_SYSFS)
                goto out;
 
        /*
@@ -155,8 +150,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev, u32 mode)
                drvdata->buf = drvdata->vaddr;
        }
 
-       memset(drvdata->vaddr, 0, drvdata->size);
-
+       drvdata->mode = CS_MODE_SYSFS;
        tmc_etr_enable_hw(drvdata);
 out:
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
@@ -171,34 +165,29 @@ out:
        return ret;
 }
 
-static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, u32 mode)
+static int tmc_enable_etr_sink_perf(struct coresight_device *csdev)
 {
        int ret = 0;
-       long val;
        unsigned long flags;
        struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
-        /* This shouldn't be happening */
-       if (WARN_ON(mode != CS_MODE_PERF))
-               return -EINVAL;
-
        spin_lock_irqsave(&drvdata->spinlock, flags);
        if (drvdata->reading) {
                ret = -EINVAL;
                goto out;
        }
 
-       val = local_xchg(&drvdata->mode, mode);
        /*
         * In Perf mode there can be only one writer per sink.  There
         * is also no need to continue if the ETR is already operated
         * from sysFS.
         */
-       if (val != CS_MODE_DISABLED) {
+       if (drvdata->mode != CS_MODE_DISABLED) {
                ret = -EINVAL;
                goto out;
        }
 
+       drvdata->mode = CS_MODE_PERF;
        tmc_etr_enable_hw(drvdata);
 out:
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
@@ -210,9 +199,9 @@ static int tmc_enable_etr_sink(struct coresight_device *csdev, u32 mode)
 {
        switch (mode) {
        case CS_MODE_SYSFS:
-               return tmc_enable_etr_sink_sysfs(csdev, mode);
+               return tmc_enable_etr_sink_sysfs(csdev);
        case CS_MODE_PERF:
-               return tmc_enable_etr_sink_perf(csdev, mode);
+               return tmc_enable_etr_sink_perf(csdev);
        }
 
        /* We shouldn't be here */
@@ -221,7 +210,6 @@ static int tmc_enable_etr_sink(struct coresight_device *csdev, u32 mode)
 
 static void tmc_disable_etr_sink(struct coresight_device *csdev)
 {
-       long val;
        unsigned long flags;
        struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
@@ -231,10 +219,11 @@ static void tmc_disable_etr_sink(struct coresight_device *csdev)
                return;
        }
 
-       val = local_xchg(&drvdata->mode, CS_MODE_DISABLED);
        /* Disable the TMC only if it needs to */
-       if (val != CS_MODE_DISABLED)
+       if (drvdata->mode != CS_MODE_DISABLED) {
                tmc_etr_disable_hw(drvdata);
+               drvdata->mode = CS_MODE_DISABLED;
+       }
 
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
@@ -253,7 +242,6 @@ const struct coresight_ops tmc_etr_cs_ops = {
 int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
 {
        int ret = 0;
-       long val;
        unsigned long flags;
 
        /* config types are set a boot time and never change */
@@ -266,9 +254,8 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
                goto out;
        }
 
-       val = local_read(&drvdata->mode);
        /* Don't interfere if operated from Perf */
-       if (val == CS_MODE_PERF) {
+       if (drvdata->mode == CS_MODE_PERF) {
                ret = -EINVAL;
                goto out;
        }
@@ -280,7 +267,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
        }
 
        /* Disable the TMC if need be */
-       if (val == CS_MODE_SYSFS)
+       if (drvdata->mode == CS_MODE_SYSFS)
                tmc_etr_disable_hw(drvdata);
 
        drvdata->reading = true;
@@ -303,7 +290,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
        spin_lock_irqsave(&drvdata->spinlock, flags);
 
        /* RE-enable the TMC if need be */
-       if (local_read(&drvdata->mode) == CS_MODE_SYSFS) {
+       if (drvdata->mode == CS_MODE_SYSFS) {
                /*
                 * The trace run will continue with the same allocated trace
                 * buffer. The trace buffer is cleared in tmc_etr_enable_hw(),