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