1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2019 Linaro Limited, All rights reserved.
4 * Author: Mike Leach <mike.leach@linaro.org>
7 #include <linux/atomic.h>
8 #include <linux/coresight.h>
9 #include <linux/device.h>
11 #include <linux/kernel.h>
12 #include <linux/spinlock.h>
13 #include <linux/sysfs.h>
15 #include "coresight-cti.h"
18 * Declare the number of static declared attribute groups
19 * Value includes groups + NULL value at end of table.
21 #define CORESIGHT_CTI_STATIC_GROUPS_MAX 5
24 * List of trigger signal type names. Match the constants declared in
25 * include\dt-bindings\arm\coresight-cti-dt.h
27 static const char * const sig_type_names
[] = {
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 */
55 /* Show function pointer used in the connections dynamic declared attributes*/
56 typedef ssize_t (*p_show_fn
)(struct device
*dev
, struct device_attribute
*attr
,
59 /* Connection attribute types */
60 enum cti_conn_attr_type
{
62 CTI_CON_ATTR_TRIGIN_SIG
,
63 CTI_CON_ATTR_TRIGOUT_SIG
,
64 CTI_CON_ATTR_TRIGIN_TYPES
,
65 CTI_CON_ATTR_TRIGOUT_TYPES
,
69 /* Names for the connection attributes */
70 static const char * const con_attr_names
[CTI_CON_ATTR_MAX
] = {
78 /* basic attributes */
79 static ssize_t
enable_show(struct device
*dev
,
80 struct device_attribute
*attr
,
84 bool enabled
, powered
;
85 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
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
);
94 return sprintf(buf
, "%d\n", enabled
);
96 return sprintf(buf
, "%d\n", !!enable_req
);
99 static ssize_t
enable_store(struct device
*dev
,
100 struct device_attribute
*attr
,
101 const char *buf
, size_t size
)
105 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
107 ret
= kstrtoul(buf
, 0, &val
);
112 ret
= cti_enable(drvdata
->csdev
);
114 ret
= cti_disable(drvdata
->csdev
);
119 static DEVICE_ATTR_RW(enable
);
121 static ssize_t
powered_show(struct device
*dev
,
122 struct device_attribute
*attr
,
126 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
128 spin_lock(&drvdata
->spinlock
);
129 powered
= drvdata
->config
.hw_powered
;
130 spin_unlock(&drvdata
->spinlock
);
132 return sprintf(buf
, "%d\n", powered
);
134 static DEVICE_ATTR_RO(powered
);
136 static ssize_t
ctmid_show(struct device
*dev
,
137 struct device_attribute
*attr
, char *buf
)
139 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
141 return sprintf(buf
, "%d\n", drvdata
->ctidev
.ctm_id
);
143 static DEVICE_ATTR_RO(ctmid
);
145 static ssize_t
nr_trigger_cons_show(struct device
*dev
,
146 struct device_attribute
*attr
,
149 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
151 return sprintf(buf
, "%d\n", drvdata
->ctidev
.nr_trig_con
);
153 static DEVICE_ATTR_RO(nr_trigger_cons
);
155 /* attribute and group sysfs tables. */
156 static 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
,
164 /* register based attributes */
166 /* macro to access RO registers with power check only (no enable check). */
167 #define coresight_cti_reg(name, offset) \
168 static ssize_t name##_show(struct device *dev, \
169 struct device_attribute *attr, char *buf) \
171 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
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); \
181 static DEVICE_ATTR_RO(name)
183 /* coresight management registers */
184 coresight_cti_reg(devaff0
, CTIDEVAFF0
);
185 coresight_cti_reg(devaff1
, CTIDEVAFF1
);
186 coresight_cti_reg(authstatus
, CORESIGHT_AUTHSTATUS
);
187 coresight_cti_reg(devarch
, CORESIGHT_DEVARCH
);
188 coresight_cti_reg(devid
, CORESIGHT_DEVID
);
189 coresight_cti_reg(devtype
, CORESIGHT_DEVTYPE
);
190 coresight_cti_reg(pidr0
, CORESIGHT_PERIPHIDR0
);
191 coresight_cti_reg(pidr1
, CORESIGHT_PERIPHIDR1
);
192 coresight_cti_reg(pidr2
, CORESIGHT_PERIPHIDR2
);
193 coresight_cti_reg(pidr3
, CORESIGHT_PERIPHIDR3
);
194 coresight_cti_reg(pidr4
, CORESIGHT_PERIPHIDR4
);
196 static 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
,
211 /* CTI low level programming registers */
214 * Show a simple 32 bit value if enabled and powered.
215 * If inaccessible & pcached_val not NULL then show cached value.
217 static ssize_t
cti_reg32_show(struct device
*dev
, char *buf
,
218 u32
*pcached_val
, int reg_offset
)
221 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
222 struct cti_config
*config
= &drvdata
->config
;
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
);
230 CS_LOCK(drvdata
->base
);
231 } else if (pcached_val
) {
234 spin_unlock(&drvdata
->spinlock
);
235 return sprintf(buf
, "%#x\n", val
);
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.
243 static ssize_t
cti_reg32_store(struct device
*dev
, const char *buf
,
244 size_t size
, u32
*pcached_val
, int reg_offset
)
247 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
248 struct cti_config
*config
= &drvdata
->config
;
250 if (kstrtoul(buf
, 0, &val
))
253 spin_lock(&drvdata
->spinlock
);
256 *pcached_val
= (u32
)val
;
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
);
265 /* Standard macro for simple rw cti config registers */
266 #define cti_config_reg32_rw(name, cfgname, offset) \
267 static ssize_t name##_show(struct device *dev, \
268 struct device_attribute *attr, \
271 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
272 return cti_reg32_show(dev, buf, \
273 &drvdata->config.cfgname, offset); \
276 static ssize_t name##_store(struct device *dev, \
277 struct device_attribute *attr, \
278 const char *buf, size_t size) \
280 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
281 return cti_reg32_store(dev, buf, size, \
282 &drvdata->config.cfgname, offset); \
284 static DEVICE_ATTR_RW(name)
286 static ssize_t
inout_sel_show(struct device
*dev
,
287 struct device_attribute
*attr
,
291 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
293 val
= (u32
)drvdata
->config
.ctiinout_sel
;
294 return sprintf(buf
, "%d\n", val
);
297 static ssize_t
inout_sel_store(struct device
*dev
,
298 struct device_attribute
*attr
,
299 const char *buf
, size_t size
)
302 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
304 if (kstrtoul(buf
, 0, &val
))
306 if (val
> (CTIINOUTEN_MAX
- 1))
309 spin_lock(&drvdata
->spinlock
);
310 drvdata
->config
.ctiinout_sel
= val
;
311 spin_unlock(&drvdata
->spinlock
);
314 static DEVICE_ATTR_RW(inout_sel
);
316 static ssize_t
inen_show(struct device
*dev
,
317 struct device_attribute
*attr
,
322 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
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
);
331 static ssize_t
inen_store(struct device
*dev
,
332 struct device_attribute
*attr
,
333 const char *buf
, size_t size
)
337 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
338 struct cti_config
*config
= &drvdata
->config
;
340 if (kstrtoul(buf
, 0, &val
))
343 spin_lock(&drvdata
->spinlock
);
344 index
= config
->ctiinout_sel
;
345 config
->ctiinen
[index
] = val
;
347 /* write through if enabled */
348 if (cti_active(config
))
349 cti_write_single_reg(drvdata
, CTIINEN(index
), val
);
350 spin_unlock(&drvdata
->spinlock
);
353 static DEVICE_ATTR_RW(inen
);
355 static ssize_t
outen_show(struct device
*dev
,
356 struct device_attribute
*attr
,
361 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
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
);
370 static ssize_t
outen_store(struct device
*dev
,
371 struct device_attribute
*attr
,
372 const char *buf
, size_t size
)
376 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
377 struct cti_config
*config
= &drvdata
->config
;
379 if (kstrtoul(buf
, 0, &val
))
382 spin_lock(&drvdata
->spinlock
);
383 index
= config
->ctiinout_sel
;
384 config
->ctiouten
[index
] = val
;
386 /* write through if enabled */
387 if (cti_active(config
))
388 cti_write_single_reg(drvdata
, CTIOUTEN(index
), val
);
389 spin_unlock(&drvdata
->spinlock
);
392 static DEVICE_ATTR_RW(outen
);
394 static ssize_t
intack_store(struct device
*dev
,
395 struct device_attribute
*attr
,
396 const char *buf
, size_t size
)
400 if (kstrtoul(buf
, 0, &val
))
403 cti_write_intack(dev
, val
);
406 static DEVICE_ATTR_WO(intack
);
408 cti_config_reg32_rw(gate
, ctigate
, CTIGATE
);
409 cti_config_reg32_rw(asicctl
, asicctl
, ASICCTL
);
410 cti_config_reg32_rw(appset
, ctiappset
, CTIAPPSET
);
412 static ssize_t
appclear_store(struct device
*dev
,
413 struct device_attribute
*attr
,
414 const char *buf
, size_t size
)
417 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
418 struct cti_config
*config
= &drvdata
->config
;
420 if (kstrtoul(buf
, 0, &val
))
423 spin_lock(&drvdata
->spinlock
);
425 /* a 1'b1 in appclr clears down the same bit in appset*/
426 config
->ctiappset
&= ~val
;
428 /* write through if enabled */
429 if (cti_active(config
))
430 cti_write_single_reg(drvdata
, CTIAPPCLEAR
, val
);
431 spin_unlock(&drvdata
->spinlock
);
434 static DEVICE_ATTR_WO(appclear
);
436 static ssize_t
apppulse_store(struct device
*dev
,
437 struct device_attribute
*attr
,
438 const char *buf
, size_t size
)
441 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
442 struct cti_config
*config
= &drvdata
->config
;
444 if (kstrtoul(buf
, 0, &val
))
447 spin_lock(&drvdata
->spinlock
);
449 /* write through if enabled */
450 if (cti_active(config
))
451 cti_write_single_reg(drvdata
, CTIAPPPULSE
, val
);
452 spin_unlock(&drvdata
->spinlock
);
455 static DEVICE_ATTR_WO(apppulse
);
457 coresight_cti_reg(triginstatus
, CTITRIGINSTATUS
);
458 coresight_cti_reg(trigoutstatus
, CTITRIGOUTSTATUS
);
459 coresight_cti_reg(chinstatus
, CTICHINSTATUS
);
460 coresight_cti_reg(choutstatus
, CTICHOUTSTATUS
);
463 * Define CONFIG_CORESIGHT_CTI_INTEGRATION_REGS to enable the access to the
464 * integration control registers. Normally only used to investigate connection
467 #ifdef CONFIG_CORESIGHT_CTI_INTEGRATION_REGS
469 /* macro to access RW registers with power check only (no enable check). */
470 #define coresight_cti_reg_rw(name, offset) \
471 static ssize_t name##_show(struct device *dev, \
472 struct device_attribute *attr, char *buf) \
474 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
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); \
485 static ssize_t name##_store(struct device *dev, \
486 struct device_attribute *attr, \
487 const char *buf, size_t size) \
489 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
490 unsigned long val = 0; \
491 if (kstrtoul(buf, 0, &val)) \
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); \
502 static DEVICE_ATTR_RW(name)
504 /* macro to access WO registers with power check only (no enable check). */
505 #define coresight_cti_reg_wo(name, offset) \
506 static ssize_t name##_store(struct device *dev, \
507 struct device_attribute *attr, \
508 const char *buf, size_t size) \
510 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
511 unsigned long val = 0; \
512 if (kstrtoul(buf, 0, &val)) \
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); \
523 static DEVICE_ATTR_WO(name)
525 coresight_cti_reg_rw(itchout
, ITCHOUT
);
526 coresight_cti_reg_rw(ittrigout
, ITTRIGOUT
);
527 coresight_cti_reg_rw(itctrl
, CORESIGHT_ITCTRL
);
528 coresight_cti_reg_wo(itchinack
, ITCHINACK
);
529 coresight_cti_reg_wo(ittriginack
, ITTRIGINACK
);
530 coresight_cti_reg(ittrigin
, ITTRIGIN
);
531 coresight_cti_reg(itchin
, ITCHIN
);
532 coresight_cti_reg(itchoutack
, ITCHOUTACK
);
533 coresight_cti_reg(ittrigoutack
, ITTRIGOUTACK
);
535 #endif /* CORESIGHT_CTI_INTEGRATION_REGS */
537 static struct attribute
*coresight_cti_regs_attrs
[] = {
538 &dev_attr_inout_sel
.attr
,
540 &dev_attr_outen
.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
,
565 /* CTI channel x-trigger programming */
567 cti_trig_op_parse(struct device
*dev
, enum cti_chan_op op
,
568 enum cti_trig_dir dir
, const char *buf
, size_t size
)
572 int items
, err
= -EINVAL
;
574 /* extract chan idx and trigger idx */
575 items
= sscanf(buf
, "%d %d", &chan_idx
, &trig_idx
);
577 err
= cti_channel_trig_op(dev
, op
, dir
, chan_idx
, trig_idx
);
584 static ssize_t
trigin_attach_store(struct device
*dev
,
585 struct device_attribute
*attr
,
586 const char *buf
, size_t size
)
588 return cti_trig_op_parse(dev
, CTI_CHAN_ATTACH
, CTI_TRIG_IN
,
591 static DEVICE_ATTR_WO(trigin_attach
);
593 static ssize_t
trigin_detach_store(struct device
*dev
,
594 struct device_attribute
*attr
,
595 const char *buf
, size_t size
)
597 return cti_trig_op_parse(dev
, CTI_CHAN_DETACH
, CTI_TRIG_IN
,
600 static DEVICE_ATTR_WO(trigin_detach
);
602 static ssize_t
trigout_attach_store(struct device
*dev
,
603 struct device_attribute
*attr
,
604 const char *buf
, size_t size
)
606 return cti_trig_op_parse(dev
, CTI_CHAN_ATTACH
, CTI_TRIG_OUT
,
609 static DEVICE_ATTR_WO(trigout_attach
);
611 static ssize_t
trigout_detach_store(struct device
*dev
,
612 struct device_attribute
*attr
,
613 const char *buf
, size_t size
)
615 return cti_trig_op_parse(dev
, CTI_CHAN_DETACH
, CTI_TRIG_OUT
,
618 static DEVICE_ATTR_WO(trigout_detach
);
621 static ssize_t
chan_gate_enable_store(struct device
*dev
,
622 struct device_attribute
*attr
,
623 const char *buf
, size_t size
)
625 int err
= 0, channel
= 0;
627 if (kstrtoint(buf
, 0, &channel
))
630 err
= cti_channel_gate_op(dev
, CTI_GATE_CHAN_ENABLE
, channel
);
631 return err
? err
: size
;
634 static ssize_t
chan_gate_enable_show(struct device
*dev
,
635 struct device_attribute
*attr
,
638 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
639 struct cti_config
*cfg
= &drvdata
->config
;
640 unsigned long ctigate_bitmask
= cfg
->ctigate
;
643 if (cfg
->ctigate
== 0)
644 size
= sprintf(buf
, "\n");
646 size
= bitmap_print_to_pagebuf(true, buf
, &ctigate_bitmask
,
647 cfg
->nr_ctm_channels
);
650 static DEVICE_ATTR_RW(chan_gate_enable
);
652 static ssize_t
chan_gate_disable_store(struct device
*dev
,
653 struct device_attribute
*attr
,
654 const char *buf
, size_t size
)
656 int err
= 0, channel
= 0;
658 if (kstrtoint(buf
, 0, &channel
))
661 err
= cti_channel_gate_op(dev
, CTI_GATE_CHAN_DISABLE
, channel
);
662 return err
? err
: size
;
664 static DEVICE_ATTR_WO(chan_gate_disable
);
667 chan_op_parse(struct device
*dev
, enum cti_chan_set_op op
, const char *buf
)
669 int err
= 0, channel
= 0;
671 if (kstrtoint(buf
, 0, &channel
))
674 err
= cti_channel_setop(dev
, op
, channel
);
679 static ssize_t
chan_set_store(struct device
*dev
,
680 struct device_attribute
*attr
,
681 const char *buf
, size_t size
)
683 int err
= chan_op_parse(dev
, CTI_CHAN_SET
, buf
);
685 return err
? err
: size
;
687 static DEVICE_ATTR_WO(chan_set
);
689 static ssize_t
chan_clear_store(struct device
*dev
,
690 struct device_attribute
*attr
,
691 const char *buf
, size_t size
)
693 int err
= chan_op_parse(dev
, CTI_CHAN_CLR
, buf
);
695 return err
? err
: size
;
697 static DEVICE_ATTR_WO(chan_clear
);
699 static ssize_t
chan_pulse_store(struct device
*dev
,
700 struct device_attribute
*attr
,
701 const char *buf
, size_t size
)
703 int err
= chan_op_parse(dev
, CTI_CHAN_PULSE
, buf
);
705 return err
? err
: size
;
707 static DEVICE_ATTR_WO(chan_pulse
);
709 static ssize_t
trig_filter_enable_show(struct device
*dev
,
710 struct device_attribute
*attr
,
714 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
716 spin_lock(&drvdata
->spinlock
);
717 val
= drvdata
->config
.trig_filter_enable
;
718 spin_unlock(&drvdata
->spinlock
);
719 return sprintf(buf
, "%d\n", val
);
722 static ssize_t
trig_filter_enable_store(struct device
*dev
,
723 struct device_attribute
*attr
,
724 const char *buf
, size_t size
)
727 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
729 if (kstrtoul(buf
, 0, &val
))
732 spin_lock(&drvdata
->spinlock
);
733 drvdata
->config
.trig_filter_enable
= !!val
;
734 spin_unlock(&drvdata
->spinlock
);
737 static DEVICE_ATTR_RW(trig_filter_enable
);
739 static ssize_t
trigout_filtered_show(struct device
*dev
,
740 struct device_attribute
*attr
,
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
;
749 size
= bitmap_print_to_pagebuf(true, buf
, &mask
, nr_trig_max
);
752 static DEVICE_ATTR_RO(trigout_filtered
);
754 /* clear all xtrigger / channel programming */
755 static ssize_t
chan_xtrigs_reset_store(struct device
*dev
,
756 struct device_attribute
*attr
,
757 const char *buf
, size_t size
)
760 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
761 struct cti_config
*config
= &drvdata
->config
;
763 spin_lock(&drvdata
->spinlock
);
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;
771 /* clear the other regs */
772 config
->ctigate
= GENMASK(config
->nr_ctm_channels
- 1, 0);
774 config
->ctiappset
= 0;
775 config
->ctiinout_sel
= 0;
776 config
->xtrig_rchan_sel
= 0;
778 /* if enabled then write through */
779 if (cti_active(config
))
780 cti_write_all_hw_regs(drvdata
);
782 spin_unlock(&drvdata
->spinlock
);
785 static DEVICE_ATTR_WO(chan_xtrigs_reset
);
788 * Write to select a channel to view, read to display the
789 * cross triggers for the selected channel.
791 static ssize_t
chan_xtrigs_sel_store(struct device
*dev
,
792 struct device_attribute
*attr
,
793 const char *buf
, size_t size
)
796 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
798 if (kstrtoul(buf
, 0, &val
))
800 if (val
> (drvdata
->config
.nr_ctm_channels
- 1))
803 spin_lock(&drvdata
->spinlock
);
804 drvdata
->config
.xtrig_rchan_sel
= val
;
805 spin_unlock(&drvdata
->spinlock
);
809 static ssize_t
chan_xtrigs_sel_show(struct device
*dev
,
810 struct device_attribute
*attr
,
814 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
816 spin_lock(&drvdata
->spinlock
);
817 val
= drvdata
->config
.xtrig_rchan_sel
;
818 spin_unlock(&drvdata
->spinlock
);
820 return sprintf(buf
, "%ld\n", val
);
822 static DEVICE_ATTR_RW(chan_xtrigs_sel
);
824 static ssize_t
chan_xtrigs_in_show(struct device
*dev
,
825 struct device_attribute
*attr
,
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
);
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
);
839 used
+= sprintf(buf
+ used
, "\n");
842 static DEVICE_ATTR_RO(chan_xtrigs_in
);
844 static ssize_t
chan_xtrigs_out_show(struct device
*dev
,
845 struct device_attribute
*attr
,
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
);
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
);
859 used
+= sprintf(buf
+ used
, "\n");
862 static DEVICE_ATTR_RO(chan_xtrigs_out
);
864 static ssize_t
print_chan_list(struct device
*dev
,
865 char *buf
, bool inuse
)
867 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
868 struct cti_config
*config
= &drvdata
->config
;
870 unsigned long inuse_bits
= 0, chan_mask
;
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
];
878 spin_unlock(&drvdata
->spinlock
);
880 /* inverse bits if printing free channels */
882 inuse_bits
= ~inuse_bits
;
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
);
890 size
= sprintf(buf
, "\n");
894 static ssize_t
chan_inuse_show(struct device
*dev
,
895 struct device_attribute
*attr
,
898 return print_chan_list(dev
, buf
, true);
900 static DEVICE_ATTR_RO(chan_inuse
);
902 static ssize_t
chan_free_show(struct device
*dev
,
903 struct device_attribute
*attr
,
906 return print_chan_list(dev
, buf
, false);
908 static DEVICE_ATTR_RO(chan_free
);
910 static 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
,
931 /* Create the connections trigger groups and attrs dynamically */
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
941 static ssize_t
con_name_show(struct device
*dev
,
942 struct device_attribute
*attr
,
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
;
949 return sprintf(buf
, "%s\n", con
->con_dev_name
);
952 static ssize_t
trigin_sig_show(struct device
*dev
,
953 struct device_attribute
*attr
,
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
;
963 return bitmap_print_to_pagebuf(true, buf
, &mask
, cfg
->nr_trig_max
);
966 static ssize_t
trigout_sig_show(struct device
*dev
,
967 struct device_attribute
*attr
,
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
;
977 return bitmap_print_to_pagebuf(true, buf
, &mask
, cfg
->nr_trig_max
);
980 /* convert a sig type id to a name */
982 cti_sig_type_name(struct cti_trig_con
*con
, int used_count
, bool in
)
985 struct cti_trig_grp
*grp
= in
? con
->con_in
: con
->con_out
;
987 if (used_count
< grp
->nr_sigs
)
988 idx
= grp
->sig_types
[used_count
];
989 return sig_type_names
[idx
];
992 static ssize_t
trigin_type_show(struct device
*dev
,
993 struct device_attribute
*attr
,
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;
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
);
1006 used
+= sprintf(buf
+ used
, "\n");
1010 static ssize_t
trigout_type_show(struct device
*dev
,
1011 struct device_attribute
*attr
,
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;
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
);
1024 used
+= sprintf(buf
+ used
, "\n");
1029 * Array of show function names declared above to allow selection
1030 * for the connection attributes
1032 static p_show_fn show_fns
[CTI_CON_ATTR_MAX
] = {
1040 static int cti_create_con_sysfs_attr(struct device
*dev
,
1041 struct cti_trig_con
*con
,
1042 enum cti_conn_attr_type attr_type
,
1045 struct dev_ext_attribute
*eattr
;
1048 eattr
= devm_kzalloc(dev
, sizeof(struct dev_ext_attribute
),
1051 name
= devm_kstrdup(dev
, con_attr_names
[attr_type
],
1054 /* fill out the underlying attribute struct */
1055 eattr
->attr
.attr
.name
= name
;
1056 eattr
->attr
.attr
.mode
= 0444;
1058 /* now the device_attribute struct */
1059 eattr
->attr
.show
= show_fns
[attr_type
];
1067 con
->con_attrs
[attr_idx
] = &eattr
->attr
.attr
;
1069 * Initialize the dynamically allocated attribute
1070 * to avoid LOCKDEP splat. See include/linux/sysfs.h
1073 sysfs_attr_init(con
->con_attrs
[attr_idx
]);
1078 static struct attribute_group
*
1079 cti_create_con_sysfs_group(struct device
*dev
, struct cti_device
*ctidev
,
1080 int con_idx
, struct cti_trig_con
*tc
)
1082 struct attribute_group
*group
= NULL
;
1085 group
= devm_kzalloc(dev
, sizeof(struct attribute_group
), GFP_KERNEL
);
1089 group
->name
= devm_kasprintf(dev
, GFP_KERNEL
, "triggers%d", con_idx
);
1093 grp_idx
= con_idx
+ CORESIGHT_CTI_STATIC_GROUPS_MAX
- 1;
1094 ctidev
->con_groups
[grp_idx
] = group
;
1095 tc
->attr_group
= group
;
1099 /* create a triggers connection group and the attributes for that group */
1100 static int cti_create_con_attr_set(struct device
*dev
, int con_idx
,
1101 struct cti_device
*ctidev
,
1102 struct cti_trig_con
*tc
)
1104 struct attribute_group
*attr_group
= NULL
;
1108 attr_group
= cti_create_con_sysfs_group(dev
, ctidev
, con_idx
, tc
);
1112 /* allocate NULL terminated array of attributes */
1113 tc
->con_attrs
= devm_kcalloc(dev
, CTI_CON_ATTR_MAX
+ 1,
1114 sizeof(struct attribute
*), GFP_KERNEL
);
1118 err
= cti_create_con_sysfs_attr(dev
, tc
, CTI_CON_ATTR_NAME
,
1123 if (tc
->con_in
->nr_sigs
> 0) {
1124 err
= cti_create_con_sysfs_attr(dev
, tc
,
1125 CTI_CON_ATTR_TRIGIN_SIG
,
1130 err
= cti_create_con_sysfs_attr(dev
, tc
,
1131 CTI_CON_ATTR_TRIGIN_TYPES
,
1137 if (tc
->con_out
->nr_sigs
> 0) {
1138 err
= cti_create_con_sysfs_attr(dev
, tc
,
1139 CTI_CON_ATTR_TRIGOUT_SIG
,
1144 err
= cti_create_con_sysfs_attr(dev
, tc
,
1145 CTI_CON_ATTR_TRIGOUT_TYPES
,
1150 attr_group
->attrs
= tc
->con_attrs
;
1154 /* create the array of group pointers for the CTI sysfs groups */
1155 static int cti_create_cons_groups(struct device
*dev
, struct cti_device
*ctidev
)
1159 /* nr groups = dynamic + static + NULL terminator */
1160 nr_groups
= ctidev
->nr_trig_con
+ CORESIGHT_CTI_STATIC_GROUPS_MAX
;
1161 ctidev
->con_groups
= devm_kcalloc(dev
, nr_groups
,
1162 sizeof(struct attribute_group
*),
1164 if (!ctidev
->con_groups
)
1169 int cti_create_cons_sysfs(struct device
*dev
, struct cti_drvdata
*drvdata
)
1171 struct cti_device
*ctidev
= &drvdata
->ctidev
;
1172 int err
, con_idx
= 0, i
;
1173 struct cti_trig_con
*tc
;
1175 err
= cti_create_cons_groups(dev
, ctidev
);
1179 /* populate first locations with the static set of groups */
1180 for (i
= 0; i
< (CORESIGHT_CTI_STATIC_GROUPS_MAX
- 1); i
++)
1181 ctidev
->con_groups
[i
] = coresight_cti_groups
[i
];
1183 /* add dynamic set for each connection */
1184 list_for_each_entry(tc
, &ctidev
->trig_cons
, node
) {
1185 err
= cti_create_con_attr_set(dev
, con_idx
++, ctidev
, tc
);
1192 /* attribute and group sysfs tables. */
1193 static const struct attribute_group coresight_cti_group
= {
1194 .attrs
= coresight_cti_attrs
,
1197 static const struct attribute_group coresight_cti_mgmt_group
= {
1198 .attrs
= coresight_cti_mgmt_attrs
,
1202 static const struct attribute_group coresight_cti_regs_group
= {
1203 .attrs
= coresight_cti_regs_attrs
,
1207 static const struct attribute_group coresight_cti_channels_group
= {
1208 .attrs
= coresight_cti_channel_attrs
,
1212 const struct attribute_group
*
1213 coresight_cti_groups
[CORESIGHT_CTI_STATIC_GROUPS_MAX
] = {
1214 &coresight_cti_group
,
1215 &coresight_cti_mgmt_group
,
1216 &coresight_cti_regs_group
,
1217 &coresight_cti_channels_group
,