diff options
author | Mathieu Poirier <mathieu.poirier@linaro.org> | 2018-09-20 15:17:58 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-09-25 14:09:18 -0400 |
commit | d43b8ec599f90c1f07b1bdd29b0c4b6306726ef2 (patch) | |
tree | e694b0c27d356d7c0428471072ff9285b44ff23a /drivers/hwtracing | |
parent | 22f429f19c4135d51e9dcaf360c0920e32aac7f9 (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.c | 62 |
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) | |||
138 | static int etb_enable(struct coresight_device *csdev, u32 mode, void *data) | 137 | static 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 | ||
178 | out: | 179 | out: |
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); |