summaryrefslogtreecommitdiff
path: root/drivers/hwtracing/coresight/coresight-etb10.c
diff options
context:
space:
mode:
authorMathieu Poirier <mathieu.poirier@linaro.org>2019-04-25 13:52:58 -0600
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-04-25 22:00:17 +0200
commit0916447c8728ed1ffa2bf9feee220f01d802b37e (patch)
treea034eb12de23f6006a7e7a080b92a5efd955b6c5 /drivers/hwtracing/coresight/coresight-etb10.c
parent12dfc9e022aa4e8768d127416bf841c169f8c57e (diff)
coresight: Properly address concurrency in sink::update() functions
When operating in CPU-wide trace scenarios and working with an N:1 source/sink HW topology, update() functions need to be made atomic in order to avoid racing with start and stop operations. Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Tested-by: Leo Yan <leo.yan@linaro.org> Tested-by: Robert Walker <robert.walker@arm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hwtracing/coresight/coresight-etb10.c')
-rw-r--r--drivers/hwtracing/coresight/coresight-etb10.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index 6b73bc2e0dbd..00d664c6a401 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -405,7 +405,7 @@ static unsigned long etb_update_buffer(struct coresight_device *csdev,
const u32 *barrier;
u32 read_ptr, write_ptr, capacity;
u32 status, read_data;
- unsigned long offset, to_read;
+ unsigned long offset, to_read, flags;
struct cs_buffers *buf = sink_config;
struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
@@ -414,6 +414,7 @@ static unsigned long etb_update_buffer(struct coresight_device *csdev,
capacity = drvdata->buffer_depth * ETB_FRAME_SIZE_WORDS;
+ spin_lock_irqsave(&drvdata->spinlock, flags);
__etb_disable_hw(drvdata);
CS_UNLOCK(drvdata->base);
@@ -524,6 +525,7 @@ static unsigned long etb_update_buffer(struct coresight_device *csdev,
}
__etb_enable_hw(drvdata);
CS_LOCK(drvdata->base);
+ spin_unlock_irqrestore(&drvdata->spinlock, flags);
return to_read;
}