xref: /linux/drivers/hwtracing/coresight/coresight-cti-sysfs.c (revision cb4eb6771c0f8fd1c52a8f6fdec7762fb087380a)
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