Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
   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};