Linux Audio

Check our new training course

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