cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

coresight-cti-sysfs.c (33232B)


      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	/*
   1069	 * Initialize the dynamically allocated attribute
   1070	 * to avoid LOCKDEP splat. See include/linux/sysfs.h
   1071	 * for more details.
   1072	 */
   1073	sysfs_attr_init(con->con_attrs[attr_idx]);
   1074
   1075	return 0;
   1076}
   1077
   1078static struct attribute_group *
   1079cti_create_con_sysfs_group(struct device *dev, struct cti_device *ctidev,
   1080			   int con_idx, struct cti_trig_con *tc)
   1081{
   1082	struct attribute_group *group = NULL;
   1083	int grp_idx;
   1084
   1085	group = devm_kzalloc(dev, sizeof(struct attribute_group), GFP_KERNEL);
   1086	if (!group)
   1087		return NULL;
   1088
   1089	group->name = devm_kasprintf(dev, GFP_KERNEL, "triggers%d", con_idx);
   1090	if (!group->name)
   1091		return NULL;
   1092
   1093	grp_idx = con_idx + CORESIGHT_CTI_STATIC_GROUPS_MAX - 1;
   1094	ctidev->con_groups[grp_idx] = group;
   1095	tc->attr_group = group;
   1096	return group;
   1097}
   1098
   1099/* create a triggers connection group and the attributes for that group */
   1100static int cti_create_con_attr_set(struct device *dev, int con_idx,
   1101				   struct cti_device *ctidev,
   1102				   struct cti_trig_con *tc)
   1103{
   1104	struct attribute_group *attr_group = NULL;
   1105	int attr_idx = 0;
   1106	int err = -ENOMEM;
   1107
   1108	attr_group = cti_create_con_sysfs_group(dev, ctidev, con_idx, tc);
   1109	if (!attr_group)
   1110		return -ENOMEM;
   1111
   1112	/* allocate NULL terminated array of attributes */
   1113	tc->con_attrs = devm_kcalloc(dev, CTI_CON_ATTR_MAX + 1,
   1114				     sizeof(struct attribute *), GFP_KERNEL);
   1115	if (!tc->con_attrs)
   1116		return -ENOMEM;
   1117
   1118	err = cti_create_con_sysfs_attr(dev, tc, CTI_CON_ATTR_NAME,
   1119					attr_idx++);
   1120	if (err)
   1121		return err;
   1122
   1123	if (tc->con_in->nr_sigs > 0) {
   1124		err = cti_create_con_sysfs_attr(dev, tc,
   1125						CTI_CON_ATTR_TRIGIN_SIG,
   1126						attr_idx++);
   1127		if (err)
   1128			return err;
   1129
   1130		err = cti_create_con_sysfs_attr(dev, tc,
   1131						CTI_CON_ATTR_TRIGIN_TYPES,
   1132						attr_idx++);
   1133		if (err)
   1134			return err;
   1135	}
   1136
   1137	if (tc->con_out->nr_sigs > 0) {
   1138		err = cti_create_con_sysfs_attr(dev, tc,
   1139						CTI_CON_ATTR_TRIGOUT_SIG,
   1140						attr_idx++);
   1141		if (err)
   1142			return err;
   1143
   1144		err = cti_create_con_sysfs_attr(dev, tc,
   1145						CTI_CON_ATTR_TRIGOUT_TYPES,
   1146						attr_idx++);
   1147		if (err)
   1148			return err;
   1149	}
   1150	attr_group->attrs = tc->con_attrs;
   1151	return 0;
   1152}
   1153
   1154/* create the array of group pointers for the CTI sysfs groups */
   1155static int cti_create_cons_groups(struct device *dev, struct cti_device *ctidev)
   1156{
   1157	int nr_groups;
   1158
   1159	/* nr groups = dynamic + static + NULL terminator */
   1160	nr_groups = ctidev->nr_trig_con + CORESIGHT_CTI_STATIC_GROUPS_MAX;
   1161	ctidev->con_groups = devm_kcalloc(dev, nr_groups,
   1162					  sizeof(struct attribute_group *),
   1163					  GFP_KERNEL);
   1164	if (!ctidev->con_groups)
   1165		return -ENOMEM;
   1166	return 0;
   1167}
   1168
   1169int cti_create_cons_sysfs(struct device *dev, struct cti_drvdata *drvdata)
   1170{
   1171	struct cti_device *ctidev = &drvdata->ctidev;
   1172	int err, con_idx = 0, i;
   1173	struct cti_trig_con *tc;
   1174
   1175	err = cti_create_cons_groups(dev, ctidev);
   1176	if (err)
   1177		return err;
   1178
   1179	/* populate first locations with the static set of groups */
   1180	for (i = 0; i < (CORESIGHT_CTI_STATIC_GROUPS_MAX - 1); i++)
   1181		ctidev->con_groups[i] = coresight_cti_groups[i];
   1182
   1183	/* add dynamic set for each connection */
   1184	list_for_each_entry(tc, &ctidev->trig_cons, node) {
   1185		err = cti_create_con_attr_set(dev, con_idx++, ctidev, tc);
   1186		if (err)
   1187			break;
   1188	}
   1189	return err;
   1190}
   1191
   1192/* attribute and group sysfs tables. */
   1193static const struct attribute_group coresight_cti_group = {
   1194	.attrs = coresight_cti_attrs,
   1195};
   1196
   1197static const struct attribute_group coresight_cti_mgmt_group = {
   1198	.attrs = coresight_cti_mgmt_attrs,
   1199	.name = "mgmt",
   1200};
   1201
   1202static const struct attribute_group coresight_cti_regs_group = {
   1203	.attrs = coresight_cti_regs_attrs,
   1204	.name = "regs",
   1205};
   1206
   1207static const struct attribute_group coresight_cti_channels_group = {
   1208	.attrs = coresight_cti_channel_attrs,
   1209	.name = "channels",
   1210};
   1211
   1212const struct attribute_group *
   1213coresight_cti_groups[CORESIGHT_CTI_STATIC_GROUPS_MAX] = {
   1214	&coresight_cti_group,
   1215	&coresight_cti_mgmt_group,
   1216	&coresight_cti_regs_group,
   1217	&coresight_cti_channels_group,
   1218	NULL,
   1219};