Linux Audio

Check our new training course

In-person Linux kernel drivers training

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