blob: e9b071953f8099f832ac98f11acd563019dd6a45 [file] [log] [blame]
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001/*
2 * Copyright(C) 2015 Linaro Limited. All rights reserved.
3 * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <linux/pm_runtime.h>
19#include <linux/sysfs.h>
20#include "coresight-etm.h"
Mathieu Poirier2b7adc42016-08-25 15:19:11 -060021#include "coresight-priv.h"
Mathieu Poirierc04148e2016-02-17 17:51:49 -070022
23static ssize_t nr_addr_cmp_show(struct device *dev,
24 struct device_attribute *attr, char *buf)
25{
26 unsigned long val;
27 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
28
29 val = drvdata->nr_addr_cmp;
30 return sprintf(buf, "%#lx\n", val);
31}
32static DEVICE_ATTR_RO(nr_addr_cmp);
33
34static ssize_t nr_cntr_show(struct device *dev,
35 struct device_attribute *attr, char *buf)
36{ unsigned long val;
37 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
38
39 val = drvdata->nr_cntr;
40 return sprintf(buf, "%#lx\n", val);
41}
42static DEVICE_ATTR_RO(nr_cntr);
43
44static ssize_t nr_ctxid_cmp_show(struct device *dev,
45 struct device_attribute *attr, char *buf)
46{
47 unsigned long val;
48 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
49
50 val = drvdata->nr_ctxid_cmp;
51 return sprintf(buf, "%#lx\n", val);
52}
53static DEVICE_ATTR_RO(nr_ctxid_cmp);
54
55static ssize_t etmsr_show(struct device *dev,
56 struct device_attribute *attr, char *buf)
57{
58 unsigned long flags, val;
59 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
60
61 pm_runtime_get_sync(drvdata->dev);
62 spin_lock_irqsave(&drvdata->spinlock, flags);
63 CS_UNLOCK(drvdata->base);
64
65 val = etm_readl(drvdata, ETMSR);
66
67 CS_LOCK(drvdata->base);
68 spin_unlock_irqrestore(&drvdata->spinlock, flags);
69 pm_runtime_put(drvdata->dev);
70
71 return sprintf(buf, "%#lx\n", val);
72}
73static DEVICE_ATTR_RO(etmsr);
74
75static ssize_t reset_store(struct device *dev,
76 struct device_attribute *attr,
77 const char *buf, size_t size)
78{
79 int i, ret;
80 unsigned long val;
81 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -070082 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -070083
84 ret = kstrtoul(buf, 16, &val);
85 if (ret)
86 return ret;
87
88 if (val) {
89 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -070090 memset(config, 0, sizeof(struct etm_config));
91 config->mode = ETM_MODE_EXCLUDE;
92 config->trigger_event = ETM_DEFAULT_EVENT_VAL;
Mathieu Poirierc04148e2016-02-17 17:51:49 -070093 for (i = 0; i < drvdata->nr_addr_cmp; i++) {
Mathieu Poirier1925a472016-02-17 17:51:51 -070094 config->addr_type[i] = ETM_ADDR_TYPE_NONE;
Mathieu Poirierc04148e2016-02-17 17:51:49 -070095 }
Mathieu Poirierc04148e2016-02-17 17:51:49 -070096
Mathieu Poirier1925a472016-02-17 17:51:51 -070097 etm_set_default(config);
Mathieu Poirierc04148e2016-02-17 17:51:49 -070098 spin_unlock(&drvdata->spinlock);
99 }
100
101 return size;
102}
103static DEVICE_ATTR_WO(reset);
104
105static ssize_t mode_show(struct device *dev,
106 struct device_attribute *attr, char *buf)
107{
108 unsigned long val;
109 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700110 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700111
Mathieu Poirier1925a472016-02-17 17:51:51 -0700112 val = config->mode;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700113 return sprintf(buf, "%#lx\n", val);
114}
115
116static ssize_t mode_store(struct device *dev,
117 struct device_attribute *attr,
118 const char *buf, size_t size)
119{
120 int ret;
121 unsigned long val;
122 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700123 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700124
125 ret = kstrtoul(buf, 16, &val);
126 if (ret)
127 return ret;
128
129 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700130 config->mode = val & ETM_MODE_ALL;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700131
Mathieu Poirier1925a472016-02-17 17:51:51 -0700132 if (config->mode & ETM_MODE_EXCLUDE)
133 config->enable_ctrl1 |= ETMTECR1_INC_EXC;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700134 else
Mathieu Poirier1925a472016-02-17 17:51:51 -0700135 config->enable_ctrl1 &= ~ETMTECR1_INC_EXC;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700136
Mathieu Poirier1925a472016-02-17 17:51:51 -0700137 if (config->mode & ETM_MODE_CYCACC)
138 config->ctrl |= ETMCR_CYC_ACC;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700139 else
Mathieu Poirier1925a472016-02-17 17:51:51 -0700140 config->ctrl &= ~ETMCR_CYC_ACC;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700141
Mathieu Poirier1925a472016-02-17 17:51:51 -0700142 if (config->mode & ETM_MODE_STALL) {
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700143 if (!(drvdata->etmccr & ETMCCR_FIFOFULL)) {
144 dev_warn(drvdata->dev, "stall mode not supported\n");
145 ret = -EINVAL;
146 goto err_unlock;
147 }
Mathieu Poirier1925a472016-02-17 17:51:51 -0700148 config->ctrl |= ETMCR_STALL_MODE;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700149 } else
Mathieu Poirier1925a472016-02-17 17:51:51 -0700150 config->ctrl &= ~ETMCR_STALL_MODE;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700151
Mathieu Poirier1925a472016-02-17 17:51:51 -0700152 if (config->mode & ETM_MODE_TIMESTAMP) {
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700153 if (!(drvdata->etmccer & ETMCCER_TIMESTAMP)) {
154 dev_warn(drvdata->dev, "timestamp not supported\n");
155 ret = -EINVAL;
156 goto err_unlock;
157 }
Mathieu Poirier1925a472016-02-17 17:51:51 -0700158 config->ctrl |= ETMCR_TIMESTAMP_EN;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700159 } else
Mathieu Poirier1925a472016-02-17 17:51:51 -0700160 config->ctrl &= ~ETMCR_TIMESTAMP_EN;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700161
Mathieu Poirier1925a472016-02-17 17:51:51 -0700162 if (config->mode & ETM_MODE_CTXID)
163 config->ctrl |= ETMCR_CTXID_SIZE;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700164 else
Mathieu Poirier1925a472016-02-17 17:51:51 -0700165 config->ctrl &= ~ETMCR_CTXID_SIZE;
Mathieu Poirier21271542016-02-17 17:51:56 -0700166
167 if (config->mode & (ETM_MODE_EXCL_KERN | ETM_MODE_EXCL_USER))
168 etm_config_trace_mode(config);
169
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700170 spin_unlock(&drvdata->spinlock);
171
172 return size;
173
174err_unlock:
175 spin_unlock(&drvdata->spinlock);
176 return ret;
177}
178static DEVICE_ATTR_RW(mode);
179
180static ssize_t trigger_event_show(struct device *dev,
181 struct device_attribute *attr, char *buf)
182{
183 unsigned long val;
184 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700185 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700186
Mathieu Poirier1925a472016-02-17 17:51:51 -0700187 val = config->trigger_event;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700188 return sprintf(buf, "%#lx\n", val);
189}
190
191static ssize_t trigger_event_store(struct device *dev,
192 struct device_attribute *attr,
193 const char *buf, size_t size)
194{
195 int ret;
196 unsigned long val;
197 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700198 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700199
200 ret = kstrtoul(buf, 16, &val);
201 if (ret)
202 return ret;
203
Mathieu Poirier1925a472016-02-17 17:51:51 -0700204 config->trigger_event = val & ETM_EVENT_MASK;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700205
206 return size;
207}
208static DEVICE_ATTR_RW(trigger_event);
209
210static ssize_t enable_event_show(struct device *dev,
211 struct device_attribute *attr, char *buf)
212{
213 unsigned long val;
214 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700215 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700216
Mathieu Poirier1925a472016-02-17 17:51:51 -0700217 val = config->enable_event;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700218 return sprintf(buf, "%#lx\n", val);
219}
220
221static ssize_t enable_event_store(struct device *dev,
222 struct device_attribute *attr,
223 const char *buf, size_t size)
224{
225 int ret;
226 unsigned long val;
227 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700228 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700229
230 ret = kstrtoul(buf, 16, &val);
231 if (ret)
232 return ret;
233
Mathieu Poirier1925a472016-02-17 17:51:51 -0700234 config->enable_event = val & ETM_EVENT_MASK;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700235
236 return size;
237}
238static DEVICE_ATTR_RW(enable_event);
239
240static ssize_t fifofull_level_show(struct device *dev,
241 struct device_attribute *attr, char *buf)
242{
243 unsigned long val;
244 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700245 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700246
Mathieu Poirier1925a472016-02-17 17:51:51 -0700247 val = config->fifofull_level;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700248 return sprintf(buf, "%#lx\n", val);
249}
250
251static ssize_t fifofull_level_store(struct device *dev,
252 struct device_attribute *attr,
253 const char *buf, size_t size)
254{
255 int ret;
256 unsigned long val;
257 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700258 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700259
260 ret = kstrtoul(buf, 16, &val);
261 if (ret)
262 return ret;
263
Mathieu Poirier1925a472016-02-17 17:51:51 -0700264 config->fifofull_level = val;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700265
266 return size;
267}
268static DEVICE_ATTR_RW(fifofull_level);
269
270static ssize_t addr_idx_show(struct device *dev,
271 struct device_attribute *attr, char *buf)
272{
273 unsigned long val;
274 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700275 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700276
Mathieu Poirier1925a472016-02-17 17:51:51 -0700277 val = config->addr_idx;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700278 return sprintf(buf, "%#lx\n", val);
279}
280
281static ssize_t addr_idx_store(struct device *dev,
282 struct device_attribute *attr,
283 const char *buf, size_t size)
284{
285 int ret;
286 unsigned long val;
287 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700288 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700289
290 ret = kstrtoul(buf, 16, &val);
291 if (ret)
292 return ret;
293
294 if (val >= drvdata->nr_addr_cmp)
295 return -EINVAL;
296
297 /*
298 * Use spinlock to ensure index doesn't change while it gets
299 * dereferenced multiple times within a spinlock block elsewhere.
300 */
301 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700302 config->addr_idx = val;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700303 spin_unlock(&drvdata->spinlock);
304
305 return size;
306}
307static DEVICE_ATTR_RW(addr_idx);
308
309static ssize_t addr_single_show(struct device *dev,
310 struct device_attribute *attr, char *buf)
311{
312 u8 idx;
313 unsigned long val;
314 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700315 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700316
317 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700318 idx = config->addr_idx;
319 if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
320 config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700321 spin_unlock(&drvdata->spinlock);
322 return -EINVAL;
323 }
324
Mathieu Poirier1925a472016-02-17 17:51:51 -0700325 val = config->addr_val[idx];
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700326 spin_unlock(&drvdata->spinlock);
327
328 return sprintf(buf, "%#lx\n", val);
329}
330
331static ssize_t addr_single_store(struct device *dev,
332 struct device_attribute *attr,
333 const char *buf, size_t size)
334{
335 u8 idx;
336 int ret;
337 unsigned long val;
338 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700339 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700340
341 ret = kstrtoul(buf, 16, &val);
342 if (ret)
343 return ret;
344
345 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700346 idx = config->addr_idx;
347 if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
348 config->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700349 spin_unlock(&drvdata->spinlock);
350 return -EINVAL;
351 }
352
Mathieu Poirier1925a472016-02-17 17:51:51 -0700353 config->addr_val[idx] = val;
354 config->addr_type[idx] = ETM_ADDR_TYPE_SINGLE;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700355 spin_unlock(&drvdata->spinlock);
356
357 return size;
358}
359static DEVICE_ATTR_RW(addr_single);
360
361static ssize_t addr_range_show(struct device *dev,
362 struct device_attribute *attr, char *buf)
363{
364 u8 idx;
365 unsigned long val1, val2;
366 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700367 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700368
369 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700370 idx = config->addr_idx;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700371 if (idx % 2 != 0) {
372 spin_unlock(&drvdata->spinlock);
373 return -EPERM;
374 }
Mathieu Poirier1925a472016-02-17 17:51:51 -0700375 if (!((config->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
376 config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
377 (config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
378 config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700379 spin_unlock(&drvdata->spinlock);
380 return -EPERM;
381 }
382
Mathieu Poirier1925a472016-02-17 17:51:51 -0700383 val1 = config->addr_val[idx];
384 val2 = config->addr_val[idx + 1];
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700385 spin_unlock(&drvdata->spinlock);
386
387 return sprintf(buf, "%#lx %#lx\n", val1, val2);
388}
389
390static ssize_t addr_range_store(struct device *dev,
391 struct device_attribute *attr,
392 const char *buf, size_t size)
393{
394 u8 idx;
395 unsigned long val1, val2;
396 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700397 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700398
399 if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
400 return -EINVAL;
401 /* Lower address comparator cannot have a higher address value */
402 if (val1 > val2)
403 return -EINVAL;
404
405 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700406 idx = config->addr_idx;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700407 if (idx % 2 != 0) {
408 spin_unlock(&drvdata->spinlock);
409 return -EPERM;
410 }
Mathieu Poirier1925a472016-02-17 17:51:51 -0700411 if (!((config->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
412 config->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
413 (config->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
414 config->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700415 spin_unlock(&drvdata->spinlock);
416 return -EPERM;
417 }
418
Mathieu Poirier1925a472016-02-17 17:51:51 -0700419 config->addr_val[idx] = val1;
420 config->addr_type[idx] = ETM_ADDR_TYPE_RANGE;
421 config->addr_val[idx + 1] = val2;
422 config->addr_type[idx + 1] = ETM_ADDR_TYPE_RANGE;
423 config->enable_ctrl1 |= (1 << (idx/2));
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700424 spin_unlock(&drvdata->spinlock);
425
426 return size;
427}
428static DEVICE_ATTR_RW(addr_range);
429
430static ssize_t addr_start_show(struct device *dev,
431 struct device_attribute *attr, char *buf)
432{
433 u8 idx;
434 unsigned long val;
435 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700436 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700437
438 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700439 idx = config->addr_idx;
440 if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
441 config->addr_type[idx] == ETM_ADDR_TYPE_START)) {
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700442 spin_unlock(&drvdata->spinlock);
443 return -EPERM;
444 }
445
Mathieu Poirier1925a472016-02-17 17:51:51 -0700446 val = config->addr_val[idx];
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700447 spin_unlock(&drvdata->spinlock);
448
449 return sprintf(buf, "%#lx\n", val);
450}
451
452static ssize_t addr_start_store(struct device *dev,
453 struct device_attribute *attr,
454 const char *buf, size_t size)
455{
456 u8 idx;
457 int ret;
458 unsigned long val;
459 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700460 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700461
462 ret = kstrtoul(buf, 16, &val);
463 if (ret)
464 return ret;
465
466 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700467 idx = config->addr_idx;
468 if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
469 config->addr_type[idx] == ETM_ADDR_TYPE_START)) {
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700470 spin_unlock(&drvdata->spinlock);
471 return -EPERM;
472 }
473
Mathieu Poirier1925a472016-02-17 17:51:51 -0700474 config->addr_val[idx] = val;
475 config->addr_type[idx] = ETM_ADDR_TYPE_START;
476 config->startstop_ctrl |= (1 << idx);
477 config->enable_ctrl1 |= BIT(25);
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700478 spin_unlock(&drvdata->spinlock);
479
480 return size;
481}
482static DEVICE_ATTR_RW(addr_start);
483
484static ssize_t addr_stop_show(struct device *dev,
485 struct device_attribute *attr, char *buf)
486{
487 u8 idx;
488 unsigned long val;
489 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700490 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700491
492 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700493 idx = config->addr_idx;
494 if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
495 config->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700496 spin_unlock(&drvdata->spinlock);
497 return -EPERM;
498 }
499
Mathieu Poirier1925a472016-02-17 17:51:51 -0700500 val = config->addr_val[idx];
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700501 spin_unlock(&drvdata->spinlock);
502
503 return sprintf(buf, "%#lx\n", val);
504}
505
506static ssize_t addr_stop_store(struct device *dev,
507 struct device_attribute *attr,
508 const char *buf, size_t size)
509{
510 u8 idx;
511 int ret;
512 unsigned long val;
513 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700514 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700515
516 ret = kstrtoul(buf, 16, &val);
517 if (ret)
518 return ret;
519
520 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700521 idx = config->addr_idx;
522 if (!(config->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
523 config->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700524 spin_unlock(&drvdata->spinlock);
525 return -EPERM;
526 }
527
Mathieu Poirier1925a472016-02-17 17:51:51 -0700528 config->addr_val[idx] = val;
529 config->addr_type[idx] = ETM_ADDR_TYPE_STOP;
530 config->startstop_ctrl |= (1 << (idx + 16));
531 config->enable_ctrl1 |= ETMTECR1_START_STOP;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700532 spin_unlock(&drvdata->spinlock);
533
534 return size;
535}
536static DEVICE_ATTR_RW(addr_stop);
537
538static ssize_t addr_acctype_show(struct device *dev,
539 struct device_attribute *attr, char *buf)
540{
541 unsigned long val;
542 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700543 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700544
545 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700546 val = config->addr_acctype[config->addr_idx];
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700547 spin_unlock(&drvdata->spinlock);
548
549 return sprintf(buf, "%#lx\n", val);
550}
551
552static ssize_t addr_acctype_store(struct device *dev,
553 struct device_attribute *attr,
554 const char *buf, size_t size)
555{
556 int ret;
557 unsigned long val;
558 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700559 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700560
561 ret = kstrtoul(buf, 16, &val);
562 if (ret)
563 return ret;
564
565 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700566 config->addr_acctype[config->addr_idx] = val;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700567 spin_unlock(&drvdata->spinlock);
568
569 return size;
570}
571static DEVICE_ATTR_RW(addr_acctype);
572
573static ssize_t cntr_idx_show(struct device *dev,
574 struct device_attribute *attr, char *buf)
575{
576 unsigned long val;
577 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700578 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700579
Mathieu Poirier1925a472016-02-17 17:51:51 -0700580 val = config->cntr_idx;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700581 return sprintf(buf, "%#lx\n", val);
582}
583
584static ssize_t cntr_idx_store(struct device *dev,
585 struct device_attribute *attr,
586 const char *buf, size_t size)
587{
588 int ret;
589 unsigned long val;
590 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700591 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700592
593 ret = kstrtoul(buf, 16, &val);
594 if (ret)
595 return ret;
596
597 if (val >= drvdata->nr_cntr)
598 return -EINVAL;
599 /*
600 * Use spinlock to ensure index doesn't change while it gets
601 * dereferenced multiple times within a spinlock block elsewhere.
602 */
603 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700604 config->cntr_idx = val;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700605 spin_unlock(&drvdata->spinlock);
606
607 return size;
608}
609static DEVICE_ATTR_RW(cntr_idx);
610
611static ssize_t cntr_rld_val_show(struct device *dev,
612 struct device_attribute *attr, char *buf)
613{
614 unsigned long val;
615 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700616 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700617
618 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700619 val = config->cntr_rld_val[config->cntr_idx];
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700620 spin_unlock(&drvdata->spinlock);
621
622 return sprintf(buf, "%#lx\n", val);
623}
624
625static ssize_t cntr_rld_val_store(struct device *dev,
626 struct device_attribute *attr,
627 const char *buf, size_t size)
628{
629 int ret;
630 unsigned long val;
631 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700632 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700633
634 ret = kstrtoul(buf, 16, &val);
635 if (ret)
636 return ret;
637
638 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700639 config->cntr_rld_val[config->cntr_idx] = val;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700640 spin_unlock(&drvdata->spinlock);
641
642 return size;
643}
644static DEVICE_ATTR_RW(cntr_rld_val);
645
646static ssize_t cntr_event_show(struct device *dev,
647 struct device_attribute *attr, char *buf)
648{
649 unsigned long val;
650 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700651 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700652
653 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700654 val = config->cntr_event[config->cntr_idx];
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700655 spin_unlock(&drvdata->spinlock);
656
657 return sprintf(buf, "%#lx\n", val);
658}
659
660static ssize_t cntr_event_store(struct device *dev,
661 struct device_attribute *attr,
662 const char *buf, size_t size)
663{
664 int ret;
665 unsigned long val;
666 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700667 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700668
669 ret = kstrtoul(buf, 16, &val);
670 if (ret)
671 return ret;
672
673 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700674 config->cntr_event[config->cntr_idx] = val & ETM_EVENT_MASK;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700675 spin_unlock(&drvdata->spinlock);
676
677 return size;
678}
679static DEVICE_ATTR_RW(cntr_event);
680
681static ssize_t cntr_rld_event_show(struct device *dev,
682 struct device_attribute *attr, char *buf)
683{
684 unsigned long val;
685 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700686 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700687
688 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700689 val = config->cntr_rld_event[config->cntr_idx];
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700690 spin_unlock(&drvdata->spinlock);
691
692 return sprintf(buf, "%#lx\n", val);
693}
694
695static ssize_t cntr_rld_event_store(struct device *dev,
696 struct device_attribute *attr,
697 const char *buf, size_t size)
698{
699 int ret;
700 unsigned long val;
701 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700702 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700703
704 ret = kstrtoul(buf, 16, &val);
705 if (ret)
706 return ret;
707
708 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700709 config->cntr_rld_event[config->cntr_idx] = val & ETM_EVENT_MASK;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700710 spin_unlock(&drvdata->spinlock);
711
712 return size;
713}
714static DEVICE_ATTR_RW(cntr_rld_event);
715
716static ssize_t cntr_val_show(struct device *dev,
717 struct device_attribute *attr, char *buf)
718{
719 int i, ret = 0;
720 u32 val;
721 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700722 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700723
Mathieu Poirier22fd5322016-02-17 17:51:52 -0700724 if (!local_read(&drvdata->mode)) {
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700725 spin_lock(&drvdata->spinlock);
726 for (i = 0; i < drvdata->nr_cntr; i++)
727 ret += sprintf(buf, "counter %d: %x\n",
Mathieu Poirier1925a472016-02-17 17:51:51 -0700728 i, config->cntr_val[i]);
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700729 spin_unlock(&drvdata->spinlock);
730 return ret;
731 }
732
733 for (i = 0; i < drvdata->nr_cntr; i++) {
734 val = etm_readl(drvdata, ETMCNTVRn(i));
735 ret += sprintf(buf, "counter %d: %x\n", i, val);
736 }
737
738 return ret;
739}
740
741static ssize_t cntr_val_store(struct device *dev,
742 struct device_attribute *attr,
743 const char *buf, size_t size)
744{
745 int ret;
746 unsigned long val;
747 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700748 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700749
750 ret = kstrtoul(buf, 16, &val);
751 if (ret)
752 return ret;
753
754 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700755 config->cntr_val[config->cntr_idx] = val;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700756 spin_unlock(&drvdata->spinlock);
757
758 return size;
759}
760static DEVICE_ATTR_RW(cntr_val);
761
762static ssize_t seq_12_event_show(struct device *dev,
763 struct device_attribute *attr, char *buf)
764{
765 unsigned long val;
766 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700767 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700768
Mathieu Poirier1925a472016-02-17 17:51:51 -0700769 val = config->seq_12_event;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700770 return sprintf(buf, "%#lx\n", val);
771}
772
773static ssize_t seq_12_event_store(struct device *dev,
774 struct device_attribute *attr,
775 const char *buf, size_t size)
776{
777 int ret;
778 unsigned long val;
779 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700780 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700781
782 ret = kstrtoul(buf, 16, &val);
783 if (ret)
784 return ret;
785
Mathieu Poirier1925a472016-02-17 17:51:51 -0700786 config->seq_12_event = val & ETM_EVENT_MASK;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700787 return size;
788}
789static DEVICE_ATTR_RW(seq_12_event);
790
791static ssize_t seq_21_event_show(struct device *dev,
792 struct device_attribute *attr, char *buf)
793{
794 unsigned long val;
795 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700796 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700797
Mathieu Poirier1925a472016-02-17 17:51:51 -0700798 val = config->seq_21_event;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700799 return sprintf(buf, "%#lx\n", val);
800}
801
802static ssize_t seq_21_event_store(struct device *dev,
803 struct device_attribute *attr,
804 const char *buf, size_t size)
805{
806 int ret;
807 unsigned long val;
808 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700809 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700810
811 ret = kstrtoul(buf, 16, &val);
812 if (ret)
813 return ret;
814
Mathieu Poirier1925a472016-02-17 17:51:51 -0700815 config->seq_21_event = val & ETM_EVENT_MASK;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700816 return size;
817}
818static DEVICE_ATTR_RW(seq_21_event);
819
820static ssize_t seq_23_event_show(struct device *dev,
821 struct device_attribute *attr, char *buf)
822{
823 unsigned long val;
824 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700825 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700826
Mathieu Poirier1925a472016-02-17 17:51:51 -0700827 val = config->seq_23_event;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700828 return sprintf(buf, "%#lx\n", val);
829}
830
831static ssize_t seq_23_event_store(struct device *dev,
832 struct device_attribute *attr,
833 const char *buf, size_t size)
834{
835 int ret;
836 unsigned long val;
837 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700838 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700839
840 ret = kstrtoul(buf, 16, &val);
841 if (ret)
842 return ret;
843
Mathieu Poirier1925a472016-02-17 17:51:51 -0700844 config->seq_23_event = val & ETM_EVENT_MASK;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700845 return size;
846}
847static DEVICE_ATTR_RW(seq_23_event);
848
849static ssize_t seq_31_event_show(struct device *dev,
850 struct device_attribute *attr, char *buf)
851{
852 unsigned long val;
853 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700854 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700855
Mathieu Poirier1925a472016-02-17 17:51:51 -0700856 val = config->seq_31_event;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700857 return sprintf(buf, "%#lx\n", val);
858}
859
860static ssize_t seq_31_event_store(struct device *dev,
861 struct device_attribute *attr,
862 const char *buf, size_t size)
863{
864 int ret;
865 unsigned long val;
866 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700867 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700868
869 ret = kstrtoul(buf, 16, &val);
870 if (ret)
871 return ret;
872
Mathieu Poirier1925a472016-02-17 17:51:51 -0700873 config->seq_31_event = val & ETM_EVENT_MASK;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700874 return size;
875}
876static DEVICE_ATTR_RW(seq_31_event);
877
878static ssize_t seq_32_event_show(struct device *dev,
879 struct device_attribute *attr, char *buf)
880{
881 unsigned long val;
882 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700883 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700884
Mathieu Poirier1925a472016-02-17 17:51:51 -0700885 val = config->seq_32_event;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700886 return sprintf(buf, "%#lx\n", val);
887}
888
889static ssize_t seq_32_event_store(struct device *dev,
890 struct device_attribute *attr,
891 const char *buf, size_t size)
892{
893 int ret;
894 unsigned long val;
895 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700896 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700897
898 ret = kstrtoul(buf, 16, &val);
899 if (ret)
900 return ret;
901
Mathieu Poirier1925a472016-02-17 17:51:51 -0700902 config->seq_32_event = val & ETM_EVENT_MASK;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700903 return size;
904}
905static DEVICE_ATTR_RW(seq_32_event);
906
907static ssize_t seq_13_event_show(struct device *dev,
908 struct device_attribute *attr, char *buf)
909{
910 unsigned long val;
911 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700912 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700913
Mathieu Poirier1925a472016-02-17 17:51:51 -0700914 val = config->seq_13_event;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700915 return sprintf(buf, "%#lx\n", val);
916}
917
918static ssize_t seq_13_event_store(struct device *dev,
919 struct device_attribute *attr,
920 const char *buf, size_t size)
921{
922 int ret;
923 unsigned long val;
924 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700925 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700926
927 ret = kstrtoul(buf, 16, &val);
928 if (ret)
929 return ret;
930
Mathieu Poirier1925a472016-02-17 17:51:51 -0700931 config->seq_13_event = val & ETM_EVENT_MASK;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700932 return size;
933}
934static DEVICE_ATTR_RW(seq_13_event);
935
936static ssize_t seq_curr_state_show(struct device *dev,
937 struct device_attribute *attr, char *buf)
938{
939 unsigned long val, flags;
940 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700941 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700942
Mathieu Poirier22fd5322016-02-17 17:51:52 -0700943 if (!local_read(&drvdata->mode)) {
Mathieu Poirier1925a472016-02-17 17:51:51 -0700944 val = config->seq_curr_state;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700945 goto out;
946 }
947
948 pm_runtime_get_sync(drvdata->dev);
949 spin_lock_irqsave(&drvdata->spinlock, flags);
950
951 CS_UNLOCK(drvdata->base);
952 val = (etm_readl(drvdata, ETMSQR) & ETM_SQR_MASK);
953 CS_LOCK(drvdata->base);
954
955 spin_unlock_irqrestore(&drvdata->spinlock, flags);
956 pm_runtime_put(drvdata->dev);
957out:
958 return sprintf(buf, "%#lx\n", val);
959}
960
961static ssize_t seq_curr_state_store(struct device *dev,
962 struct device_attribute *attr,
963 const char *buf, size_t size)
964{
965 int ret;
966 unsigned long val;
967 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700968 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700969
970 ret = kstrtoul(buf, 16, &val);
971 if (ret)
972 return ret;
973
974 if (val > ETM_SEQ_STATE_MAX_VAL)
975 return -EINVAL;
976
Mathieu Poirier1925a472016-02-17 17:51:51 -0700977 config->seq_curr_state = val;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700978
979 return size;
980}
981static DEVICE_ATTR_RW(seq_curr_state);
982
983static ssize_t ctxid_idx_show(struct device *dev,
984 struct device_attribute *attr, char *buf)
985{
986 unsigned long val;
987 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -0700988 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700989
Mathieu Poirier1925a472016-02-17 17:51:51 -0700990 val = config->ctxid_idx;
Mathieu Poirierc04148e2016-02-17 17:51:49 -0700991 return sprintf(buf, "%#lx\n", val);
992}
993
994static ssize_t ctxid_idx_store(struct device *dev,
995 struct device_attribute *attr,
996 const char *buf, size_t size)
997{
998 int ret;
999 unsigned long val;
1000 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -07001001 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001002
1003 ret = kstrtoul(buf, 16, &val);
1004 if (ret)
1005 return ret;
1006
1007 if (val >= drvdata->nr_ctxid_cmp)
1008 return -EINVAL;
1009
1010 /*
1011 * Use spinlock to ensure index doesn't change while it gets
1012 * dereferenced multiple times within a spinlock block elsewhere.
1013 */
1014 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -07001015 config->ctxid_idx = val;
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001016 spin_unlock(&drvdata->spinlock);
1017
1018 return size;
1019}
1020static DEVICE_ATTR_RW(ctxid_idx);
1021
1022static ssize_t ctxid_pid_show(struct device *dev,
1023 struct device_attribute *attr, char *buf)
1024{
1025 unsigned long val;
1026 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -07001027 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001028
1029 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -07001030 val = config->ctxid_vpid[config->ctxid_idx];
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001031 spin_unlock(&drvdata->spinlock);
1032
1033 return sprintf(buf, "%#lx\n", val);
1034}
1035
1036static ssize_t ctxid_pid_store(struct device *dev,
1037 struct device_attribute *attr,
1038 const char *buf, size_t size)
1039{
1040 int ret;
1041 unsigned long vpid, pid;
1042 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -07001043 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001044
1045 ret = kstrtoul(buf, 16, &vpid);
1046 if (ret)
1047 return ret;
1048
1049 pid = coresight_vpid_to_pid(vpid);
1050
1051 spin_lock(&drvdata->spinlock);
Mathieu Poirier1925a472016-02-17 17:51:51 -07001052 config->ctxid_pid[config->ctxid_idx] = pid;
1053 config->ctxid_vpid[config->ctxid_idx] = vpid;
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001054 spin_unlock(&drvdata->spinlock);
1055
1056 return size;
1057}
1058static DEVICE_ATTR_RW(ctxid_pid);
1059
1060static ssize_t ctxid_mask_show(struct device *dev,
1061 struct device_attribute *attr, char *buf)
1062{
1063 unsigned long val;
1064 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -07001065 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001066
Mathieu Poirier1925a472016-02-17 17:51:51 -07001067 val = config->ctxid_mask;
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001068 return sprintf(buf, "%#lx\n", val);
1069}
1070
1071static ssize_t ctxid_mask_store(struct device *dev,
1072 struct device_attribute *attr,
1073 const char *buf, size_t size)
1074{
1075 int ret;
1076 unsigned long val;
1077 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -07001078 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001079
1080 ret = kstrtoul(buf, 16, &val);
1081 if (ret)
1082 return ret;
1083
Mathieu Poirier1925a472016-02-17 17:51:51 -07001084 config->ctxid_mask = val;
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001085 return size;
1086}
1087static DEVICE_ATTR_RW(ctxid_mask);
1088
1089static ssize_t sync_freq_show(struct device *dev,
1090 struct device_attribute *attr, char *buf)
1091{
1092 unsigned long val;
1093 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -07001094 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001095
Mathieu Poirier1925a472016-02-17 17:51:51 -07001096 val = config->sync_freq;
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001097 return sprintf(buf, "%#lx\n", val);
1098}
1099
1100static ssize_t sync_freq_store(struct device *dev,
1101 struct device_attribute *attr,
1102 const char *buf, size_t size)
1103{
1104 int ret;
1105 unsigned long val;
1106 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -07001107 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001108
1109 ret = kstrtoul(buf, 16, &val);
1110 if (ret)
1111 return ret;
1112
Mathieu Poirier1925a472016-02-17 17:51:51 -07001113 config->sync_freq = val & ETM_SYNC_MASK;
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001114 return size;
1115}
1116static DEVICE_ATTR_RW(sync_freq);
1117
1118static ssize_t timestamp_event_show(struct device *dev,
1119 struct device_attribute *attr, char *buf)
1120{
1121 unsigned long val;
1122 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -07001123 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001124
Mathieu Poirier1925a472016-02-17 17:51:51 -07001125 val = config->timestamp_event;
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001126 return sprintf(buf, "%#lx\n", val);
1127}
1128
1129static ssize_t timestamp_event_store(struct device *dev,
1130 struct device_attribute *attr,
1131 const char *buf, size_t size)
1132{
1133 int ret;
1134 unsigned long val;
1135 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
Mathieu Poirier1925a472016-02-17 17:51:51 -07001136 struct etm_config *config = &drvdata->config;
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001137
1138 ret = kstrtoul(buf, 16, &val);
1139 if (ret)
1140 return ret;
1141
Mathieu Poirier1925a472016-02-17 17:51:51 -07001142 config->timestamp_event = val & ETM_EVENT_MASK;
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001143 return size;
1144}
1145static DEVICE_ATTR_RW(timestamp_event);
1146
1147static ssize_t cpu_show(struct device *dev,
1148 struct device_attribute *attr, char *buf)
1149{
1150 int val;
1151 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1152
1153 val = drvdata->cpu;
1154 return scnprintf(buf, PAGE_SIZE, "%d\n", val);
1155
1156}
1157static DEVICE_ATTR_RO(cpu);
1158
1159static ssize_t traceid_show(struct device *dev,
1160 struct device_attribute *attr, char *buf)
1161{
1162 unsigned long val;
1163 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1164
1165 val = etm_get_trace_id(drvdata);
1166
1167 return sprintf(buf, "%#lx\n", val);
1168}
1169
1170static ssize_t traceid_store(struct device *dev,
1171 struct device_attribute *attr,
1172 const char *buf, size_t size)
1173{
1174 int ret;
1175 unsigned long val;
1176 struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
1177
1178 ret = kstrtoul(buf, 16, &val);
1179 if (ret)
1180 return ret;
1181
1182 drvdata->traceid = val & ETM_TRACEID_MASK;
1183 return size;
1184}
1185static DEVICE_ATTR_RW(traceid);
1186
1187static struct attribute *coresight_etm_attrs[] = {
1188 &dev_attr_nr_addr_cmp.attr,
1189 &dev_attr_nr_cntr.attr,
1190 &dev_attr_nr_ctxid_cmp.attr,
1191 &dev_attr_etmsr.attr,
1192 &dev_attr_reset.attr,
1193 &dev_attr_mode.attr,
1194 &dev_attr_trigger_event.attr,
1195 &dev_attr_enable_event.attr,
1196 &dev_attr_fifofull_level.attr,
1197 &dev_attr_addr_idx.attr,
1198 &dev_attr_addr_single.attr,
1199 &dev_attr_addr_range.attr,
1200 &dev_attr_addr_start.attr,
1201 &dev_attr_addr_stop.attr,
1202 &dev_attr_addr_acctype.attr,
1203 &dev_attr_cntr_idx.attr,
1204 &dev_attr_cntr_rld_val.attr,
1205 &dev_attr_cntr_event.attr,
1206 &dev_attr_cntr_rld_event.attr,
1207 &dev_attr_cntr_val.attr,
1208 &dev_attr_seq_12_event.attr,
1209 &dev_attr_seq_21_event.attr,
1210 &dev_attr_seq_23_event.attr,
1211 &dev_attr_seq_31_event.attr,
1212 &dev_attr_seq_32_event.attr,
1213 &dev_attr_seq_13_event.attr,
1214 &dev_attr_seq_curr_state.attr,
1215 &dev_attr_ctxid_idx.attr,
1216 &dev_attr_ctxid_pid.attr,
1217 &dev_attr_ctxid_mask.attr,
1218 &dev_attr_sync_freq.attr,
1219 &dev_attr_timestamp_event.attr,
1220 &dev_attr_traceid.attr,
1221 &dev_attr_cpu.attr,
1222 NULL,
1223};
1224
Mathieu Poirier154f35202016-04-05 11:53:50 -06001225#define coresight_etm3x_simple_func(name, offset) \
Sudeep Holla3224dcc2016-08-25 15:19:09 -06001226 coresight_simple_func(struct etm_drvdata, NULL, name, offset)
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001227
Mathieu Poirier154f35202016-04-05 11:53:50 -06001228coresight_etm3x_simple_func(etmccr, ETMCCR);
1229coresight_etm3x_simple_func(etmccer, ETMCCER);
1230coresight_etm3x_simple_func(etmscr, ETMSCR);
1231coresight_etm3x_simple_func(etmidr, ETMIDR);
1232coresight_etm3x_simple_func(etmcr, ETMCR);
1233coresight_etm3x_simple_func(etmtraceidr, ETMTRACEIDR);
1234coresight_etm3x_simple_func(etmteevr, ETMTEEVR);
1235coresight_etm3x_simple_func(etmtssvr, ETMTSSCR);
1236coresight_etm3x_simple_func(etmtecr1, ETMTECR1);
1237coresight_etm3x_simple_func(etmtecr2, ETMTECR2);
Mathieu Poirierc04148e2016-02-17 17:51:49 -07001238
1239static struct attribute *coresight_etm_mgmt_attrs[] = {
1240 &dev_attr_etmccr.attr,
1241 &dev_attr_etmccer.attr,
1242 &dev_attr_etmscr.attr,
1243 &dev_attr_etmidr.attr,
1244 &dev_attr_etmcr.attr,
1245 &dev_attr_etmtraceidr.attr,
1246 &dev_attr_etmteevr.attr,
1247 &dev_attr_etmtssvr.attr,
1248 &dev_attr_etmtecr1.attr,
1249 &dev_attr_etmtecr2.attr,
1250 NULL,
1251};
1252
1253static const struct attribute_group coresight_etm_group = {
1254 .attrs = coresight_etm_attrs,
1255};
1256
1257static const struct attribute_group coresight_etm_mgmt_group = {
1258 .attrs = coresight_etm_mgmt_attrs,
1259 .name = "mgmt",
1260};
1261
1262const struct attribute_group *coresight_etm_groups[] = {
1263 &coresight_etm_group,
1264 &coresight_etm_mgmt_group,
1265 NULL,
1266};