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 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
);
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
= pm_runtime_resume_and_get(dev
->parent
);
115 ret
= cti_enable(drvdata
->csdev
, CS_MODE_SYSFS
, NULL
);
117 pm_runtime_put(dev
->parent
);
119 ret
= cti_disable(drvdata
->csdev
, NULL
);
121 pm_runtime_put(dev
->parent
);
128 static DEVICE_ATTR_RW(enable
);
130 static ssize_t
powered_show(struct device
*dev
,
131 struct device_attribute
*attr
,
135 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
137 spin_lock(&drvdata
->spinlock
);
138 powered
= drvdata
->config
.hw_powered
;
139 spin_unlock(&drvdata
->spinlock
);
141 return sprintf(buf
, "%d\n", powered
);
143 static DEVICE_ATTR_RO(powered
);
145 static ssize_t
ctmid_show(struct device
*dev
,
146 struct device_attribute
*attr
, char *buf
)
148 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
150 return sprintf(buf
, "%d\n", drvdata
->ctidev
.ctm_id
);
152 static DEVICE_ATTR_RO(ctmid
);
154 static ssize_t
nr_trigger_cons_show(struct device
*dev
,
155 struct device_attribute
*attr
,
158 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
160 return sprintf(buf
, "%d\n", drvdata
->ctidev
.nr_trig_con
);
162 static DEVICE_ATTR_RO(nr_trigger_cons
);
164 /* attribute and group sysfs tables. */
165 static 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
,
173 /* register based attributes */
175 /* Read registers with power check only (no enable check). */
176 static ssize_t
coresight_cti_reg_show(struct device
*dev
,
177 struct device_attribute
*attr
, char *buf
)
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
);
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
);
192 /* Write registers with power check only (no enable check). */
193 static __maybe_unused ssize_t
coresight_cti_reg_store(struct device
*dev
,
194 struct device_attribute
*attr
,
195 const char *buf
, size_t size
)
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;
201 if (kstrtoul(buf
, 0, &val
))
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
);
213 #define coresight_cti_reg(name, offset) \
214 (&((struct cs_off_attribute[]) { \
216 __ATTR(name, 0444, coresight_cti_reg_show, NULL), \
221 #define coresight_cti_reg_rw(name, offset) \
222 (&((struct cs_off_attribute[]) { \
224 __ATTR(name, 0644, coresight_cti_reg_show, \
225 coresight_cti_reg_store), \
230 #define coresight_cti_reg_wo(name, offset) \
231 (&((struct cs_off_attribute[]) { \
233 __ATTR(name, 0200, NULL, coresight_cti_reg_store), \
238 /* coresight management registers */
239 static 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
),
254 /* CTI low level programming registers */
257 * Show a simple 32 bit value if enabled and powered.
258 * If inaccessible & pcached_val not NULL then show cached value.
260 static ssize_t
cti_reg32_show(struct device
*dev
, char *buf
,
261 u32
*pcached_val
, int reg_offset
)
264 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
265 struct cti_config
*config
= &drvdata
->config
;
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
);
273 CS_LOCK(drvdata
->base
);
274 } else if (pcached_val
) {
277 spin_unlock(&drvdata
->spinlock
);
278 return sprintf(buf
, "%#x\n", val
);
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.
286 static ssize_t
cti_reg32_store(struct device
*dev
, const char *buf
,
287 size_t size
, u32
*pcached_val
, int reg_offset
)
290 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
291 struct cti_config
*config
= &drvdata
->config
;
293 if (kstrtoul(buf
, 0, &val
))
296 spin_lock(&drvdata
->spinlock
);
299 *pcached_val
= (u32
)val
;
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
);
308 /* Standard macro for simple rw cti config registers */
309 #define cti_config_reg32_rw(name, cfgname, offset) \
310 static ssize_t name##_show(struct device *dev, \
311 struct device_attribute *attr, \
314 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
315 return cti_reg32_show(dev, buf, \
316 &drvdata->config.cfgname, offset); \
319 static ssize_t name##_store(struct device *dev, \
320 struct device_attribute *attr, \
321 const char *buf, size_t size) \
323 struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
324 return cti_reg32_store(dev, buf, size, \
325 &drvdata->config.cfgname, offset); \
327 static DEVICE_ATTR_RW(name)
329 static ssize_t
inout_sel_show(struct device
*dev
,
330 struct device_attribute
*attr
,
334 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
336 val
= (u32
)drvdata
->config
.ctiinout_sel
;
337 return sprintf(buf
, "%d\n", val
);
340 static ssize_t
inout_sel_store(struct device
*dev
,
341 struct device_attribute
*attr
,
342 const char *buf
, size_t size
)
345 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
347 if (kstrtoul(buf
, 0, &val
))
349 if (val
> (CTIINOUTEN_MAX
- 1))
352 spin_lock(&drvdata
->spinlock
);
353 drvdata
->config
.ctiinout_sel
= val
;
354 spin_unlock(&drvdata
->spinlock
);
357 static DEVICE_ATTR_RW(inout_sel
);
359 static ssize_t
inen_show(struct device
*dev
,
360 struct device_attribute
*attr
,
365 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
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
);
374 static ssize_t
inen_store(struct device
*dev
,
375 struct device_attribute
*attr
,
376 const char *buf
, size_t size
)
380 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
381 struct cti_config
*config
= &drvdata
->config
;
383 if (kstrtoul(buf
, 0, &val
))
386 spin_lock(&drvdata
->spinlock
);
387 index
= config
->ctiinout_sel
;
388 config
->ctiinen
[index
] = val
;
390 /* write through if enabled */
391 if (cti_active(config
))
392 cti_write_single_reg(drvdata
, CTIINEN(index
), val
);
393 spin_unlock(&drvdata
->spinlock
);
396 static DEVICE_ATTR_RW(inen
);
398 static ssize_t
outen_show(struct device
*dev
,
399 struct device_attribute
*attr
,
404 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
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
);
413 static ssize_t
outen_store(struct device
*dev
,
414 struct device_attribute
*attr
,
415 const char *buf
, size_t size
)
419 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
420 struct cti_config
*config
= &drvdata
->config
;
422 if (kstrtoul(buf
, 0, &val
))
425 spin_lock(&drvdata
->spinlock
);
426 index
= config
->ctiinout_sel
;
427 config
->ctiouten
[index
] = val
;
429 /* write through if enabled */
430 if (cti_active(config
))
431 cti_write_single_reg(drvdata
, CTIOUTEN(index
), val
);
432 spin_unlock(&drvdata
->spinlock
);
435 static DEVICE_ATTR_RW(outen
);
437 static ssize_t
intack_store(struct device
*dev
,
438 struct device_attribute
*attr
,
439 const char *buf
, size_t size
)
443 if (kstrtoul(buf
, 0, &val
))
446 cti_write_intack(dev
, val
);
449 static DEVICE_ATTR_WO(intack
);
451 cti_config_reg32_rw(gate
, ctigate
, CTIGATE
);
452 cti_config_reg32_rw(asicctl
, asicctl
, ASICCTL
);
453 cti_config_reg32_rw(appset
, ctiappset
, CTIAPPSET
);
455 static ssize_t
appclear_store(struct device
*dev
,
456 struct device_attribute
*attr
,
457 const char *buf
, size_t size
)
460 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
461 struct cti_config
*config
= &drvdata
->config
;
463 if (kstrtoul(buf
, 0, &val
))
466 spin_lock(&drvdata
->spinlock
);
468 /* a 1'b1 in appclr clears down the same bit in appset*/
469 config
->ctiappset
&= ~val
;
471 /* write through if enabled */
472 if (cti_active(config
))
473 cti_write_single_reg(drvdata
, CTIAPPCLEAR
, val
);
474 spin_unlock(&drvdata
->spinlock
);
477 static DEVICE_ATTR_WO(appclear
);
479 static ssize_t
apppulse_store(struct device
*dev
,
480 struct device_attribute
*attr
,
481 const char *buf
, size_t size
)
484 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
485 struct cti_config
*config
= &drvdata
->config
;
487 if (kstrtoul(buf
, 0, &val
))
490 spin_lock(&drvdata
->spinlock
);
492 /* write through if enabled */
493 if (cti_active(config
))
494 cti_write_single_reg(drvdata
, CTIAPPPULSE
, val
);
495 spin_unlock(&drvdata
->spinlock
);
498 static DEVICE_ATTR_WO(apppulse
);
501 * Define CONFIG_CORESIGHT_CTI_INTEGRATION_REGS to enable the access to the
502 * integration control registers. Normally only used to investigate connection
505 static struct attribute
*coresight_cti_regs_attrs
[] = {
506 &dev_attr_inout_sel
.attr
,
508 &dev_attr_outen
.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
),
533 /* CTI channel x-trigger programming */
535 cti_trig_op_parse(struct device
*dev
, enum cti_chan_op op
,
536 enum cti_trig_dir dir
, const char *buf
, size_t size
)
540 int items
, err
= -EINVAL
;
542 /* extract chan idx and trigger idx */
543 items
= sscanf(buf
, "%d %d", &chan_idx
, &trig_idx
);
545 err
= cti_channel_trig_op(dev
, op
, dir
, chan_idx
, trig_idx
);
552 static ssize_t
trigin_attach_store(struct device
*dev
,
553 struct device_attribute
*attr
,
554 const char *buf
, size_t size
)
556 return cti_trig_op_parse(dev
, CTI_CHAN_ATTACH
, CTI_TRIG_IN
,
559 static DEVICE_ATTR_WO(trigin_attach
);
561 static ssize_t
trigin_detach_store(struct device
*dev
,
562 struct device_attribute
*attr
,
563 const char *buf
, size_t size
)
565 return cti_trig_op_parse(dev
, CTI_CHAN_DETACH
, CTI_TRIG_IN
,
568 static DEVICE_ATTR_WO(trigin_detach
);
570 static ssize_t
trigout_attach_store(struct device
*dev
,
571 struct device_attribute
*attr
,
572 const char *buf
, size_t size
)
574 return cti_trig_op_parse(dev
, CTI_CHAN_ATTACH
, CTI_TRIG_OUT
,
577 static DEVICE_ATTR_WO(trigout_attach
);
579 static ssize_t
trigout_detach_store(struct device
*dev
,
580 struct device_attribute
*attr
,
581 const char *buf
, size_t size
)
583 return cti_trig_op_parse(dev
, CTI_CHAN_DETACH
, CTI_TRIG_OUT
,
586 static DEVICE_ATTR_WO(trigout_detach
);
589 static ssize_t
chan_gate_enable_store(struct device
*dev
,
590 struct device_attribute
*attr
,
591 const char *buf
, size_t size
)
593 int err
= 0, channel
= 0;
595 if (kstrtoint(buf
, 0, &channel
))
598 err
= cti_channel_gate_op(dev
, CTI_GATE_CHAN_ENABLE
, channel
);
599 return err
? err
: size
;
602 static ssize_t
chan_gate_enable_show(struct device
*dev
,
603 struct device_attribute
*attr
,
606 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
607 struct cti_config
*cfg
= &drvdata
->config
;
608 unsigned long ctigate_bitmask
= cfg
->ctigate
;
611 if (cfg
->ctigate
== 0)
612 size
= sprintf(buf
, "\n");
614 size
= bitmap_print_to_pagebuf(true, buf
, &ctigate_bitmask
,
615 cfg
->nr_ctm_channels
);
618 static DEVICE_ATTR_RW(chan_gate_enable
);
620 static ssize_t
chan_gate_disable_store(struct device
*dev
,
621 struct device_attribute
*attr
,
622 const char *buf
, size_t size
)
624 int err
= 0, channel
= 0;
626 if (kstrtoint(buf
, 0, &channel
))
629 err
= cti_channel_gate_op(dev
, CTI_GATE_CHAN_DISABLE
, channel
);
630 return err
? err
: size
;
632 static DEVICE_ATTR_WO(chan_gate_disable
);
635 chan_op_parse(struct device
*dev
, enum cti_chan_set_op op
, const char *buf
)
637 int err
= 0, channel
= 0;
639 if (kstrtoint(buf
, 0, &channel
))
642 err
= cti_channel_setop(dev
, op
, channel
);
647 static ssize_t
chan_set_store(struct device
*dev
,
648 struct device_attribute
*attr
,
649 const char *buf
, size_t size
)
651 int err
= chan_op_parse(dev
, CTI_CHAN_SET
, buf
);
653 return err
? err
: size
;
655 static DEVICE_ATTR_WO(chan_set
);
657 static ssize_t
chan_clear_store(struct device
*dev
,
658 struct device_attribute
*attr
,
659 const char *buf
, size_t size
)
661 int err
= chan_op_parse(dev
, CTI_CHAN_CLR
, buf
);
663 return err
? err
: size
;
665 static DEVICE_ATTR_WO(chan_clear
);
667 static ssize_t
chan_pulse_store(struct device
*dev
,
668 struct device_attribute
*attr
,
669 const char *buf
, size_t size
)
671 int err
= chan_op_parse(dev
, CTI_CHAN_PULSE
, buf
);
673 return err
? err
: size
;
675 static DEVICE_ATTR_WO(chan_pulse
);
677 static ssize_t
trig_filter_enable_show(struct device
*dev
,
678 struct device_attribute
*attr
,
682 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
684 spin_lock(&drvdata
->spinlock
);
685 val
= drvdata
->config
.trig_filter_enable
;
686 spin_unlock(&drvdata
->spinlock
);
687 return sprintf(buf
, "%d\n", val
);
690 static ssize_t
trig_filter_enable_store(struct device
*dev
,
691 struct device_attribute
*attr
,
692 const char *buf
, size_t size
)
695 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
697 if (kstrtoul(buf
, 0, &val
))
700 spin_lock(&drvdata
->spinlock
);
701 drvdata
->config
.trig_filter_enable
= !!val
;
702 spin_unlock(&drvdata
->spinlock
);
705 static DEVICE_ATTR_RW(trig_filter_enable
);
707 static ssize_t
trigout_filtered_show(struct device
*dev
,
708 struct device_attribute
*attr
,
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
;
717 size
= bitmap_print_to_pagebuf(true, buf
, &mask
, nr_trig_max
);
720 static DEVICE_ATTR_RO(trigout_filtered
);
722 /* clear all xtrigger / channel programming */
723 static ssize_t
chan_xtrigs_reset_store(struct device
*dev
,
724 struct device_attribute
*attr
,
725 const char *buf
, size_t size
)
728 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
729 struct cti_config
*config
= &drvdata
->config
;
731 spin_lock(&drvdata
->spinlock
);
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;
739 /* clear the other regs */
740 config
->ctigate
= GENMASK(config
->nr_ctm_channels
- 1, 0);
742 config
->ctiappset
= 0;
743 config
->ctiinout_sel
= 0;
744 config
->xtrig_rchan_sel
= 0;
746 /* if enabled then write through */
747 if (cti_active(config
))
748 cti_write_all_hw_regs(drvdata
);
750 spin_unlock(&drvdata
->spinlock
);
753 static DEVICE_ATTR_WO(chan_xtrigs_reset
);
756 * Write to select a channel to view, read to display the
757 * cross triggers for the selected channel.
759 static ssize_t
chan_xtrigs_sel_store(struct device
*dev
,
760 struct device_attribute
*attr
,
761 const char *buf
, size_t size
)
764 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
766 if (kstrtoul(buf
, 0, &val
))
768 if (val
> (drvdata
->config
.nr_ctm_channels
- 1))
771 spin_lock(&drvdata
->spinlock
);
772 drvdata
->config
.xtrig_rchan_sel
= val
;
773 spin_unlock(&drvdata
->spinlock
);
777 static ssize_t
chan_xtrigs_sel_show(struct device
*dev
,
778 struct device_attribute
*attr
,
782 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
784 spin_lock(&drvdata
->spinlock
);
785 val
= drvdata
->config
.xtrig_rchan_sel
;
786 spin_unlock(&drvdata
->spinlock
);
788 return sprintf(buf
, "%ld\n", val
);
790 static DEVICE_ATTR_RW(chan_xtrigs_sel
);
792 static ssize_t
chan_xtrigs_in_show(struct device
*dev
,
793 struct device_attribute
*attr
,
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
);
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
);
807 used
+= sprintf(buf
+ used
, "\n");
810 static DEVICE_ATTR_RO(chan_xtrigs_in
);
812 static ssize_t
chan_xtrigs_out_show(struct device
*dev
,
813 struct device_attribute
*attr
,
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
);
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
);
827 used
+= sprintf(buf
+ used
, "\n");
830 static DEVICE_ATTR_RO(chan_xtrigs_out
);
832 static ssize_t
print_chan_list(struct device
*dev
,
833 char *buf
, bool inuse
)
835 struct cti_drvdata
*drvdata
= dev_get_drvdata(dev
->parent
);
836 struct cti_config
*config
= &drvdata
->config
;
838 unsigned long inuse_bits
= 0, chan_mask
;
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
];
846 spin_unlock(&drvdata
->spinlock
);
848 /* inverse bits if printing free channels */
850 inuse_bits
= ~inuse_bits
;
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
);
858 size
= sprintf(buf
, "\n");
862 static ssize_t
chan_inuse_show(struct device
*dev
,
863 struct device_attribute
*attr
,
866 return print_chan_list(dev
, buf
, true);
868 static DEVICE_ATTR_RO(chan_inuse
);
870 static ssize_t
chan_free_show(struct device
*dev
,
871 struct device_attribute
*attr
,
874 return print_chan_list(dev
, buf
, false);
876 static DEVICE_ATTR_RO(chan_free
);
878 static 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
,
899 /* Create the connections trigger groups and attrs dynamically */
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
909 static ssize_t
con_name_show(struct device
*dev
,
910 struct device_attribute
*attr
,
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
;
917 return sprintf(buf
, "%s\n", con
->con_dev_name
);
920 static ssize_t
trigin_sig_show(struct device
*dev
,
921 struct device_attribute
*attr
,
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
;
931 return bitmap_print_to_pagebuf(true, buf
, &mask
, cfg
->nr_trig_max
);
934 static ssize_t
trigout_sig_show(struct device
*dev
,
935 struct device_attribute
*attr
,
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
;
945 return bitmap_print_to_pagebuf(true, buf
, &mask
, cfg
->nr_trig_max
);
948 /* convert a sig type id to a name */
950 cti_sig_type_name(struct cti_trig_con
*con
, int used_count
, bool in
)
953 struct cti_trig_grp
*grp
= in
? con
->con_in
: con
->con_out
;
955 if (used_count
< grp
->nr_sigs
)
956 idx
= grp
->sig_types
[used_count
];
957 return sig_type_names
[idx
];
960 static ssize_t
trigin_type_show(struct device
*dev
,
961 struct device_attribute
*attr
,
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;
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
);
974 used
+= sprintf(buf
+ used
, "\n");
978 static ssize_t
trigout_type_show(struct device
*dev
,
979 struct device_attribute
*attr
,
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;
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
);
992 used
+= sprintf(buf
+ used
, "\n");
997 * Array of show function names declared above to allow selection
998 * for the connection attributes
1000 static p_show_fn show_fns
[CTI_CON_ATTR_MAX
] = {
1008 static int cti_create_con_sysfs_attr(struct device
*dev
,
1009 struct cti_trig_con
*con
,
1010 enum cti_conn_attr_type attr_type
,
1013 struct dev_ext_attribute
*eattr
;
1016 eattr
= devm_kzalloc(dev
, sizeof(struct dev_ext_attribute
),
1019 name
= devm_kstrdup(dev
, con_attr_names
[attr_type
],
1022 /* fill out the underlying attribute struct */
1023 eattr
->attr
.attr
.name
= name
;
1024 eattr
->attr
.attr
.mode
= 0444;
1026 /* now the device_attribute struct */
1027 eattr
->attr
.show
= show_fns
[attr_type
];
1035 con
->con_attrs
[attr_idx
] = &eattr
->attr
.attr
;
1037 * Initialize the dynamically allocated attribute
1038 * to avoid LOCKDEP splat. See include/linux/sysfs.h
1041 sysfs_attr_init(con
->con_attrs
[attr_idx
]);
1046 static struct attribute_group
*
1047 cti_create_con_sysfs_group(struct device
*dev
, struct cti_device
*ctidev
,
1048 int con_idx
, struct cti_trig_con
*tc
)
1050 struct attribute_group
*group
= NULL
;
1053 group
= devm_kzalloc(dev
, sizeof(struct attribute_group
), GFP_KERNEL
);
1057 group
->name
= devm_kasprintf(dev
, GFP_KERNEL
, "triggers%d", con_idx
);
1061 grp_idx
= con_idx
+ CORESIGHT_CTI_STATIC_GROUPS_MAX
- 1;
1062 ctidev
->con_groups
[grp_idx
] = group
;
1063 tc
->attr_group
= group
;
1067 /* create a triggers connection group and the attributes for that group */
1068 static int cti_create_con_attr_set(struct device
*dev
, int con_idx
,
1069 struct cti_device
*ctidev
,
1070 struct cti_trig_con
*tc
)
1072 struct attribute_group
*attr_group
= NULL
;
1076 attr_group
= cti_create_con_sysfs_group(dev
, ctidev
, con_idx
, tc
);
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
);
1086 err
= cti_create_con_sysfs_attr(dev
, tc
, CTI_CON_ATTR_NAME
,
1091 if (tc
->con_in
->nr_sigs
> 0) {
1092 err
= cti_create_con_sysfs_attr(dev
, tc
,
1093 CTI_CON_ATTR_TRIGIN_SIG
,
1098 err
= cti_create_con_sysfs_attr(dev
, tc
,
1099 CTI_CON_ATTR_TRIGIN_TYPES
,
1105 if (tc
->con_out
->nr_sigs
> 0) {
1106 err
= cti_create_con_sysfs_attr(dev
, tc
,
1107 CTI_CON_ATTR_TRIGOUT_SIG
,
1112 err
= cti_create_con_sysfs_attr(dev
, tc
,
1113 CTI_CON_ATTR_TRIGOUT_TYPES
,
1118 attr_group
->attrs
= tc
->con_attrs
;
1122 /* create the array of group pointers for the CTI sysfs groups */
1123 static int cti_create_cons_groups(struct device
*dev
, struct cti_device
*ctidev
)
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
*),
1132 if (!ctidev
->con_groups
)
1137 int cti_create_cons_sysfs(struct device
*dev
, struct cti_drvdata
*drvdata
)
1139 struct cti_device
*ctidev
= &drvdata
->ctidev
;
1140 int err
, con_idx
= 0, i
;
1141 struct cti_trig_con
*tc
;
1143 err
= cti_create_cons_groups(dev
, ctidev
);
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
];
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
);
1160 /* attribute and group sysfs tables. */
1161 static const struct attribute_group coresight_cti_group
= {
1162 .attrs
= coresight_cti_attrs
,
1165 static const struct attribute_group coresight_cti_mgmt_group
= {
1166 .attrs
= coresight_cti_mgmt_attrs
,
1170 static const struct attribute_group coresight_cti_regs_group
= {
1171 .attrs
= coresight_cti_regs_attrs
,
1175 static const struct attribute_group coresight_cti_channels_group
= {
1176 .attrs
= coresight_cti_channel_attrs
,
1180 const struct attribute_group
*
1181 coresight_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
,