Loading...
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2019 Linaro Limited, All rights reserved.
4 * Author: Mike Leach <mike.leach@linaro.org>
5 */
6
7#include <linux/atomic.h>
8#include <linux/coresight.h>
9#include <linux/device.h>
10#include <linux/io.h>
11#include <linux/kernel.h>
12#include <linux/spinlock.h>
13#include <linux/sysfs.h>
14
15#include "coresight-cti.h"
16
17/*
18 * Declare the number of static declared attribute groups
19 * Value includes groups + NULL value at end of table.
20 */
21#define CORESIGHT_CTI_STATIC_GROUPS_MAX 5
22
23/*
24 * List of trigger signal type names. Match the constants declared in
25 * include\dt-bindings\arm\coresight-cti-dt.h
26 */
27static const char * const sig_type_names[] = {
28 "genio", /* GEN_IO */
29 "intreq", /* GEN_INTREQ */
30 "intack", /* GEN_INTACK */
31 "haltreq", /* GEN_HALTREQ */
32 "restartreq", /* GEN_RESTARTREQ */
33 "pe_edbgreq", /* PE_EDBGREQ */
34 "pe_dbgrestart",/* PE_DBGRESTART */
35 "pe_ctiirq", /* PE_CTIIRQ */
36 "pe_pmuirq", /* PE_PMUIRQ */
37 "pe_dbgtrigger",/* PE_DBGTRIGGER */
38 "etm_extout", /* ETM_EXTOUT */
39 "etm_extin", /* ETM_EXTIN */
40 "snk_full", /* SNK_FULL */
41 "snk_acqcomp", /* SNK_ACQCOMP */
42 "snk_flushcomp",/* SNK_FLUSHCOMP */
43 "snk_flushin", /* SNK_FLUSHIN */
44 "snk_trigin", /* SNK_TRIGIN */
45 "stm_asyncout", /* STM_ASYNCOUT */
46 "stm_tout_spte",/* STM_TOUT_SPTE */
47 "stm_tout_sw", /* STM_TOUT_SW */
48 "stm_tout_hete",/* STM_TOUT_HETE */
49 "stm_hwevent", /* STM_HWEVENT */
50 "ela_tstart", /* ELA_TSTART */
51 "ela_tstop", /* ELA_TSTOP */
52 "ela_dbgreq", /* ELA_DBGREQ */
53};
54
55/* Show function pointer used in the connections dynamic declared attributes*/
56typedef ssize_t (*p_show_fn)(struct device *dev, struct device_attribute *attr,
57 char *buf);
58
59/* Connection attribute types */
60enum cti_conn_attr_type {
61 CTI_CON_ATTR_NAME,
62 CTI_CON_ATTR_TRIGIN_SIG,
63 CTI_CON_ATTR_TRIGOUT_SIG,
64 CTI_CON_ATTR_TRIGIN_TYPES,
65 CTI_CON_ATTR_TRIGOUT_TYPES,
66 CTI_CON_ATTR_MAX,
67};
68
69/* Names for the connection attributes */
70static const char * const con_attr_names[CTI_CON_ATTR_MAX] = {
71 "name",
72 "in_signals",
73 "out_signals",
74 "in_types",
75 "out_types",
76};
77
78/* basic attributes */
79static ssize_t enable_show(struct device *dev,
80 struct device_attribute *attr,
81 char *buf)
82{
83 int enable_req;
84 bool enabled, powered;
85 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
86
87 spin_lock(&drvdata->spinlock);
88 enable_req = drvdata->config.enable_req_count;
89 powered = drvdata->config.hw_powered;
90 enabled = drvdata->config.hw_enabled;
91 spin_unlock(&drvdata->spinlock);
92
93 if (powered)
94 return sprintf(buf, "%d\n", enabled);
95 else
96 return sprintf(buf, "%d\n", !!enable_req);
97}
98
99static ssize_t enable_store(struct device *dev,
100 struct device_attribute *attr,
101 const char *buf, size_t size)
102{
103 int ret = 0;
104 unsigned long val;
105 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
106
107 ret = kstrtoul(buf, 0, &val);
108 if (ret)
109 return ret;
110
111 if (val) {
112 ret = pm_runtime_resume_and_get(dev->parent);
113 if (ret)
114 return ret;
115 ret = cti_enable(drvdata->csdev, CS_MODE_SYSFS, NULL);
116 if (ret)
117 pm_runtime_put(dev->parent);
118 } else {
119 ret = cti_disable(drvdata->csdev, NULL);
120 if (!ret)
121 pm_runtime_put(dev->parent);
122 }
123
124 if (ret)
125 return ret;
126 return size;
127}
128static DEVICE_ATTR_RW(enable);
129
130static ssize_t powered_show(struct device *dev,
131 struct device_attribute *attr,
132 char *buf)
133{
134 bool powered;
135 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
136
137 spin_lock(&drvdata->spinlock);
138 powered = drvdata->config.hw_powered;
139 spin_unlock(&drvdata->spinlock);
140
141 return sprintf(buf, "%d\n", powered);
142}
143static DEVICE_ATTR_RO(powered);
144
145static ssize_t ctmid_show(struct device *dev,
146 struct device_attribute *attr, char *buf)
147{
148 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
149
150 return sprintf(buf, "%d\n", drvdata->ctidev.ctm_id);
151}
152static DEVICE_ATTR_RO(ctmid);
153
154static ssize_t nr_trigger_cons_show(struct device *dev,
155 struct device_attribute *attr,
156 char *buf)
157{
158 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
159
160 return sprintf(buf, "%d\n", drvdata->ctidev.nr_trig_con);
161}
162static DEVICE_ATTR_RO(nr_trigger_cons);
163
164/* attribute and group sysfs tables. */
165static struct attribute *coresight_cti_attrs[] = {
166 &dev_attr_enable.attr,
167 &dev_attr_powered.attr,
168 &dev_attr_ctmid.attr,
169 &dev_attr_nr_trigger_cons.attr,
170 NULL,
171};
172
173/* register based attributes */
174
175/* Read registers with power check only (no enable check). */
176static ssize_t coresight_cti_reg_show(struct device *dev,
177 struct device_attribute *attr, char *buf)
178{
179 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
180 struct cs_off_attribute *cti_attr = container_of(attr, struct cs_off_attribute, attr);
181 u32 val = 0;
182
183 pm_runtime_get_sync(dev->parent);
184 spin_lock(&drvdata->spinlock);
185 if (drvdata->config.hw_powered)
186 val = readl_relaxed(drvdata->base + cti_attr->off);
187 spin_unlock(&drvdata->spinlock);
188 pm_runtime_put_sync(dev->parent);
189 return sysfs_emit(buf, "0x%x\n", val);
190}
191
192/* Write registers with power check only (no enable check). */
193static __maybe_unused ssize_t coresight_cti_reg_store(struct device *dev,
194 struct device_attribute *attr,
195 const char *buf, size_t size)
196{
197 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
198 struct cs_off_attribute *cti_attr = container_of(attr, struct cs_off_attribute, attr);
199 unsigned long val = 0;
200
201 if (kstrtoul(buf, 0, &val))
202 return -EINVAL;
203
204 pm_runtime_get_sync(dev->parent);
205 spin_lock(&drvdata->spinlock);
206 if (drvdata->config.hw_powered)
207 cti_write_single_reg(drvdata, cti_attr->off, val);
208 spin_unlock(&drvdata->spinlock);
209 pm_runtime_put_sync(dev->parent);
210 return size;
211}
212
213#define coresight_cti_reg(name, offset) \
214 (&((struct cs_off_attribute[]) { \
215 { \
216 __ATTR(name, 0444, coresight_cti_reg_show, NULL), \
217 offset \
218 } \
219 })[0].attr.attr)
220
221#define coresight_cti_reg_rw(name, offset) \
222 (&((struct cs_off_attribute[]) { \
223 { \
224 __ATTR(name, 0644, coresight_cti_reg_show, \
225 coresight_cti_reg_store), \
226 offset \
227 } \
228 })[0].attr.attr)
229
230#define coresight_cti_reg_wo(name, offset) \
231 (&((struct cs_off_attribute[]) { \
232 { \
233 __ATTR(name, 0200, NULL, coresight_cti_reg_store), \
234 offset \
235 } \
236 })[0].attr.attr)
237
238/* coresight management registers */
239static struct attribute *coresight_cti_mgmt_attrs[] = {
240 coresight_cti_reg(devaff0, CTIDEVAFF0),
241 coresight_cti_reg(devaff1, CTIDEVAFF1),
242 coresight_cti_reg(authstatus, CORESIGHT_AUTHSTATUS),
243 coresight_cti_reg(devarch, CORESIGHT_DEVARCH),
244 coresight_cti_reg(devid, CORESIGHT_DEVID),
245 coresight_cti_reg(devtype, CORESIGHT_DEVTYPE),
246 coresight_cti_reg(pidr0, CORESIGHT_PERIPHIDR0),
247 coresight_cti_reg(pidr1, CORESIGHT_PERIPHIDR1),
248 coresight_cti_reg(pidr2, CORESIGHT_PERIPHIDR2),
249 coresight_cti_reg(pidr3, CORESIGHT_PERIPHIDR3),
250 coresight_cti_reg(pidr4, CORESIGHT_PERIPHIDR4),
251 NULL,
252};
253
254/* CTI low level programming registers */
255
256/*
257 * Show a simple 32 bit value if enabled and powered.
258 * If inaccessible & pcached_val not NULL then show cached value.
259 */
260static ssize_t cti_reg32_show(struct device *dev, char *buf,
261 u32 *pcached_val, int reg_offset)
262{
263 u32 val = 0;
264 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
265 struct cti_config *config = &drvdata->config;
266
267 spin_lock(&drvdata->spinlock);
268 if ((reg_offset >= 0) && cti_active(config)) {
269 CS_UNLOCK(drvdata->base);
270 val = readl_relaxed(drvdata->base + reg_offset);
271 if (pcached_val)
272 *pcached_val = val;
273 CS_LOCK(drvdata->base);
274 } else if (pcached_val) {
275 val = *pcached_val;
276 }
277 spin_unlock(&drvdata->spinlock);
278 return sprintf(buf, "%#x\n", val);
279}
280
281/*
282 * Store a simple 32 bit value.
283 * If pcached_val not NULL, then copy to here too,
284 * if reg_offset >= 0 then write through if enabled.
285 */
286static ssize_t cti_reg32_store(struct device *dev, const char *buf,
287 size_t size, u32 *pcached_val, int reg_offset)
288{
289 unsigned long val;
290 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
291 struct cti_config *config = &drvdata->config;
292
293 if (kstrtoul(buf, 0, &val))
294 return -EINVAL;
295
296 spin_lock(&drvdata->spinlock);
297 /* local store */
298 if (pcached_val)
299 *pcached_val = (u32)val;
300
301 /* write through if offset and enabled */
302 if ((reg_offset >= 0) && cti_active(config))
303 cti_write_single_reg(drvdata, reg_offset, val);
304 spin_unlock(&drvdata->spinlock);
305 return size;
306}
307
308/* Standard macro for simple rw cti config registers */
309#define cti_config_reg32_rw(name, cfgname, offset) \
310static ssize_t name##_show(struct device *dev, \
311 struct device_attribute *attr, \
312 char *buf) \
313{ \
314 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
315 return cti_reg32_show(dev, buf, \
316 &drvdata->config.cfgname, offset); \
317} \
318 \
319static ssize_t name##_store(struct device *dev, \
320 struct device_attribute *attr, \
321 const char *buf, size_t size) \
322{ \
323 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
324 return cti_reg32_store(dev, buf, size, \
325 &drvdata->config.cfgname, offset); \
326} \
327static DEVICE_ATTR_RW(name)
328
329static ssize_t inout_sel_show(struct device *dev,
330 struct device_attribute *attr,
331 char *buf)
332{
333 u32 val;
334 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
335
336 val = (u32)drvdata->config.ctiinout_sel;
337 return sprintf(buf, "%d\n", val);
338}
339
340static ssize_t inout_sel_store(struct device *dev,
341 struct device_attribute *attr,
342 const char *buf, size_t size)
343{
344 unsigned long val;
345 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
346
347 if (kstrtoul(buf, 0, &val))
348 return -EINVAL;
349 if (val > (CTIINOUTEN_MAX - 1))
350 return -EINVAL;
351
352 spin_lock(&drvdata->spinlock);
353 drvdata->config.ctiinout_sel = val;
354 spin_unlock(&drvdata->spinlock);
355 return size;
356}
357static DEVICE_ATTR_RW(inout_sel);
358
359static ssize_t inen_show(struct device *dev,
360 struct device_attribute *attr,
361 char *buf)
362{
363 unsigned long val;
364 int index;
365 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
366
367 spin_lock(&drvdata->spinlock);
368 index = drvdata->config.ctiinout_sel;
369 val = drvdata->config.ctiinen[index];
370 spin_unlock(&drvdata->spinlock);
371 return sprintf(buf, "%#lx\n", val);
372}
373
374static ssize_t inen_store(struct device *dev,
375 struct device_attribute *attr,
376 const char *buf, size_t size)
377{
378 unsigned long val;
379 int index;
380 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
381 struct cti_config *config = &drvdata->config;
382
383 if (kstrtoul(buf, 0, &val))
384 return -EINVAL;
385
386 spin_lock(&drvdata->spinlock);
387 index = config->ctiinout_sel;
388 config->ctiinen[index] = val;
389
390 /* write through if enabled */
391 if (cti_active(config))
392 cti_write_single_reg(drvdata, CTIINEN(index), val);
393 spin_unlock(&drvdata->spinlock);
394 return size;
395}
396static DEVICE_ATTR_RW(inen);
397
398static ssize_t outen_show(struct device *dev,
399 struct device_attribute *attr,
400 char *buf)
401{
402 unsigned long val;
403 int index;
404 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
405
406 spin_lock(&drvdata->spinlock);
407 index = drvdata->config.ctiinout_sel;
408 val = drvdata->config.ctiouten[index];
409 spin_unlock(&drvdata->spinlock);
410 return sprintf(buf, "%#lx\n", val);
411}
412
413static ssize_t outen_store(struct device *dev,
414 struct device_attribute *attr,
415 const char *buf, size_t size)
416{
417 unsigned long val;
418 int index;
419 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
420 struct cti_config *config = &drvdata->config;
421
422 if (kstrtoul(buf, 0, &val))
423 return -EINVAL;
424
425 spin_lock(&drvdata->spinlock);
426 index = config->ctiinout_sel;
427 config->ctiouten[index] = val;
428
429 /* write through if enabled */
430 if (cti_active(config))
431 cti_write_single_reg(drvdata, CTIOUTEN(index), val);
432 spin_unlock(&drvdata->spinlock);
433 return size;
434}
435static DEVICE_ATTR_RW(outen);
436
437static ssize_t intack_store(struct device *dev,
438 struct device_attribute *attr,
439 const char *buf, size_t size)
440{
441 unsigned long val;
442
443 if (kstrtoul(buf, 0, &val))
444 return -EINVAL;
445
446 cti_write_intack(dev, val);
447 return size;
448}
449static DEVICE_ATTR_WO(intack);
450
451cti_config_reg32_rw(gate, ctigate, CTIGATE);
452cti_config_reg32_rw(asicctl, asicctl, ASICCTL);
453cti_config_reg32_rw(appset, ctiappset, CTIAPPSET);
454
455static ssize_t appclear_store(struct device *dev,
456 struct device_attribute *attr,
457 const char *buf, size_t size)
458{
459 unsigned long val;
460 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
461 struct cti_config *config = &drvdata->config;
462
463 if (kstrtoul(buf, 0, &val))
464 return -EINVAL;
465
466 spin_lock(&drvdata->spinlock);
467
468 /* a 1'b1 in appclr clears down the same bit in appset*/
469 config->ctiappset &= ~val;
470
471 /* write through if enabled */
472 if (cti_active(config))
473 cti_write_single_reg(drvdata, CTIAPPCLEAR, val);
474 spin_unlock(&drvdata->spinlock);
475 return size;
476}
477static DEVICE_ATTR_WO(appclear);
478
479static ssize_t apppulse_store(struct device *dev,
480 struct device_attribute *attr,
481 const char *buf, size_t size)
482{
483 unsigned long val;
484 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
485 struct cti_config *config = &drvdata->config;
486
487 if (kstrtoul(buf, 0, &val))
488 return -EINVAL;
489
490 spin_lock(&drvdata->spinlock);
491
492 /* write through if enabled */
493 if (cti_active(config))
494 cti_write_single_reg(drvdata, CTIAPPPULSE, val);
495 spin_unlock(&drvdata->spinlock);
496 return size;
497}
498static DEVICE_ATTR_WO(apppulse);
499
500/*
501 * Define CONFIG_CORESIGHT_CTI_INTEGRATION_REGS to enable the access to the
502 * integration control registers. Normally only used to investigate connection
503 * data.
504 */
505static struct attribute *coresight_cti_regs_attrs[] = {
506 &dev_attr_inout_sel.attr,
507 &dev_attr_inen.attr,
508 &dev_attr_outen.attr,
509 &dev_attr_gate.attr,
510 &dev_attr_asicctl.attr,
511 &dev_attr_intack.attr,
512 &dev_attr_appset.attr,
513 &dev_attr_appclear.attr,
514 &dev_attr_apppulse.attr,
515 coresight_cti_reg(triginstatus, CTITRIGINSTATUS),
516 coresight_cti_reg(trigoutstatus, CTITRIGOUTSTATUS),
517 coresight_cti_reg(chinstatus, CTICHINSTATUS),
518 coresight_cti_reg(choutstatus, CTICHOUTSTATUS),
519#ifdef CONFIG_CORESIGHT_CTI_INTEGRATION_REGS
520 coresight_cti_reg_rw(itctrl, CORESIGHT_ITCTRL),
521 coresight_cti_reg(ittrigin, ITTRIGIN),
522 coresight_cti_reg(itchin, ITCHIN),
523 coresight_cti_reg_rw(ittrigout, ITTRIGOUT),
524 coresight_cti_reg_rw(itchout, ITCHOUT),
525 coresight_cti_reg(itchoutack, ITCHOUTACK),
526 coresight_cti_reg(ittrigoutack, ITTRIGOUTACK),
527 coresight_cti_reg_wo(ittriginack, ITTRIGINACK),
528 coresight_cti_reg_wo(itchinack, ITCHINACK),
529#endif
530 NULL,
531};
532
533/* CTI channel x-trigger programming */
534static int
535cti_trig_op_parse(struct device *dev, enum cti_chan_op op,
536 enum cti_trig_dir dir, const char *buf, size_t size)
537{
538 u32 chan_idx;
539 u32 trig_idx;
540 int items, err = -EINVAL;
541
542 /* extract chan idx and trigger idx */
543 items = sscanf(buf, "%d %d", &chan_idx, &trig_idx);
544 if (items == 2) {
545 err = cti_channel_trig_op(dev, op, dir, chan_idx, trig_idx);
546 if (!err)
547 err = size;
548 }
549 return err;
550}
551
552static ssize_t trigin_attach_store(struct device *dev,
553 struct device_attribute *attr,
554 const char *buf, size_t size)
555{
556 return cti_trig_op_parse(dev, CTI_CHAN_ATTACH, CTI_TRIG_IN,
557 buf, size);
558}
559static DEVICE_ATTR_WO(trigin_attach);
560
561static ssize_t trigin_detach_store(struct device *dev,
562 struct device_attribute *attr,
563 const char *buf, size_t size)
564{
565 return cti_trig_op_parse(dev, CTI_CHAN_DETACH, CTI_TRIG_IN,
566 buf, size);
567}
568static DEVICE_ATTR_WO(trigin_detach);
569
570static ssize_t trigout_attach_store(struct device *dev,
571 struct device_attribute *attr,
572 const char *buf, size_t size)
573{
574 return cti_trig_op_parse(dev, CTI_CHAN_ATTACH, CTI_TRIG_OUT,
575 buf, size);
576}
577static DEVICE_ATTR_WO(trigout_attach);
578
579static ssize_t trigout_detach_store(struct device *dev,
580 struct device_attribute *attr,
581 const char *buf, size_t size)
582{
583 return cti_trig_op_parse(dev, CTI_CHAN_DETACH, CTI_TRIG_OUT,
584 buf, size);
585}
586static DEVICE_ATTR_WO(trigout_detach);
587
588
589static ssize_t chan_gate_enable_store(struct device *dev,
590 struct device_attribute *attr,
591 const char *buf, size_t size)
592{
593 int err = 0, channel = 0;
594
595 if (kstrtoint(buf, 0, &channel))
596 return -EINVAL;
597
598 err = cti_channel_gate_op(dev, CTI_GATE_CHAN_ENABLE, channel);
599 return err ? err : size;
600}
601
602static ssize_t chan_gate_enable_show(struct device *dev,
603 struct device_attribute *attr,
604 char *buf)
605{
606 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
607 struct cti_config *cfg = &drvdata->config;
608 unsigned long ctigate_bitmask = cfg->ctigate;
609 int size = 0;
610
611 if (cfg->ctigate == 0)
612 size = sprintf(buf, "\n");
613 else
614 size = bitmap_print_to_pagebuf(true, buf, &ctigate_bitmask,
615 cfg->nr_ctm_channels);
616 return size;
617}
618static DEVICE_ATTR_RW(chan_gate_enable);
619
620static ssize_t chan_gate_disable_store(struct device *dev,
621 struct device_attribute *attr,
622 const char *buf, size_t size)
623{
624 int err = 0, channel = 0;
625
626 if (kstrtoint(buf, 0, &channel))
627 return -EINVAL;
628
629 err = cti_channel_gate_op(dev, CTI_GATE_CHAN_DISABLE, channel);
630 return err ? err : size;
631}
632static DEVICE_ATTR_WO(chan_gate_disable);
633
634static int
635chan_op_parse(struct device *dev, enum cti_chan_set_op op, const char *buf)
636{
637 int err = 0, channel = 0;
638
639 if (kstrtoint(buf, 0, &channel))
640 return -EINVAL;
641
642 err = cti_channel_setop(dev, op, channel);
643 return err;
644
645}
646
647static ssize_t chan_set_store(struct device *dev,
648 struct device_attribute *attr,
649 const char *buf, size_t size)
650{
651 int err = chan_op_parse(dev, CTI_CHAN_SET, buf);
652
653 return err ? err : size;
654}
655static DEVICE_ATTR_WO(chan_set);
656
657static ssize_t chan_clear_store(struct device *dev,
658 struct device_attribute *attr,
659 const char *buf, size_t size)
660{
661 int err = chan_op_parse(dev, CTI_CHAN_CLR, buf);
662
663 return err ? err : size;
664}
665static DEVICE_ATTR_WO(chan_clear);
666
667static ssize_t chan_pulse_store(struct device *dev,
668 struct device_attribute *attr,
669 const char *buf, size_t size)
670{
671 int err = chan_op_parse(dev, CTI_CHAN_PULSE, buf);
672
673 return err ? err : size;
674}
675static DEVICE_ATTR_WO(chan_pulse);
676
677static ssize_t trig_filter_enable_show(struct device *dev,
678 struct device_attribute *attr,
679 char *buf)
680{
681 u32 val;
682 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
683
684 spin_lock(&drvdata->spinlock);
685 val = drvdata->config.trig_filter_enable;
686 spin_unlock(&drvdata->spinlock);
687 return sprintf(buf, "%d\n", val);
688}
689
690static ssize_t trig_filter_enable_store(struct device *dev,
691 struct device_attribute *attr,
692 const char *buf, size_t size)
693{
694 unsigned long val;
695 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
696
697 if (kstrtoul(buf, 0, &val))
698 return -EINVAL;
699
700 spin_lock(&drvdata->spinlock);
701 drvdata->config.trig_filter_enable = !!val;
702 spin_unlock(&drvdata->spinlock);
703 return size;
704}
705static DEVICE_ATTR_RW(trig_filter_enable);
706
707static ssize_t trigout_filtered_show(struct device *dev,
708 struct device_attribute *attr,
709 char *buf)
710{
711 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
712 struct cti_config *cfg = &drvdata->config;
713 int size = 0, nr_trig_max = cfg->nr_trig_max;
714 unsigned long mask = cfg->trig_out_filter;
715
716 if (mask)
717 size = bitmap_print_to_pagebuf(true, buf, &mask, nr_trig_max);
718 return size;
719}
720static DEVICE_ATTR_RO(trigout_filtered);
721
722/* clear all xtrigger / channel programming */
723static ssize_t chan_xtrigs_reset_store(struct device *dev,
724 struct device_attribute *attr,
725 const char *buf, size_t size)
726{
727 int i;
728 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
729 struct cti_config *config = &drvdata->config;
730
731 spin_lock(&drvdata->spinlock);
732
733 /* clear the CTI trigger / channel programming registers */
734 for (i = 0; i < config->nr_trig_max; i++) {
735 config->ctiinen[i] = 0;
736 config->ctiouten[i] = 0;
737 }
738
739 /* clear the other regs */
740 config->ctigate = GENMASK(config->nr_ctm_channels - 1, 0);
741 config->asicctl = 0;
742 config->ctiappset = 0;
743 config->ctiinout_sel = 0;
744 config->xtrig_rchan_sel = 0;
745
746 /* if enabled then write through */
747 if (cti_active(config))
748 cti_write_all_hw_regs(drvdata);
749
750 spin_unlock(&drvdata->spinlock);
751 return size;
752}
753static DEVICE_ATTR_WO(chan_xtrigs_reset);
754
755/*
756 * Write to select a channel to view, read to display the
757 * cross triggers for the selected channel.
758 */
759static ssize_t chan_xtrigs_sel_store(struct device *dev,
760 struct device_attribute *attr,
761 const char *buf, size_t size)
762{
763 unsigned long val;
764 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
765
766 if (kstrtoul(buf, 0, &val))
767 return -EINVAL;
768 if (val > (drvdata->config.nr_ctm_channels - 1))
769 return -EINVAL;
770
771 spin_lock(&drvdata->spinlock);
772 drvdata->config.xtrig_rchan_sel = val;
773 spin_unlock(&drvdata->spinlock);
774 return size;
775}
776
777static ssize_t chan_xtrigs_sel_show(struct device *dev,
778 struct device_attribute *attr,
779 char *buf)
780{
781 unsigned long val;
782 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
783
784 spin_lock(&drvdata->spinlock);
785 val = drvdata->config.xtrig_rchan_sel;
786 spin_unlock(&drvdata->spinlock);
787
788 return sprintf(buf, "%ld\n", val);
789}
790static DEVICE_ATTR_RW(chan_xtrigs_sel);
791
792static ssize_t chan_xtrigs_in_show(struct device *dev,
793 struct device_attribute *attr,
794 char *buf)
795{
796 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
797 struct cti_config *cfg = &drvdata->config;
798 int used = 0, reg_idx;
799 int nr_trig_max = drvdata->config.nr_trig_max;
800 u32 chan_mask = BIT(cfg->xtrig_rchan_sel);
801
802 for (reg_idx = 0; reg_idx < nr_trig_max; reg_idx++) {
803 if (chan_mask & cfg->ctiinen[reg_idx])
804 used += sprintf(buf + used, "%d ", reg_idx);
805 }
806
807 used += sprintf(buf + used, "\n");
808 return used;
809}
810static DEVICE_ATTR_RO(chan_xtrigs_in);
811
812static ssize_t chan_xtrigs_out_show(struct device *dev,
813 struct device_attribute *attr,
814 char *buf)
815{
816 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
817 struct cti_config *cfg = &drvdata->config;
818 int used = 0, reg_idx;
819 int nr_trig_max = drvdata->config.nr_trig_max;
820 u32 chan_mask = BIT(cfg->xtrig_rchan_sel);
821
822 for (reg_idx = 0; reg_idx < nr_trig_max; reg_idx++) {
823 if (chan_mask & cfg->ctiouten[reg_idx])
824 used += sprintf(buf + used, "%d ", reg_idx);
825 }
826
827 used += sprintf(buf + used, "\n");
828 return used;
829}
830static DEVICE_ATTR_RO(chan_xtrigs_out);
831
832static ssize_t print_chan_list(struct device *dev,
833 char *buf, bool inuse)
834{
835 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
836 struct cti_config *config = &drvdata->config;
837 int size, i;
838 unsigned long inuse_bits = 0, chan_mask;
839
840 /* scan regs to get bitmap of channels in use. */
841 spin_lock(&drvdata->spinlock);
842 for (i = 0; i < config->nr_trig_max; i++) {
843 inuse_bits |= config->ctiinen[i];
844 inuse_bits |= config->ctiouten[i];
845 }
846 spin_unlock(&drvdata->spinlock);
847
848 /* inverse bits if printing free channels */
849 if (!inuse)
850 inuse_bits = ~inuse_bits;
851
852 /* list of channels, or 'none' */
853 chan_mask = GENMASK(config->nr_ctm_channels - 1, 0);
854 if (inuse_bits & chan_mask)
855 size = bitmap_print_to_pagebuf(true, buf, &inuse_bits,
856 config->nr_ctm_channels);
857 else
858 size = sprintf(buf, "\n");
859 return size;
860}
861
862static ssize_t chan_inuse_show(struct device *dev,
863 struct device_attribute *attr,
864 char *buf)
865{
866 return print_chan_list(dev, buf, true);
867}
868static DEVICE_ATTR_RO(chan_inuse);
869
870static ssize_t chan_free_show(struct device *dev,
871 struct device_attribute *attr,
872 char *buf)
873{
874 return print_chan_list(dev, buf, false);
875}
876static DEVICE_ATTR_RO(chan_free);
877
878static struct attribute *coresight_cti_channel_attrs[] = {
879 &dev_attr_trigin_attach.attr,
880 &dev_attr_trigin_detach.attr,
881 &dev_attr_trigout_attach.attr,
882 &dev_attr_trigout_detach.attr,
883 &dev_attr_trig_filter_enable.attr,
884 &dev_attr_trigout_filtered.attr,
885 &dev_attr_chan_gate_enable.attr,
886 &dev_attr_chan_gate_disable.attr,
887 &dev_attr_chan_set.attr,
888 &dev_attr_chan_clear.attr,
889 &dev_attr_chan_pulse.attr,
890 &dev_attr_chan_inuse.attr,
891 &dev_attr_chan_free.attr,
892 &dev_attr_chan_xtrigs_sel.attr,
893 &dev_attr_chan_xtrigs_in.attr,
894 &dev_attr_chan_xtrigs_out.attr,
895 &dev_attr_chan_xtrigs_reset.attr,
896 NULL,
897};
898
899/* Create the connections trigger groups and attrs dynamically */
900/*
901 * Each connection has dynamic group triggers<N> + name, trigin/out sigs/types
902 * attributes, + each device has static nr_trigger_cons giving the number
903 * of groups. e.g. in sysfs:-
904 * /cti_<name>/triggers0
905 * /cti_<name>/triggers1
906 * /cti_<name>/nr_trigger_cons
907 * where nr_trigger_cons = 2
908 */
909static ssize_t con_name_show(struct device *dev,
910 struct device_attribute *attr,
911 char *buf)
912{
913 struct dev_ext_attribute *ext_attr =
914 container_of(attr, struct dev_ext_attribute, attr);
915 struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
916
917 return sprintf(buf, "%s\n", con->con_dev_name);
918}
919
920static ssize_t trigin_sig_show(struct device *dev,
921 struct device_attribute *attr,
922 char *buf)
923{
924 struct dev_ext_attribute *ext_attr =
925 container_of(attr, struct dev_ext_attribute, attr);
926 struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
927 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
928 struct cti_config *cfg = &drvdata->config;
929 unsigned long mask = con->con_in->used_mask;
930
931 return bitmap_print_to_pagebuf(true, buf, &mask, cfg->nr_trig_max);
932}
933
934static ssize_t trigout_sig_show(struct device *dev,
935 struct device_attribute *attr,
936 char *buf)
937{
938 struct dev_ext_attribute *ext_attr =
939 container_of(attr, struct dev_ext_attribute, attr);
940 struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
941 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
942 struct cti_config *cfg = &drvdata->config;
943 unsigned long mask = con->con_out->used_mask;
944
945 return bitmap_print_to_pagebuf(true, buf, &mask, cfg->nr_trig_max);
946}
947
948/* convert a sig type id to a name */
949static const char *
950cti_sig_type_name(struct cti_trig_con *con, int used_count, bool in)
951{
952 int idx = 0;
953 struct cti_trig_grp *grp = in ? con->con_in : con->con_out;
954
955 if (used_count < grp->nr_sigs)
956 idx = grp->sig_types[used_count];
957 return sig_type_names[idx];
958}
959
960static ssize_t trigin_type_show(struct device *dev,
961 struct device_attribute *attr,
962 char *buf)
963{
964 struct dev_ext_attribute *ext_attr =
965 container_of(attr, struct dev_ext_attribute, attr);
966 struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
967 int sig_idx, used = 0;
968 const char *name;
969
970 for (sig_idx = 0; sig_idx < con->con_in->nr_sigs; sig_idx++) {
971 name = cti_sig_type_name(con, sig_idx, true);
972 used += sprintf(buf + used, "%s ", name);
973 }
974 used += sprintf(buf + used, "\n");
975 return used;
976}
977
978static ssize_t trigout_type_show(struct device *dev,
979 struct device_attribute *attr,
980 char *buf)
981{
982 struct dev_ext_attribute *ext_attr =
983 container_of(attr, struct dev_ext_attribute, attr);
984 struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
985 int sig_idx, used = 0;
986 const char *name;
987
988 for (sig_idx = 0; sig_idx < con->con_out->nr_sigs; sig_idx++) {
989 name = cti_sig_type_name(con, sig_idx, false);
990 used += sprintf(buf + used, "%s ", name);
991 }
992 used += sprintf(buf + used, "\n");
993 return used;
994}
995
996/*
997 * Array of show function names declared above to allow selection
998 * for the connection attributes
999 */
1000static p_show_fn show_fns[CTI_CON_ATTR_MAX] = {
1001 con_name_show,
1002 trigin_sig_show,
1003 trigout_sig_show,
1004 trigin_type_show,
1005 trigout_type_show,
1006};
1007
1008static int cti_create_con_sysfs_attr(struct device *dev,
1009 struct cti_trig_con *con,
1010 enum cti_conn_attr_type attr_type,
1011 int attr_idx)
1012{
1013 struct dev_ext_attribute *eattr;
1014 char *name;
1015
1016 eattr = devm_kzalloc(dev, sizeof(struct dev_ext_attribute),
1017 GFP_KERNEL);
1018 if (eattr) {
1019 name = devm_kstrdup(dev, con_attr_names[attr_type],
1020 GFP_KERNEL);
1021 if (name) {
1022 /* fill out the underlying attribute struct */
1023 eattr->attr.attr.name = name;
1024 eattr->attr.attr.mode = 0444;
1025
1026 /* now the device_attribute struct */
1027 eattr->attr.show = show_fns[attr_type];
1028 } else {
1029 return -ENOMEM;
1030 }
1031 } else {
1032 return -ENOMEM;
1033 }
1034 eattr->var = con;
1035 con->con_attrs[attr_idx] = &eattr->attr.attr;
1036 /*
1037 * Initialize the dynamically allocated attribute
1038 * to avoid LOCKDEP splat. See include/linux/sysfs.h
1039 * for more details.
1040 */
1041 sysfs_attr_init(con->con_attrs[attr_idx]);
1042
1043 return 0;
1044}
1045
1046static struct attribute_group *
1047cti_create_con_sysfs_group(struct device *dev, struct cti_device *ctidev,
1048 int con_idx, struct cti_trig_con *tc)
1049{
1050 struct attribute_group *group = NULL;
1051 int grp_idx;
1052
1053 group = devm_kzalloc(dev, sizeof(struct attribute_group), GFP_KERNEL);
1054 if (!group)
1055 return NULL;
1056
1057 group->name = devm_kasprintf(dev, GFP_KERNEL, "triggers%d", con_idx);
1058 if (!group->name)
1059 return NULL;
1060
1061 grp_idx = con_idx + CORESIGHT_CTI_STATIC_GROUPS_MAX - 1;
1062 ctidev->con_groups[grp_idx] = group;
1063 tc->attr_group = group;
1064 return group;
1065}
1066
1067/* create a triggers connection group and the attributes for that group */
1068static int cti_create_con_attr_set(struct device *dev, int con_idx,
1069 struct cti_device *ctidev,
1070 struct cti_trig_con *tc)
1071{
1072 struct attribute_group *attr_group = NULL;
1073 int attr_idx = 0;
1074 int err = -ENOMEM;
1075
1076 attr_group = cti_create_con_sysfs_group(dev, ctidev, con_idx, tc);
1077 if (!attr_group)
1078 return -ENOMEM;
1079
1080 /* allocate NULL terminated array of attributes */
1081 tc->con_attrs = devm_kcalloc(dev, CTI_CON_ATTR_MAX + 1,
1082 sizeof(struct attribute *), GFP_KERNEL);
1083 if (!tc->con_attrs)
1084 return -ENOMEM;
1085
1086 err = cti_create_con_sysfs_attr(dev, tc, CTI_CON_ATTR_NAME,
1087 attr_idx++);
1088 if (err)
1089 return err;
1090
1091 if (tc->con_in->nr_sigs > 0) {
1092 err = cti_create_con_sysfs_attr(dev, tc,
1093 CTI_CON_ATTR_TRIGIN_SIG,
1094 attr_idx++);
1095 if (err)
1096 return err;
1097
1098 err = cti_create_con_sysfs_attr(dev, tc,
1099 CTI_CON_ATTR_TRIGIN_TYPES,
1100 attr_idx++);
1101 if (err)
1102 return err;
1103 }
1104
1105 if (tc->con_out->nr_sigs > 0) {
1106 err = cti_create_con_sysfs_attr(dev, tc,
1107 CTI_CON_ATTR_TRIGOUT_SIG,
1108 attr_idx++);
1109 if (err)
1110 return err;
1111
1112 err = cti_create_con_sysfs_attr(dev, tc,
1113 CTI_CON_ATTR_TRIGOUT_TYPES,
1114 attr_idx++);
1115 if (err)
1116 return err;
1117 }
1118 attr_group->attrs = tc->con_attrs;
1119 return 0;
1120}
1121
1122/* create the array of group pointers for the CTI sysfs groups */
1123static int cti_create_cons_groups(struct device *dev, struct cti_device *ctidev)
1124{
1125 int nr_groups;
1126
1127 /* nr groups = dynamic + static + NULL terminator */
1128 nr_groups = ctidev->nr_trig_con + CORESIGHT_CTI_STATIC_GROUPS_MAX;
1129 ctidev->con_groups = devm_kcalloc(dev, nr_groups,
1130 sizeof(struct attribute_group *),
1131 GFP_KERNEL);
1132 if (!ctidev->con_groups)
1133 return -ENOMEM;
1134 return 0;
1135}
1136
1137int cti_create_cons_sysfs(struct device *dev, struct cti_drvdata *drvdata)
1138{
1139 struct cti_device *ctidev = &drvdata->ctidev;
1140 int err, con_idx = 0, i;
1141 struct cti_trig_con *tc;
1142
1143 err = cti_create_cons_groups(dev, ctidev);
1144 if (err)
1145 return err;
1146
1147 /* populate first locations with the static set of groups */
1148 for (i = 0; i < (CORESIGHT_CTI_STATIC_GROUPS_MAX - 1); i++)
1149 ctidev->con_groups[i] = coresight_cti_groups[i];
1150
1151 /* add dynamic set for each connection */
1152 list_for_each_entry(tc, &ctidev->trig_cons, node) {
1153 err = cti_create_con_attr_set(dev, con_idx++, ctidev, tc);
1154 if (err)
1155 break;
1156 }
1157 return err;
1158}
1159
1160/* attribute and group sysfs tables. */
1161static const struct attribute_group coresight_cti_group = {
1162 .attrs = coresight_cti_attrs,
1163};
1164
1165static const struct attribute_group coresight_cti_mgmt_group = {
1166 .attrs = coresight_cti_mgmt_attrs,
1167 .name = "mgmt",
1168};
1169
1170static const struct attribute_group coresight_cti_regs_group = {
1171 .attrs = coresight_cti_regs_attrs,
1172 .name = "regs",
1173};
1174
1175static const struct attribute_group coresight_cti_channels_group = {
1176 .attrs = coresight_cti_channel_attrs,
1177 .name = "channels",
1178};
1179
1180const struct attribute_group *
1181coresight_cti_groups[CORESIGHT_CTI_STATIC_GROUPS_MAX] = {
1182 &coresight_cti_group,
1183 &coresight_cti_mgmt_group,
1184 &coresight_cti_regs_group,
1185 &coresight_cti_channels_group,
1186 NULL,
1187};
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2019 Linaro Limited, All rights reserved.
4 * Author: Mike Leach <mike.leach@linaro.org>
5 */
6
7#include <linux/atomic.h>
8#include <linux/coresight.h>
9#include <linux/device.h>
10#include <linux/io.h>
11#include <linux/kernel.h>
12#include <linux/spinlock.h>
13#include <linux/sysfs.h>
14
15#include "coresight-cti.h"
16
17/*
18 * Declare the number of static declared attribute groups
19 * Value includes groups + NULL value at end of table.
20 */
21#define CORESIGHT_CTI_STATIC_GROUPS_MAX 5
22
23/*
24 * List of trigger signal type names. Match the constants declared in
25 * include\dt-bindings\arm\coresight-cti-dt.h
26 */
27static const char * const sig_type_names[] = {
28 "genio", /* GEN_IO */
29 "intreq", /* GEN_INTREQ */
30 "intack", /* GEN_INTACK */
31 "haltreq", /* GEN_HALTREQ */
32 "restartreq", /* GEN_RESTARTREQ */
33 "pe_edbgreq", /* PE_EDBGREQ */
34 "pe_dbgrestart",/* PE_DBGRESTART */
35 "pe_ctiirq", /* PE_CTIIRQ */
36 "pe_pmuirq", /* PE_PMUIRQ */
37 "pe_dbgtrigger",/* PE_DBGTRIGGER */
38 "etm_extout", /* ETM_EXTOUT */
39 "etm_extin", /* ETM_EXTIN */
40 "snk_full", /* SNK_FULL */
41 "snk_acqcomp", /* SNK_ACQCOMP */
42 "snk_flushcomp",/* SNK_FLUSHCOMP */
43 "snk_flushin", /* SNK_FLUSHIN */
44 "snk_trigin", /* SNK_TRIGIN */
45 "stm_asyncout", /* STM_ASYNCOUT */
46 "stm_tout_spte",/* STM_TOUT_SPTE */
47 "stm_tout_sw", /* STM_TOUT_SW */
48 "stm_tout_hete",/* STM_TOUT_HETE */
49 "stm_hwevent", /* STM_HWEVENT */
50 "ela_tstart", /* ELA_TSTART */
51 "ela_tstop", /* ELA_TSTOP */
52 "ela_dbgreq", /* ELA_DBGREQ */
53};
54
55/* Show function pointer used in the connections dynamic declared attributes*/
56typedef ssize_t (*p_show_fn)(struct device *dev, struct device_attribute *attr,
57 char *buf);
58
59/* Connection attribute types */
60enum cti_conn_attr_type {
61 CTI_CON_ATTR_NAME,
62 CTI_CON_ATTR_TRIGIN_SIG,
63 CTI_CON_ATTR_TRIGOUT_SIG,
64 CTI_CON_ATTR_TRIGIN_TYPES,
65 CTI_CON_ATTR_TRIGOUT_TYPES,
66 CTI_CON_ATTR_MAX,
67};
68
69/* Names for the connection attributes */
70static const char * const con_attr_names[CTI_CON_ATTR_MAX] = {
71 "name",
72 "in_signals",
73 "out_signals",
74 "in_types",
75 "out_types",
76};
77
78/* basic attributes */
79static ssize_t enable_show(struct device *dev,
80 struct device_attribute *attr,
81 char *buf)
82{
83 int enable_req;
84 bool enabled, powered;
85 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
86
87 enable_req = atomic_read(&drvdata->config.enable_req_count);
88 spin_lock(&drvdata->spinlock);
89 powered = drvdata->config.hw_powered;
90 enabled = drvdata->config.hw_enabled;
91 spin_unlock(&drvdata->spinlock);
92
93 if (powered)
94 return sprintf(buf, "%d\n", enabled);
95 else
96 return sprintf(buf, "%d\n", !!enable_req);
97}
98
99static ssize_t enable_store(struct device *dev,
100 struct device_attribute *attr,
101 const char *buf, size_t size)
102{
103 int ret = 0;
104 unsigned long val;
105 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
106
107 ret = kstrtoul(buf, 0, &val);
108 if (ret)
109 return ret;
110
111 if (val)
112 ret = cti_enable(drvdata->csdev);
113 else
114 ret = cti_disable(drvdata->csdev);
115 if (ret)
116 return ret;
117 return size;
118}
119static DEVICE_ATTR_RW(enable);
120
121static ssize_t powered_show(struct device *dev,
122 struct device_attribute *attr,
123 char *buf)
124{
125 bool powered;
126 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
127
128 spin_lock(&drvdata->spinlock);
129 powered = drvdata->config.hw_powered;
130 spin_unlock(&drvdata->spinlock);
131
132 return sprintf(buf, "%d\n", powered);
133}
134static DEVICE_ATTR_RO(powered);
135
136static ssize_t ctmid_show(struct device *dev,
137 struct device_attribute *attr, char *buf)
138{
139 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
140
141 return sprintf(buf, "%d\n", drvdata->ctidev.ctm_id);
142}
143static DEVICE_ATTR_RO(ctmid);
144
145static ssize_t nr_trigger_cons_show(struct device *dev,
146 struct device_attribute *attr,
147 char *buf)
148{
149 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
150
151 return sprintf(buf, "%d\n", drvdata->ctidev.nr_trig_con);
152}
153static DEVICE_ATTR_RO(nr_trigger_cons);
154
155/* attribute and group sysfs tables. */
156static struct attribute *coresight_cti_attrs[] = {
157 &dev_attr_enable.attr,
158 &dev_attr_powered.attr,
159 &dev_attr_ctmid.attr,
160 &dev_attr_nr_trigger_cons.attr,
161 NULL,
162};
163
164/* register based attributes */
165
166/* macro to access RO registers with power check only (no enable check). */
167#define coresight_cti_reg(name, offset) \
168static ssize_t name##_show(struct device *dev, \
169 struct device_attribute *attr, char *buf) \
170{ \
171 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
172 u32 val = 0; \
173 pm_runtime_get_sync(dev->parent); \
174 spin_lock(&drvdata->spinlock); \
175 if (drvdata->config.hw_powered) \
176 val = readl_relaxed(drvdata->base + offset); \
177 spin_unlock(&drvdata->spinlock); \
178 pm_runtime_put_sync(dev->parent); \
179 return sprintf(buf, "0x%x\n", val); \
180} \
181static DEVICE_ATTR_RO(name)
182
183/* coresight management registers */
184coresight_cti_reg(devaff0, CTIDEVAFF0);
185coresight_cti_reg(devaff1, CTIDEVAFF1);
186coresight_cti_reg(authstatus, CORESIGHT_AUTHSTATUS);
187coresight_cti_reg(devarch, CORESIGHT_DEVARCH);
188coresight_cti_reg(devid, CORESIGHT_DEVID);
189coresight_cti_reg(devtype, CORESIGHT_DEVTYPE);
190coresight_cti_reg(pidr0, CORESIGHT_PERIPHIDR0);
191coresight_cti_reg(pidr1, CORESIGHT_PERIPHIDR1);
192coresight_cti_reg(pidr2, CORESIGHT_PERIPHIDR2);
193coresight_cti_reg(pidr3, CORESIGHT_PERIPHIDR3);
194coresight_cti_reg(pidr4, CORESIGHT_PERIPHIDR4);
195
196static struct attribute *coresight_cti_mgmt_attrs[] = {
197 &dev_attr_devaff0.attr,
198 &dev_attr_devaff1.attr,
199 &dev_attr_authstatus.attr,
200 &dev_attr_devarch.attr,
201 &dev_attr_devid.attr,
202 &dev_attr_devtype.attr,
203 &dev_attr_pidr0.attr,
204 &dev_attr_pidr1.attr,
205 &dev_attr_pidr2.attr,
206 &dev_attr_pidr3.attr,
207 &dev_attr_pidr4.attr,
208 NULL,
209};
210
211/* CTI low level programming registers */
212
213/*
214 * Show a simple 32 bit value if enabled and powered.
215 * If inaccessible & pcached_val not NULL then show cached value.
216 */
217static ssize_t cti_reg32_show(struct device *dev, char *buf,
218 u32 *pcached_val, int reg_offset)
219{
220 u32 val = 0;
221 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
222 struct cti_config *config = &drvdata->config;
223
224 spin_lock(&drvdata->spinlock);
225 if ((reg_offset >= 0) && cti_active(config)) {
226 CS_UNLOCK(drvdata->base);
227 val = readl_relaxed(drvdata->base + reg_offset);
228 if (pcached_val)
229 *pcached_val = val;
230 CS_LOCK(drvdata->base);
231 } else if (pcached_val) {
232 val = *pcached_val;
233 }
234 spin_unlock(&drvdata->spinlock);
235 return sprintf(buf, "%#x\n", val);
236}
237
238/*
239 * Store a simple 32 bit value.
240 * If pcached_val not NULL, then copy to here too,
241 * if reg_offset >= 0 then write through if enabled.
242 */
243static ssize_t cti_reg32_store(struct device *dev, const char *buf,
244 size_t size, u32 *pcached_val, int reg_offset)
245{
246 unsigned long val;
247 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
248 struct cti_config *config = &drvdata->config;
249
250 if (kstrtoul(buf, 0, &val))
251 return -EINVAL;
252
253 spin_lock(&drvdata->spinlock);
254 /* local store */
255 if (pcached_val)
256 *pcached_val = (u32)val;
257
258 /* write through if offset and enabled */
259 if ((reg_offset >= 0) && cti_active(config))
260 cti_write_single_reg(drvdata, reg_offset, val);
261 spin_unlock(&drvdata->spinlock);
262 return size;
263}
264
265/* Standard macro for simple rw cti config registers */
266#define cti_config_reg32_rw(name, cfgname, offset) \
267static ssize_t name##_show(struct device *dev, \
268 struct device_attribute *attr, \
269 char *buf) \
270{ \
271 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
272 return cti_reg32_show(dev, buf, \
273 &drvdata->config.cfgname, offset); \
274} \
275 \
276static ssize_t name##_store(struct device *dev, \
277 struct device_attribute *attr, \
278 const char *buf, size_t size) \
279{ \
280 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
281 return cti_reg32_store(dev, buf, size, \
282 &drvdata->config.cfgname, offset); \
283} \
284static DEVICE_ATTR_RW(name)
285
286static ssize_t inout_sel_show(struct device *dev,
287 struct device_attribute *attr,
288 char *buf)
289{
290 u32 val;
291 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
292
293 val = (u32)drvdata->config.ctiinout_sel;
294 return sprintf(buf, "%d\n", val);
295}
296
297static ssize_t inout_sel_store(struct device *dev,
298 struct device_attribute *attr,
299 const char *buf, size_t size)
300{
301 unsigned long val;
302 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
303
304 if (kstrtoul(buf, 0, &val))
305 return -EINVAL;
306 if (val > (CTIINOUTEN_MAX - 1))
307 return -EINVAL;
308
309 spin_lock(&drvdata->spinlock);
310 drvdata->config.ctiinout_sel = val;
311 spin_unlock(&drvdata->spinlock);
312 return size;
313}
314static DEVICE_ATTR_RW(inout_sel);
315
316static ssize_t inen_show(struct device *dev,
317 struct device_attribute *attr,
318 char *buf)
319{
320 unsigned long val;
321 int index;
322 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
323
324 spin_lock(&drvdata->spinlock);
325 index = drvdata->config.ctiinout_sel;
326 val = drvdata->config.ctiinen[index];
327 spin_unlock(&drvdata->spinlock);
328 return sprintf(buf, "%#lx\n", val);
329}
330
331static ssize_t inen_store(struct device *dev,
332 struct device_attribute *attr,
333 const char *buf, size_t size)
334{
335 unsigned long val;
336 int index;
337 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
338 struct cti_config *config = &drvdata->config;
339
340 if (kstrtoul(buf, 0, &val))
341 return -EINVAL;
342
343 spin_lock(&drvdata->spinlock);
344 index = config->ctiinout_sel;
345 config->ctiinen[index] = val;
346
347 /* write through if enabled */
348 if (cti_active(config))
349 cti_write_single_reg(drvdata, CTIINEN(index), val);
350 spin_unlock(&drvdata->spinlock);
351 return size;
352}
353static DEVICE_ATTR_RW(inen);
354
355static ssize_t outen_show(struct device *dev,
356 struct device_attribute *attr,
357 char *buf)
358{
359 unsigned long val;
360 int index;
361 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
362
363 spin_lock(&drvdata->spinlock);
364 index = drvdata->config.ctiinout_sel;
365 val = drvdata->config.ctiouten[index];
366 spin_unlock(&drvdata->spinlock);
367 return sprintf(buf, "%#lx\n", val);
368}
369
370static ssize_t outen_store(struct device *dev,
371 struct device_attribute *attr,
372 const char *buf, size_t size)
373{
374 unsigned long val;
375 int index;
376 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
377 struct cti_config *config = &drvdata->config;
378
379 if (kstrtoul(buf, 0, &val))
380 return -EINVAL;
381
382 spin_lock(&drvdata->spinlock);
383 index = config->ctiinout_sel;
384 config->ctiouten[index] = val;
385
386 /* write through if enabled */
387 if (cti_active(config))
388 cti_write_single_reg(drvdata, CTIOUTEN(index), val);
389 spin_unlock(&drvdata->spinlock);
390 return size;
391}
392static DEVICE_ATTR_RW(outen);
393
394static ssize_t intack_store(struct device *dev,
395 struct device_attribute *attr,
396 const char *buf, size_t size)
397{
398 unsigned long val;
399
400 if (kstrtoul(buf, 0, &val))
401 return -EINVAL;
402
403 cti_write_intack(dev, val);
404 return size;
405}
406static DEVICE_ATTR_WO(intack);
407
408cti_config_reg32_rw(gate, ctigate, CTIGATE);
409cti_config_reg32_rw(asicctl, asicctl, ASICCTL);
410cti_config_reg32_rw(appset, ctiappset, CTIAPPSET);
411
412static ssize_t appclear_store(struct device *dev,
413 struct device_attribute *attr,
414 const char *buf, size_t size)
415{
416 unsigned long val;
417 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
418 struct cti_config *config = &drvdata->config;
419
420 if (kstrtoul(buf, 0, &val))
421 return -EINVAL;
422
423 spin_lock(&drvdata->spinlock);
424
425 /* a 1'b1 in appclr clears down the same bit in appset*/
426 config->ctiappset &= ~val;
427
428 /* write through if enabled */
429 if (cti_active(config))
430 cti_write_single_reg(drvdata, CTIAPPCLEAR, val);
431 spin_unlock(&drvdata->spinlock);
432 return size;
433}
434static DEVICE_ATTR_WO(appclear);
435
436static ssize_t apppulse_store(struct device *dev,
437 struct device_attribute *attr,
438 const char *buf, size_t size)
439{
440 unsigned long val;
441 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
442 struct cti_config *config = &drvdata->config;
443
444 if (kstrtoul(buf, 0, &val))
445 return -EINVAL;
446
447 spin_lock(&drvdata->spinlock);
448
449 /* write through if enabled */
450 if (cti_active(config))
451 cti_write_single_reg(drvdata, CTIAPPPULSE, val);
452 spin_unlock(&drvdata->spinlock);
453 return size;
454}
455static DEVICE_ATTR_WO(apppulse);
456
457coresight_cti_reg(triginstatus, CTITRIGINSTATUS);
458coresight_cti_reg(trigoutstatus, CTITRIGOUTSTATUS);
459coresight_cti_reg(chinstatus, CTICHINSTATUS);
460coresight_cti_reg(choutstatus, CTICHOUTSTATUS);
461
462/*
463 * Define CONFIG_CORESIGHT_CTI_INTEGRATION_REGS to enable the access to the
464 * integration control registers. Normally only used to investigate connection
465 * data.
466 */
467#ifdef CONFIG_CORESIGHT_CTI_INTEGRATION_REGS
468
469/* macro to access RW registers with power check only (no enable check). */
470#define coresight_cti_reg_rw(name, offset) \
471static ssize_t name##_show(struct device *dev, \
472 struct device_attribute *attr, char *buf) \
473{ \
474 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
475 u32 val = 0; \
476 pm_runtime_get_sync(dev->parent); \
477 spin_lock(&drvdata->spinlock); \
478 if (drvdata->config.hw_powered) \
479 val = readl_relaxed(drvdata->base + offset); \
480 spin_unlock(&drvdata->spinlock); \
481 pm_runtime_put_sync(dev->parent); \
482 return sprintf(buf, "0x%x\n", val); \
483} \
484 \
485static ssize_t name##_store(struct device *dev, \
486 struct device_attribute *attr, \
487 const char *buf, size_t size) \
488{ \
489 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
490 unsigned long val = 0; \
491 if (kstrtoul(buf, 0, &val)) \
492 return -EINVAL; \
493 \
494 pm_runtime_get_sync(dev->parent); \
495 spin_lock(&drvdata->spinlock); \
496 if (drvdata->config.hw_powered) \
497 cti_write_single_reg(drvdata, offset, val); \
498 spin_unlock(&drvdata->spinlock); \
499 pm_runtime_put_sync(dev->parent); \
500 return size; \
501} \
502static DEVICE_ATTR_RW(name)
503
504/* macro to access WO registers with power check only (no enable check). */
505#define coresight_cti_reg_wo(name, offset) \
506static ssize_t name##_store(struct device *dev, \
507 struct device_attribute *attr, \
508 const char *buf, size_t size) \
509{ \
510 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
511 unsigned long val = 0; \
512 if (kstrtoul(buf, 0, &val)) \
513 return -EINVAL; \
514 \
515 pm_runtime_get_sync(dev->parent); \
516 spin_lock(&drvdata->spinlock); \
517 if (drvdata->config.hw_powered) \
518 cti_write_single_reg(drvdata, offset, val); \
519 spin_unlock(&drvdata->spinlock); \
520 pm_runtime_put_sync(dev->parent); \
521 return size; \
522} \
523static DEVICE_ATTR_WO(name)
524
525coresight_cti_reg_rw(itchout, ITCHOUT);
526coresight_cti_reg_rw(ittrigout, ITTRIGOUT);
527coresight_cti_reg_rw(itctrl, CORESIGHT_ITCTRL);
528coresight_cti_reg_wo(itchinack, ITCHINACK);
529coresight_cti_reg_wo(ittriginack, ITTRIGINACK);
530coresight_cti_reg(ittrigin, ITTRIGIN);
531coresight_cti_reg(itchin, ITCHIN);
532coresight_cti_reg(itchoutack, ITCHOUTACK);
533coresight_cti_reg(ittrigoutack, ITTRIGOUTACK);
534
535#endif /* CORESIGHT_CTI_INTEGRATION_REGS */
536
537static struct attribute *coresight_cti_regs_attrs[] = {
538 &dev_attr_inout_sel.attr,
539 &dev_attr_inen.attr,
540 &dev_attr_outen.attr,
541 &dev_attr_gate.attr,
542 &dev_attr_asicctl.attr,
543 &dev_attr_intack.attr,
544 &dev_attr_appset.attr,
545 &dev_attr_appclear.attr,
546 &dev_attr_apppulse.attr,
547 &dev_attr_triginstatus.attr,
548 &dev_attr_trigoutstatus.attr,
549 &dev_attr_chinstatus.attr,
550 &dev_attr_choutstatus.attr,
551#ifdef CONFIG_CORESIGHT_CTI_INTEGRATION_REGS
552 &dev_attr_itctrl.attr,
553 &dev_attr_ittrigin.attr,
554 &dev_attr_itchin.attr,
555 &dev_attr_ittrigout.attr,
556 &dev_attr_itchout.attr,
557 &dev_attr_itchoutack.attr,
558 &dev_attr_ittrigoutack.attr,
559 &dev_attr_ittriginack.attr,
560 &dev_attr_itchinack.attr,
561#endif
562 NULL,
563};
564
565/* CTI channel x-trigger programming */
566static int
567cti_trig_op_parse(struct device *dev, enum cti_chan_op op,
568 enum cti_trig_dir dir, const char *buf, size_t size)
569{
570 u32 chan_idx;
571 u32 trig_idx;
572 int items, err = -EINVAL;
573
574 /* extract chan idx and trigger idx */
575 items = sscanf(buf, "%d %d", &chan_idx, &trig_idx);
576 if (items == 2) {
577 err = cti_channel_trig_op(dev, op, dir, chan_idx, trig_idx);
578 if (!err)
579 err = size;
580 }
581 return err;
582}
583
584static ssize_t trigin_attach_store(struct device *dev,
585 struct device_attribute *attr,
586 const char *buf, size_t size)
587{
588 return cti_trig_op_parse(dev, CTI_CHAN_ATTACH, CTI_TRIG_IN,
589 buf, size);
590}
591static DEVICE_ATTR_WO(trigin_attach);
592
593static ssize_t trigin_detach_store(struct device *dev,
594 struct device_attribute *attr,
595 const char *buf, size_t size)
596{
597 return cti_trig_op_parse(dev, CTI_CHAN_DETACH, CTI_TRIG_IN,
598 buf, size);
599}
600static DEVICE_ATTR_WO(trigin_detach);
601
602static ssize_t trigout_attach_store(struct device *dev,
603 struct device_attribute *attr,
604 const char *buf, size_t size)
605{
606 return cti_trig_op_parse(dev, CTI_CHAN_ATTACH, CTI_TRIG_OUT,
607 buf, size);
608}
609static DEVICE_ATTR_WO(trigout_attach);
610
611static ssize_t trigout_detach_store(struct device *dev,
612 struct device_attribute *attr,
613 const char *buf, size_t size)
614{
615 return cti_trig_op_parse(dev, CTI_CHAN_DETACH, CTI_TRIG_OUT,
616 buf, size);
617}
618static DEVICE_ATTR_WO(trigout_detach);
619
620
621static ssize_t chan_gate_enable_store(struct device *dev,
622 struct device_attribute *attr,
623 const char *buf, size_t size)
624{
625 int err = 0, channel = 0;
626
627 if (kstrtoint(buf, 0, &channel))
628 return -EINVAL;
629
630 err = cti_channel_gate_op(dev, CTI_GATE_CHAN_ENABLE, channel);
631 return err ? err : size;
632}
633
634static ssize_t chan_gate_enable_show(struct device *dev,
635 struct device_attribute *attr,
636 char *buf)
637{
638 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
639 struct cti_config *cfg = &drvdata->config;
640 unsigned long ctigate_bitmask = cfg->ctigate;
641 int size = 0;
642
643 if (cfg->ctigate == 0)
644 size = sprintf(buf, "\n");
645 else
646 size = bitmap_print_to_pagebuf(true, buf, &ctigate_bitmask,
647 cfg->nr_ctm_channels);
648 return size;
649}
650static DEVICE_ATTR_RW(chan_gate_enable);
651
652static ssize_t chan_gate_disable_store(struct device *dev,
653 struct device_attribute *attr,
654 const char *buf, size_t size)
655{
656 int err = 0, channel = 0;
657
658 if (kstrtoint(buf, 0, &channel))
659 return -EINVAL;
660
661 err = cti_channel_gate_op(dev, CTI_GATE_CHAN_DISABLE, channel);
662 return err ? err : size;
663}
664static DEVICE_ATTR_WO(chan_gate_disable);
665
666static int
667chan_op_parse(struct device *dev, enum cti_chan_set_op op, const char *buf)
668{
669 int err = 0, channel = 0;
670
671 if (kstrtoint(buf, 0, &channel))
672 return -EINVAL;
673
674 err = cti_channel_setop(dev, op, channel);
675 return err;
676
677}
678
679static ssize_t chan_set_store(struct device *dev,
680 struct device_attribute *attr,
681 const char *buf, size_t size)
682{
683 int err = chan_op_parse(dev, CTI_CHAN_SET, buf);
684
685 return err ? err : size;
686}
687static DEVICE_ATTR_WO(chan_set);
688
689static ssize_t chan_clear_store(struct device *dev,
690 struct device_attribute *attr,
691 const char *buf, size_t size)
692{
693 int err = chan_op_parse(dev, CTI_CHAN_CLR, buf);
694
695 return err ? err : size;
696}
697static DEVICE_ATTR_WO(chan_clear);
698
699static ssize_t chan_pulse_store(struct device *dev,
700 struct device_attribute *attr,
701 const char *buf, size_t size)
702{
703 int err = chan_op_parse(dev, CTI_CHAN_PULSE, buf);
704
705 return err ? err : size;
706}
707static DEVICE_ATTR_WO(chan_pulse);
708
709static ssize_t trig_filter_enable_show(struct device *dev,
710 struct device_attribute *attr,
711 char *buf)
712{
713 u32 val;
714 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
715
716 spin_lock(&drvdata->spinlock);
717 val = drvdata->config.trig_filter_enable;
718 spin_unlock(&drvdata->spinlock);
719 return sprintf(buf, "%d\n", val);
720}
721
722static ssize_t trig_filter_enable_store(struct device *dev,
723 struct device_attribute *attr,
724 const char *buf, size_t size)
725{
726 unsigned long val;
727 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
728
729 if (kstrtoul(buf, 0, &val))
730 return -EINVAL;
731
732 spin_lock(&drvdata->spinlock);
733 drvdata->config.trig_filter_enable = !!val;
734 spin_unlock(&drvdata->spinlock);
735 return size;
736}
737static DEVICE_ATTR_RW(trig_filter_enable);
738
739static ssize_t trigout_filtered_show(struct device *dev,
740 struct device_attribute *attr,
741 char *buf)
742{
743 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
744 struct cti_config *cfg = &drvdata->config;
745 int size = 0, nr_trig_max = cfg->nr_trig_max;
746 unsigned long mask = cfg->trig_out_filter;
747
748 if (mask)
749 size = bitmap_print_to_pagebuf(true, buf, &mask, nr_trig_max);
750 return size;
751}
752static DEVICE_ATTR_RO(trigout_filtered);
753
754/* clear all xtrigger / channel programming */
755static ssize_t chan_xtrigs_reset_store(struct device *dev,
756 struct device_attribute *attr,
757 const char *buf, size_t size)
758{
759 int i;
760 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
761 struct cti_config *config = &drvdata->config;
762
763 spin_lock(&drvdata->spinlock);
764
765 /* clear the CTI trigger / channel programming registers */
766 for (i = 0; i < config->nr_trig_max; i++) {
767 config->ctiinen[i] = 0;
768 config->ctiouten[i] = 0;
769 }
770
771 /* clear the other regs */
772 config->ctigate = GENMASK(config->nr_ctm_channels - 1, 0);
773 config->asicctl = 0;
774 config->ctiappset = 0;
775 config->ctiinout_sel = 0;
776 config->xtrig_rchan_sel = 0;
777
778 /* if enabled then write through */
779 if (cti_active(config))
780 cti_write_all_hw_regs(drvdata);
781
782 spin_unlock(&drvdata->spinlock);
783 return size;
784}
785static DEVICE_ATTR_WO(chan_xtrigs_reset);
786
787/*
788 * Write to select a channel to view, read to display the
789 * cross triggers for the selected channel.
790 */
791static ssize_t chan_xtrigs_sel_store(struct device *dev,
792 struct device_attribute *attr,
793 const char *buf, size_t size)
794{
795 unsigned long val;
796 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
797
798 if (kstrtoul(buf, 0, &val))
799 return -EINVAL;
800 if (val > (drvdata->config.nr_ctm_channels - 1))
801 return -EINVAL;
802
803 spin_lock(&drvdata->spinlock);
804 drvdata->config.xtrig_rchan_sel = val;
805 spin_unlock(&drvdata->spinlock);
806 return size;
807}
808
809static ssize_t chan_xtrigs_sel_show(struct device *dev,
810 struct device_attribute *attr,
811 char *buf)
812{
813 unsigned long val;
814 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
815
816 spin_lock(&drvdata->spinlock);
817 val = drvdata->config.xtrig_rchan_sel;
818 spin_unlock(&drvdata->spinlock);
819
820 return sprintf(buf, "%ld\n", val);
821}
822static DEVICE_ATTR_RW(chan_xtrigs_sel);
823
824static ssize_t chan_xtrigs_in_show(struct device *dev,
825 struct device_attribute *attr,
826 char *buf)
827{
828 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
829 struct cti_config *cfg = &drvdata->config;
830 int used = 0, reg_idx;
831 int nr_trig_max = drvdata->config.nr_trig_max;
832 u32 chan_mask = BIT(cfg->xtrig_rchan_sel);
833
834 for (reg_idx = 0; reg_idx < nr_trig_max; reg_idx++) {
835 if (chan_mask & cfg->ctiinen[reg_idx])
836 used += sprintf(buf + used, "%d ", reg_idx);
837 }
838
839 used += sprintf(buf + used, "\n");
840 return used;
841}
842static DEVICE_ATTR_RO(chan_xtrigs_in);
843
844static ssize_t chan_xtrigs_out_show(struct device *dev,
845 struct device_attribute *attr,
846 char *buf)
847{
848 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
849 struct cti_config *cfg = &drvdata->config;
850 int used = 0, reg_idx;
851 int nr_trig_max = drvdata->config.nr_trig_max;
852 u32 chan_mask = BIT(cfg->xtrig_rchan_sel);
853
854 for (reg_idx = 0; reg_idx < nr_trig_max; reg_idx++) {
855 if (chan_mask & cfg->ctiouten[reg_idx])
856 used += sprintf(buf + used, "%d ", reg_idx);
857 }
858
859 used += sprintf(buf + used, "\n");
860 return used;
861}
862static DEVICE_ATTR_RO(chan_xtrigs_out);
863
864static ssize_t print_chan_list(struct device *dev,
865 char *buf, bool inuse)
866{
867 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
868 struct cti_config *config = &drvdata->config;
869 int size, i;
870 unsigned long inuse_bits = 0, chan_mask;
871
872 /* scan regs to get bitmap of channels in use. */
873 spin_lock(&drvdata->spinlock);
874 for (i = 0; i < config->nr_trig_max; i++) {
875 inuse_bits |= config->ctiinen[i];
876 inuse_bits |= config->ctiouten[i];
877 }
878 spin_unlock(&drvdata->spinlock);
879
880 /* inverse bits if printing free channels */
881 if (!inuse)
882 inuse_bits = ~inuse_bits;
883
884 /* list of channels, or 'none' */
885 chan_mask = GENMASK(config->nr_ctm_channels - 1, 0);
886 if (inuse_bits & chan_mask)
887 size = bitmap_print_to_pagebuf(true, buf, &inuse_bits,
888 config->nr_ctm_channels);
889 else
890 size = sprintf(buf, "\n");
891 return size;
892}
893
894static ssize_t chan_inuse_show(struct device *dev,
895 struct device_attribute *attr,
896 char *buf)
897{
898 return print_chan_list(dev, buf, true);
899}
900static DEVICE_ATTR_RO(chan_inuse);
901
902static ssize_t chan_free_show(struct device *dev,
903 struct device_attribute *attr,
904 char *buf)
905{
906 return print_chan_list(dev, buf, false);
907}
908static DEVICE_ATTR_RO(chan_free);
909
910static struct attribute *coresight_cti_channel_attrs[] = {
911 &dev_attr_trigin_attach.attr,
912 &dev_attr_trigin_detach.attr,
913 &dev_attr_trigout_attach.attr,
914 &dev_attr_trigout_detach.attr,
915 &dev_attr_trig_filter_enable.attr,
916 &dev_attr_trigout_filtered.attr,
917 &dev_attr_chan_gate_enable.attr,
918 &dev_attr_chan_gate_disable.attr,
919 &dev_attr_chan_set.attr,
920 &dev_attr_chan_clear.attr,
921 &dev_attr_chan_pulse.attr,
922 &dev_attr_chan_inuse.attr,
923 &dev_attr_chan_free.attr,
924 &dev_attr_chan_xtrigs_sel.attr,
925 &dev_attr_chan_xtrigs_in.attr,
926 &dev_attr_chan_xtrigs_out.attr,
927 &dev_attr_chan_xtrigs_reset.attr,
928 NULL,
929};
930
931/* Create the connections trigger groups and attrs dynamically */
932/*
933 * Each connection has dynamic group triggers<N> + name, trigin/out sigs/types
934 * attributes, + each device has static nr_trigger_cons giving the number
935 * of groups. e.g. in sysfs:-
936 * /cti_<name>/triggers0
937 * /cti_<name>/triggers1
938 * /cti_<name>/nr_trigger_cons
939 * where nr_trigger_cons = 2
940 */
941static ssize_t con_name_show(struct device *dev,
942 struct device_attribute *attr,
943 char *buf)
944{
945 struct dev_ext_attribute *ext_attr =
946 container_of(attr, struct dev_ext_attribute, attr);
947 struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
948
949 return sprintf(buf, "%s\n", con->con_dev_name);
950}
951
952static ssize_t trigin_sig_show(struct device *dev,
953 struct device_attribute *attr,
954 char *buf)
955{
956 struct dev_ext_attribute *ext_attr =
957 container_of(attr, struct dev_ext_attribute, attr);
958 struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
959 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
960 struct cti_config *cfg = &drvdata->config;
961 unsigned long mask = con->con_in->used_mask;
962
963 return bitmap_print_to_pagebuf(true, buf, &mask, cfg->nr_trig_max);
964}
965
966static ssize_t trigout_sig_show(struct device *dev,
967 struct device_attribute *attr,
968 char *buf)
969{
970 struct dev_ext_attribute *ext_attr =
971 container_of(attr, struct dev_ext_attribute, attr);
972 struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
973 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
974 struct cti_config *cfg = &drvdata->config;
975 unsigned long mask = con->con_out->used_mask;
976
977 return bitmap_print_to_pagebuf(true, buf, &mask, cfg->nr_trig_max);
978}
979
980/* convert a sig type id to a name */
981static const char *
982cti_sig_type_name(struct cti_trig_con *con, int used_count, bool in)
983{
984 int idx = 0;
985 struct cti_trig_grp *grp = in ? con->con_in : con->con_out;
986
987 if (used_count < grp->nr_sigs)
988 idx = grp->sig_types[used_count];
989 return sig_type_names[idx];
990}
991
992static ssize_t trigin_type_show(struct device *dev,
993 struct device_attribute *attr,
994 char *buf)
995{
996 struct dev_ext_attribute *ext_attr =
997 container_of(attr, struct dev_ext_attribute, attr);
998 struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
999 int sig_idx, used = 0;
1000 const char *name;
1001
1002 for (sig_idx = 0; sig_idx < con->con_in->nr_sigs; sig_idx++) {
1003 name = cti_sig_type_name(con, sig_idx, true);
1004 used += sprintf(buf + used, "%s ", name);
1005 }
1006 used += sprintf(buf + used, "\n");
1007 return used;
1008}
1009
1010static ssize_t trigout_type_show(struct device *dev,
1011 struct device_attribute *attr,
1012 char *buf)
1013{
1014 struct dev_ext_attribute *ext_attr =
1015 container_of(attr, struct dev_ext_attribute, attr);
1016 struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
1017 int sig_idx, used = 0;
1018 const char *name;
1019
1020 for (sig_idx = 0; sig_idx < con->con_out->nr_sigs; sig_idx++) {
1021 name = cti_sig_type_name(con, sig_idx, false);
1022 used += sprintf(buf + used, "%s ", name);
1023 }
1024 used += sprintf(buf + used, "\n");
1025 return used;
1026}
1027
1028/*
1029 * Array of show function names declared above to allow selection
1030 * for the connection attributes
1031 */
1032static p_show_fn show_fns[CTI_CON_ATTR_MAX] = {
1033 con_name_show,
1034 trigin_sig_show,
1035 trigout_sig_show,
1036 trigin_type_show,
1037 trigout_type_show,
1038};
1039
1040static int cti_create_con_sysfs_attr(struct device *dev,
1041 struct cti_trig_con *con,
1042 enum cti_conn_attr_type attr_type,
1043 int attr_idx)
1044{
1045 struct dev_ext_attribute *eattr;
1046 char *name;
1047
1048 eattr = devm_kzalloc(dev, sizeof(struct dev_ext_attribute),
1049 GFP_KERNEL);
1050 if (eattr) {
1051 name = devm_kstrdup(dev, con_attr_names[attr_type],
1052 GFP_KERNEL);
1053 if (name) {
1054 /* fill out the underlying attribute struct */
1055 eattr->attr.attr.name = name;
1056 eattr->attr.attr.mode = 0444;
1057
1058 /* now the device_attribute struct */
1059 eattr->attr.show = show_fns[attr_type];
1060 } else {
1061 return -ENOMEM;
1062 }
1063 } else {
1064 return -ENOMEM;
1065 }
1066 eattr->var = con;
1067 con->con_attrs[attr_idx] = &eattr->attr.attr;
1068 return 0;
1069}
1070
1071static struct attribute_group *
1072cti_create_con_sysfs_group(struct device *dev, struct cti_device *ctidev,
1073 int con_idx, struct cti_trig_con *tc)
1074{
1075 struct attribute_group *group = NULL;
1076 int grp_idx;
1077
1078 group = devm_kzalloc(dev, sizeof(struct attribute_group), GFP_KERNEL);
1079 if (!group)
1080 return NULL;
1081
1082 group->name = devm_kasprintf(dev, GFP_KERNEL, "triggers%d", con_idx);
1083 if (!group->name)
1084 return NULL;
1085
1086 grp_idx = con_idx + CORESIGHT_CTI_STATIC_GROUPS_MAX - 1;
1087 ctidev->con_groups[grp_idx] = group;
1088 tc->attr_group = group;
1089 return group;
1090}
1091
1092/* create a triggers connection group and the attributes for that group */
1093static int cti_create_con_attr_set(struct device *dev, int con_idx,
1094 struct cti_device *ctidev,
1095 struct cti_trig_con *tc)
1096{
1097 struct attribute_group *attr_group = NULL;
1098 int attr_idx = 0;
1099 int err = -ENOMEM;
1100
1101 attr_group = cti_create_con_sysfs_group(dev, ctidev, con_idx, tc);
1102 if (!attr_group)
1103 return -ENOMEM;
1104
1105 /* allocate NULL terminated array of attributes */
1106 tc->con_attrs = devm_kcalloc(dev, CTI_CON_ATTR_MAX + 1,
1107 sizeof(struct attribute *), GFP_KERNEL);
1108 if (!tc->con_attrs)
1109 return -ENOMEM;
1110
1111 err = cti_create_con_sysfs_attr(dev, tc, CTI_CON_ATTR_NAME,
1112 attr_idx++);
1113 if (err)
1114 return err;
1115
1116 if (tc->con_in->nr_sigs > 0) {
1117 err = cti_create_con_sysfs_attr(dev, tc,
1118 CTI_CON_ATTR_TRIGIN_SIG,
1119 attr_idx++);
1120 if (err)
1121 return err;
1122
1123 err = cti_create_con_sysfs_attr(dev, tc,
1124 CTI_CON_ATTR_TRIGIN_TYPES,
1125 attr_idx++);
1126 if (err)
1127 return err;
1128 }
1129
1130 if (tc->con_out->nr_sigs > 0) {
1131 err = cti_create_con_sysfs_attr(dev, tc,
1132 CTI_CON_ATTR_TRIGOUT_SIG,
1133 attr_idx++);
1134 if (err)
1135 return err;
1136
1137 err = cti_create_con_sysfs_attr(dev, tc,
1138 CTI_CON_ATTR_TRIGOUT_TYPES,
1139 attr_idx++);
1140 if (err)
1141 return err;
1142 }
1143 attr_group->attrs = tc->con_attrs;
1144 return 0;
1145}
1146
1147/* create the array of group pointers for the CTI sysfs groups */
1148static int cti_create_cons_groups(struct device *dev, struct cti_device *ctidev)
1149{
1150 int nr_groups;
1151
1152 /* nr groups = dynamic + static + NULL terminator */
1153 nr_groups = ctidev->nr_trig_con + CORESIGHT_CTI_STATIC_GROUPS_MAX;
1154 ctidev->con_groups = devm_kcalloc(dev, nr_groups,
1155 sizeof(struct attribute_group *),
1156 GFP_KERNEL);
1157 if (!ctidev->con_groups)
1158 return -ENOMEM;
1159 return 0;
1160}
1161
1162int cti_create_cons_sysfs(struct device *dev, struct cti_drvdata *drvdata)
1163{
1164 struct cti_device *ctidev = &drvdata->ctidev;
1165 int err, con_idx = 0, i;
1166 struct cti_trig_con *tc;
1167
1168 err = cti_create_cons_groups(dev, ctidev);
1169 if (err)
1170 return err;
1171
1172 /* populate first locations with the static set of groups */
1173 for (i = 0; i < (CORESIGHT_CTI_STATIC_GROUPS_MAX - 1); i++)
1174 ctidev->con_groups[i] = coresight_cti_groups[i];
1175
1176 /* add dynamic set for each connection */
1177 list_for_each_entry(tc, &ctidev->trig_cons, node) {
1178 err = cti_create_con_attr_set(dev, con_idx++, ctidev, tc);
1179 if (err)
1180 break;
1181 }
1182 return err;
1183}
1184
1185/* attribute and group sysfs tables. */
1186static const struct attribute_group coresight_cti_group = {
1187 .attrs = coresight_cti_attrs,
1188};
1189
1190static const struct attribute_group coresight_cti_mgmt_group = {
1191 .attrs = coresight_cti_mgmt_attrs,
1192 .name = "mgmt",
1193};
1194
1195static const struct attribute_group coresight_cti_regs_group = {
1196 .attrs = coresight_cti_regs_attrs,
1197 .name = "regs",
1198};
1199
1200static const struct attribute_group coresight_cti_channels_group = {
1201 .attrs = coresight_cti_channel_attrs,
1202 .name = "channels",
1203};
1204
1205const struct attribute_group *
1206coresight_cti_groups[CORESIGHT_CTI_STATIC_GROUPS_MAX] = {
1207 &coresight_cti_group,
1208 &coresight_cti_mgmt_group,
1209 &coresight_cti_regs_group,
1210 &coresight_cti_channels_group,
1211 NULL,
1212};