Linux Audio

Check our new training course

Loading...
v6.2
   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};
v6.13.7
   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	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
  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 = 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}
 128static DEVICE_ATTR_RW(enable);
 129
 130static 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}
 143static DEVICE_ATTR_RO(powered);
 144
 145static 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}
 152static DEVICE_ATTR_RO(ctmid);
 153
 154static 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}
 162static DEVICE_ATTR_RO(nr_trigger_cons);
 163
 164/* attribute and group sysfs tables. */
 165static 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). */
 176static 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). */
 193static __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 */
 239static 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 */
 260static 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 */
 286static 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)			\
 310static 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									\
 319static 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}									\
 327static DEVICE_ATTR_RW(name)
 328
 329static 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
 340static 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}
 357static DEVICE_ATTR_RW(inout_sel);
 358
 359static 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
 374static 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}
 396static DEVICE_ATTR_RW(inen);
 397
 398static 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
 413static 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}
 435static DEVICE_ATTR_RW(outen);
 436
 437static 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}
 449static DEVICE_ATTR_WO(intack);
 450
 451cti_config_reg32_rw(gate, ctigate, CTIGATE);
 452cti_config_reg32_rw(asicctl, asicctl, ASICCTL);
 453cti_config_reg32_rw(appset, ctiappset, CTIAPPSET);
 454
 455static 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}
 477static DEVICE_ATTR_WO(appclear);
 478
 479static 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}
 498static 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 */
 505static 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 */
 534static int
 535cti_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
 552static 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}
 559static DEVICE_ATTR_WO(trigin_attach);
 560
 561static 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}
 568static DEVICE_ATTR_WO(trigin_detach);
 569
 570static 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}
 577static DEVICE_ATTR_WO(trigout_attach);
 578
 579static 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}
 586static DEVICE_ATTR_WO(trigout_detach);
 587
 588
 589static 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
 602static 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}
 618static DEVICE_ATTR_RW(chan_gate_enable);
 619
 620static 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}
 632static DEVICE_ATTR_WO(chan_gate_disable);
 633
 634static int
 635chan_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
 647static 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}
 655static DEVICE_ATTR_WO(chan_set);
 656
 657static 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}
 665static DEVICE_ATTR_WO(chan_clear);
 666
 667static 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}
 675static DEVICE_ATTR_WO(chan_pulse);
 676
 677static 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
 690static 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}
 705static DEVICE_ATTR_RW(trig_filter_enable);
 706
 707static 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}
 720static DEVICE_ATTR_RO(trigout_filtered);
 721
 722/* clear all xtrigger / channel programming */
 723static 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}
 753static 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 */
 759static 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
 777static 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}
 790static DEVICE_ATTR_RW(chan_xtrigs_sel);
 791
 792static 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}
 810static DEVICE_ATTR_RO(chan_xtrigs_in);
 811
 812static 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}
 830static DEVICE_ATTR_RO(chan_xtrigs_out);
 831
 832static 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
 862static 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}
 868static DEVICE_ATTR_RO(chan_inuse);
 869
 870static 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}
 876static DEVICE_ATTR_RO(chan_free);
 877
 878static 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 */
 909static 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
 920static 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
 934static 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 */
 949static const char *
 950cti_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
 960static 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
 978static 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 */
1000static 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
1008static 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
1046static struct attribute_group *
1047cti_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 */
1068static 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 */
1123static 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
1137int 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. */
1161static const struct attribute_group coresight_cti_group = {
1162	.attrs = coresight_cti_attrs,
1163};
1164
1165static const struct attribute_group coresight_cti_mgmt_group = {
1166	.attrs = coresight_cti_mgmt_attrs,
1167	.name = "mgmt",
1168};
1169
1170static const struct attribute_group coresight_cti_regs_group = {
1171	.attrs = coresight_cti_regs_attrs,
1172	.name = "regs",
1173};
1174
1175static const struct attribute_group coresight_cti_channels_group = {
1176	.attrs = coresight_cti_channel_attrs,
1177	.name = "channels",
1178};
1179
1180const struct attribute_group *
1181coresight_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};