aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwtracing
diff options
context:
space:
mode:
authorMathieu Poirier <mathieu.poirier@linaro.org>2018-09-20 15:17:58 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-09-25 14:09:18 -0400
commitd43b8ec599f90c1f07b1bdd29b0c4b6306726ef2 (patch)
treee694b0c27d356d7c0428471072ff9285b44ff23a /drivers/hwtracing
parent22f429f19c4135d51e9dcaf360c0920e32aac7f9 (diff)
coresight: etb10: Refactor etb_drvdata::mode handling
This patch moves the etb_drvdata::mode from a locat_t to a simple u32, as it is for the ETF and ETR drivers. This streamlines the code and adds commonality with the other drivers when dealing with similar operations. Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hwtracing')
-rw-r--r--drivers/hwtracing/coresight/coresight-etb10.c62
1 files changed, 34 insertions, 28 deletions
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index 9fd77fdc1244..69287163ce4e 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -5,7 +5,6 @@
5 * Description: CoreSight Embedded Trace Buffer driver 5 * Description: CoreSight Embedded Trace Buffer driver
6 */ 6 */
7 7
8#include <asm/local.h>
9#include <linux/kernel.h> 8#include <linux/kernel.h>
10#include <linux/init.h> 9#include <linux/init.h>
11#include <linux/types.h> 10#include <linux/types.h>
@@ -72,8 +71,8 @@
72 * @miscdev: specifics to handle "/dev/xyz.etb" entry. 71 * @miscdev: specifics to handle "/dev/xyz.etb" entry.
73 * @spinlock: only one at a time pls. 72 * @spinlock: only one at a time pls.
74 * @reading: synchronise user space access to etb buffer. 73 * @reading: synchronise user space access to etb buffer.
75 * @mode: this ETB is being used.
76 * @buf: area of memory where ETB buffer content gets sent. 74 * @buf: area of memory where ETB buffer content gets sent.
75 * @mode: this ETB is being used.
77 * @buffer_depth: size of @buf. 76 * @buffer_depth: size of @buf.
78 * @trigger_cntr: amount of words to store after a trigger. 77 * @trigger_cntr: amount of words to store after a trigger.
79 */ 78 */
@@ -85,8 +84,8 @@ struct etb_drvdata {
85 struct miscdevice miscdev; 84 struct miscdevice miscdev;
86 spinlock_t spinlock; 85 spinlock_t spinlock;
87 local_t reading; 86 local_t reading;
88 local_t mode;
89 u8 *buf; 87 u8 *buf;
88 u32 mode;
90 u32 buffer_depth; 89 u32 buffer_depth;
91 u32 trigger_cntr; 90 u32 trigger_cntr;
92}; 91};
@@ -138,44 +137,48 @@ static void etb_enable_hw(struct etb_drvdata *drvdata)
138static int etb_enable(struct coresight_device *csdev, u32 mode, void *data) 137static int etb_enable(struct coresight_device *csdev, u32 mode, void *data)
139{ 138{
140 int ret = 0; 139 int ret = 0;
141 u32 val;
142 unsigned long flags; 140 unsigned long flags;
143 struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 141 struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
144 142
145 /* 143 spin_lock_irqsave(&drvdata->spinlock, flags);
146 * We don't have an internal state to clean up if we fail to setup
147 * the perf buffer. So we can perform the step before we turn the
148 * ETB on and leave without cleaning up.
149 */
150 if (mode == CS_MODE_PERF) {
151 ret = etb_set_buffer(csdev, (struct perf_output_handle *)data);
152 if (ret)
153 goto out;
154 }
155 144
156 val = local_cmpxchg(&drvdata->mode,
157 CS_MODE_DISABLED, mode);
158 /* 145 /*
159 * When accessing from Perf, a HW buffer can be handled 146 * When accessing from Perf, a HW buffer can be handled
160 * by a single trace entity. In sysFS mode many tracers 147 * by a single trace entity. In sysFS mode many tracers
161 * can be logging to the same HW buffer. 148 * can be logging to the same HW buffer.
162 */ 149 */
163 if (val == CS_MODE_PERF) 150 if (drvdata->mode == CS_MODE_PERF) {
164 return -EBUSY; 151 ret = -EBUSY;
152 goto out;
153 }
165 154
166 /* Don't let perf disturb sysFS sessions */ 155 /* Don't let perf disturb sysFS sessions */
167 if (val == CS_MODE_SYSFS && mode == CS_MODE_PERF) 156 if (drvdata->mode == CS_MODE_SYSFS && mode == CS_MODE_PERF) {
168 return -EBUSY; 157 ret = -EBUSY;
158 goto out;
159 }
169 160
170 /* Nothing to do, the tracer is already enabled. */ 161 /* Nothing to do, the tracer is already enabled. */
171 if (val == CS_MODE_SYSFS) 162 if (drvdata->mode == CS_MODE_SYSFS && mode == CS_MODE_SYSFS)
172 goto out; 163 goto out;
173 164
174 spin_lock_irqsave(&drvdata->spinlock, flags); 165 /*
166 * We don't have an internal state to clean up if we fail to setup
167 * the perf buffer. So we can perform the step before we turn the
168 * ETB on and leave without cleaning up.
169 */
170 if (mode == CS_MODE_PERF) {
171 ret = etb_set_buffer(csdev, (struct perf_output_handle *)data);
172 if (ret)
173 goto out;
174 }
175
176 drvdata->mode = mode;
175 etb_enable_hw(drvdata); 177 etb_enable_hw(drvdata);
176 spin_unlock_irqrestore(&drvdata->spinlock, flags);
177 178
178out: 179out:
180 spin_unlock_irqrestore(&drvdata->spinlock, flags);
181
179 if (!ret) 182 if (!ret)
180 dev_dbg(drvdata->dev, "ETB enabled\n"); 183 dev_dbg(drvdata->dev, "ETB enabled\n");
181 return ret; 184 return ret;
@@ -277,11 +280,14 @@ static void etb_disable(struct coresight_device *csdev)
277 unsigned long flags; 280 unsigned long flags;
278 281
279 spin_lock_irqsave(&drvdata->spinlock, flags); 282 spin_lock_irqsave(&drvdata->spinlock, flags);
280 etb_disable_hw(drvdata);
281 etb_dump_hw(drvdata);
282 spin_unlock_irqrestore(&drvdata->spinlock, flags);
283 283
284 local_set(&drvdata->mode, CS_MODE_DISABLED); 284 /* Disable the ETB only if it needs to */
285 if (drvdata->mode != CS_MODE_DISABLED) {
286 etb_disable_hw(drvdata);
287 etb_dump_hw(drvdata);
288 drvdata->mode = CS_MODE_DISABLED;
289 }
290 spin_unlock_irqrestore(&drvdata->spinlock, flags);
285 291
286 dev_dbg(drvdata->dev, "ETB disabled\n"); 292 dev_dbg(drvdata->dev, "ETB disabled\n");
287} 293}
@@ -488,7 +494,7 @@ static void etb_dump(struct etb_drvdata *drvdata)
488 unsigned long flags; 494 unsigned long flags;
489 495
490 spin_lock_irqsave(&drvdata->spinlock, flags); 496 spin_lock_irqsave(&drvdata->spinlock, flags);
491 if (local_read(&drvdata->mode) == CS_MODE_SYSFS) { 497 if (drvdata->mode == CS_MODE_SYSFS) {
492 etb_disable_hw(drvdata); 498 etb_disable_hw(drvdata);
493 etb_dump_hw(drvdata); 499 etb_dump_hw(drvdata);
494 etb_enable_hw(drvdata); 500 etb_enable_hw(drvdata);