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