Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2019 Linaro Limited, All rights reserved.
0004  * Author: Mike Leach <mike.leach@linaro.org>
0005  */
0006 
0007 #include <linux/atomic.h>
0008 #include <linux/coresight.h>
0009 #include <linux/device.h>
0010 #include <linux/io.h>
0011 #include <linux/kernel.h>
0012 #include <linux/spinlock.h>
0013 #include <linux/sysfs.h>
0014 
0015 #include "coresight-cti.h"
0016 
0017 /*
0018  * Declare the number of static declared attribute groups
0019  * Value includes groups + NULL value at end of table.
0020  */
0021 #define CORESIGHT_CTI_STATIC_GROUPS_MAX 5
0022 
0023 /*
0024  * List of trigger signal type names. Match the constants declared in
0025  * include\dt-bindings\arm\coresight-cti-dt.h
0026  */
0027 static const char * const sig_type_names[] = {
0028     "genio",    /* GEN_IO */
0029     "intreq",   /* GEN_INTREQ */
0030     "intack",   /* GEN_INTACK */
0031     "haltreq",  /* GEN_HALTREQ */
0032     "restartreq",   /* GEN_RESTARTREQ */
0033     "pe_edbgreq",   /* PE_EDBGREQ */
0034     "pe_dbgrestart",/* PE_DBGRESTART */
0035     "pe_ctiirq",    /* PE_CTIIRQ */
0036     "pe_pmuirq",    /* PE_PMUIRQ */
0037     "pe_dbgtrigger",/* PE_DBGTRIGGER */
0038     "etm_extout",   /* ETM_EXTOUT */
0039     "etm_extin",    /* ETM_EXTIN */
0040     "snk_full", /* SNK_FULL */
0041     "snk_acqcomp",  /* SNK_ACQCOMP */
0042     "snk_flushcomp",/* SNK_FLUSHCOMP */
0043     "snk_flushin",  /* SNK_FLUSHIN */
0044     "snk_trigin",   /* SNK_TRIGIN */
0045     "stm_asyncout", /* STM_ASYNCOUT */
0046     "stm_tout_spte",/* STM_TOUT_SPTE */
0047     "stm_tout_sw",  /* STM_TOUT_SW */
0048     "stm_tout_hete",/* STM_TOUT_HETE */
0049     "stm_hwevent",  /* STM_HWEVENT */
0050     "ela_tstart",   /* ELA_TSTART */
0051     "ela_tstop",    /* ELA_TSTOP */
0052     "ela_dbgreq",   /* ELA_DBGREQ */
0053 };
0054 
0055 /* Show function pointer used in the connections dynamic declared attributes*/
0056 typedef ssize_t (*p_show_fn)(struct device *dev, struct device_attribute *attr,
0057                  char *buf);
0058 
0059 /* Connection attribute types */
0060 enum cti_conn_attr_type {
0061     CTI_CON_ATTR_NAME,
0062     CTI_CON_ATTR_TRIGIN_SIG,
0063     CTI_CON_ATTR_TRIGOUT_SIG,
0064     CTI_CON_ATTR_TRIGIN_TYPES,
0065     CTI_CON_ATTR_TRIGOUT_TYPES,
0066     CTI_CON_ATTR_MAX,
0067 };
0068 
0069 /* Names for the connection attributes */
0070 static const char * const con_attr_names[CTI_CON_ATTR_MAX] = {
0071     "name",
0072     "in_signals",
0073     "out_signals",
0074     "in_types",
0075     "out_types",
0076 };
0077 
0078 /* basic attributes */
0079 static ssize_t enable_show(struct device *dev,
0080                struct device_attribute *attr,
0081                char *buf)
0082 {
0083     int enable_req;
0084     bool enabled, powered;
0085     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0086 
0087     enable_req = atomic_read(&drvdata->config.enable_req_count);
0088     spin_lock(&drvdata->spinlock);
0089     powered = drvdata->config.hw_powered;
0090     enabled = drvdata->config.hw_enabled;
0091     spin_unlock(&drvdata->spinlock);
0092 
0093     if (powered)
0094         return sprintf(buf, "%d\n", enabled);
0095     else
0096         return sprintf(buf, "%d\n", !!enable_req);
0097 }
0098 
0099 static ssize_t enable_store(struct device *dev,
0100                 struct device_attribute *attr,
0101                 const char *buf, size_t size)
0102 {
0103     int ret = 0;
0104     unsigned long val;
0105     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0106 
0107     ret = kstrtoul(buf, 0, &val);
0108     if (ret)
0109         return ret;
0110 
0111     if (val)
0112         ret = cti_enable(drvdata->csdev);
0113     else
0114         ret = cti_disable(drvdata->csdev);
0115     if (ret)
0116         return ret;
0117     return size;
0118 }
0119 static DEVICE_ATTR_RW(enable);
0120 
0121 static ssize_t powered_show(struct device *dev,
0122                 struct device_attribute *attr,
0123                 char *buf)
0124 {
0125     bool powered;
0126     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0127 
0128     spin_lock(&drvdata->spinlock);
0129     powered = drvdata->config.hw_powered;
0130     spin_unlock(&drvdata->spinlock);
0131 
0132     return sprintf(buf, "%d\n", powered);
0133 }
0134 static DEVICE_ATTR_RO(powered);
0135 
0136 static ssize_t ctmid_show(struct device *dev,
0137               struct device_attribute *attr, char *buf)
0138 {
0139     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0140 
0141     return sprintf(buf, "%d\n", drvdata->ctidev.ctm_id);
0142 }
0143 static DEVICE_ATTR_RO(ctmid);
0144 
0145 static ssize_t nr_trigger_cons_show(struct device *dev,
0146                     struct device_attribute *attr,
0147                     char *buf)
0148 {
0149     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0150 
0151     return sprintf(buf, "%d\n", drvdata->ctidev.nr_trig_con);
0152 }
0153 static DEVICE_ATTR_RO(nr_trigger_cons);
0154 
0155 /* attribute and group sysfs tables. */
0156 static struct attribute *coresight_cti_attrs[] = {
0157     &dev_attr_enable.attr,
0158     &dev_attr_powered.attr,
0159     &dev_attr_ctmid.attr,
0160     &dev_attr_nr_trigger_cons.attr,
0161     NULL,
0162 };
0163 
0164 /* register based attributes */
0165 
0166 /* macro to access RO registers with power check only (no enable check). */
0167 #define coresight_cti_reg(name, offset)         \
0168 static ssize_t name##_show(struct device *dev,              \
0169                struct device_attribute *attr, char *buf)    \
0170 {                                   \
0171     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
0172     u32 val = 0;                            \
0173     pm_runtime_get_sync(dev->parent);               \
0174     spin_lock(&drvdata->spinlock);                  \
0175     if (drvdata->config.hw_powered)                 \
0176         val = readl_relaxed(drvdata->base + offset);        \
0177     spin_unlock(&drvdata->spinlock);                \
0178     pm_runtime_put_sync(dev->parent);               \
0179     return sprintf(buf, "0x%x\n", val);             \
0180 }                                   \
0181 static DEVICE_ATTR_RO(name)
0182 
0183 /* coresight management registers */
0184 coresight_cti_reg(devaff0, CTIDEVAFF0);
0185 coresight_cti_reg(devaff1, CTIDEVAFF1);
0186 coresight_cti_reg(authstatus, CORESIGHT_AUTHSTATUS);
0187 coresight_cti_reg(devarch, CORESIGHT_DEVARCH);
0188 coresight_cti_reg(devid, CORESIGHT_DEVID);
0189 coresight_cti_reg(devtype, CORESIGHT_DEVTYPE);
0190 coresight_cti_reg(pidr0, CORESIGHT_PERIPHIDR0);
0191 coresight_cti_reg(pidr1, CORESIGHT_PERIPHIDR1);
0192 coresight_cti_reg(pidr2, CORESIGHT_PERIPHIDR2);
0193 coresight_cti_reg(pidr3, CORESIGHT_PERIPHIDR3);
0194 coresight_cti_reg(pidr4, CORESIGHT_PERIPHIDR4);
0195 
0196 static struct attribute *coresight_cti_mgmt_attrs[] = {
0197     &dev_attr_devaff0.attr,
0198     &dev_attr_devaff1.attr,
0199     &dev_attr_authstatus.attr,
0200     &dev_attr_devarch.attr,
0201     &dev_attr_devid.attr,
0202     &dev_attr_devtype.attr,
0203     &dev_attr_pidr0.attr,
0204     &dev_attr_pidr1.attr,
0205     &dev_attr_pidr2.attr,
0206     &dev_attr_pidr3.attr,
0207     &dev_attr_pidr4.attr,
0208     NULL,
0209 };
0210 
0211 /* CTI low level programming registers */
0212 
0213 /*
0214  * Show a simple 32 bit value if enabled and powered.
0215  * If inaccessible & pcached_val not NULL then show cached value.
0216  */
0217 static ssize_t cti_reg32_show(struct device *dev, char *buf,
0218                   u32 *pcached_val, int reg_offset)
0219 {
0220     u32 val = 0;
0221     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0222     struct cti_config *config = &drvdata->config;
0223 
0224     spin_lock(&drvdata->spinlock);
0225     if ((reg_offset >= 0) && cti_active(config)) {
0226         CS_UNLOCK(drvdata->base);
0227         val = readl_relaxed(drvdata->base + reg_offset);
0228         if (pcached_val)
0229             *pcached_val = val;
0230         CS_LOCK(drvdata->base);
0231     } else if (pcached_val) {
0232         val = *pcached_val;
0233     }
0234     spin_unlock(&drvdata->spinlock);
0235     return sprintf(buf, "%#x\n", val);
0236 }
0237 
0238 /*
0239  * Store a simple 32 bit value.
0240  * If pcached_val not NULL, then copy to here too,
0241  * if reg_offset >= 0 then write through if enabled.
0242  */
0243 static ssize_t cti_reg32_store(struct device *dev, const char *buf,
0244                    size_t size, u32 *pcached_val, int reg_offset)
0245 {
0246     unsigned long val;
0247     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0248     struct cti_config *config = &drvdata->config;
0249 
0250     if (kstrtoul(buf, 0, &val))
0251         return -EINVAL;
0252 
0253     spin_lock(&drvdata->spinlock);
0254     /* local store */
0255     if (pcached_val)
0256         *pcached_val = (u32)val;
0257 
0258     /* write through if offset and enabled */
0259     if ((reg_offset >= 0) && cti_active(config))
0260         cti_write_single_reg(drvdata, reg_offset, val);
0261     spin_unlock(&drvdata->spinlock);
0262     return size;
0263 }
0264 
0265 /* Standard macro for simple rw cti config registers */
0266 #define cti_config_reg32_rw(name, cfgname, offset)          \
0267 static ssize_t name##_show(struct device *dev,              \
0268                struct device_attribute *attr,       \
0269                char *buf)                   \
0270 {                                   \
0271     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
0272     return cti_reg32_show(dev, buf,                 \
0273                   &drvdata->config.cfgname, offset);    \
0274 }                                   \
0275                                     \
0276 static ssize_t name##_store(struct device *dev,             \
0277                 struct device_attribute *attr,      \
0278                 const char *buf, size_t size)       \
0279 {                                   \
0280     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
0281     return cti_reg32_store(dev, buf, size,              \
0282                    &drvdata->config.cfgname, offset);   \
0283 }                                   \
0284 static DEVICE_ATTR_RW(name)
0285 
0286 static ssize_t inout_sel_show(struct device *dev,
0287                   struct device_attribute *attr,
0288                   char *buf)
0289 {
0290     u32 val;
0291     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0292 
0293     val = (u32)drvdata->config.ctiinout_sel;
0294     return sprintf(buf, "%d\n", val);
0295 }
0296 
0297 static ssize_t inout_sel_store(struct device *dev,
0298                    struct device_attribute *attr,
0299                    const char *buf, size_t size)
0300 {
0301     unsigned long val;
0302     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0303 
0304     if (kstrtoul(buf, 0, &val))
0305         return -EINVAL;
0306     if (val > (CTIINOUTEN_MAX - 1))
0307         return -EINVAL;
0308 
0309     spin_lock(&drvdata->spinlock);
0310     drvdata->config.ctiinout_sel = val;
0311     spin_unlock(&drvdata->spinlock);
0312     return size;
0313 }
0314 static DEVICE_ATTR_RW(inout_sel);
0315 
0316 static ssize_t inen_show(struct device *dev,
0317              struct device_attribute *attr,
0318              char *buf)
0319 {
0320     unsigned long val;
0321     int index;
0322     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0323 
0324     spin_lock(&drvdata->spinlock);
0325     index = drvdata->config.ctiinout_sel;
0326     val = drvdata->config.ctiinen[index];
0327     spin_unlock(&drvdata->spinlock);
0328     return sprintf(buf, "%#lx\n", val);
0329 }
0330 
0331 static ssize_t inen_store(struct device *dev,
0332               struct device_attribute *attr,
0333               const char *buf, size_t size)
0334 {
0335     unsigned long val;
0336     int index;
0337     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0338     struct cti_config *config = &drvdata->config;
0339 
0340     if (kstrtoul(buf, 0, &val))
0341         return -EINVAL;
0342 
0343     spin_lock(&drvdata->spinlock);
0344     index = config->ctiinout_sel;
0345     config->ctiinen[index] = val;
0346 
0347     /* write through if enabled */
0348     if (cti_active(config))
0349         cti_write_single_reg(drvdata, CTIINEN(index), val);
0350     spin_unlock(&drvdata->spinlock);
0351     return size;
0352 }
0353 static DEVICE_ATTR_RW(inen);
0354 
0355 static ssize_t outen_show(struct device *dev,
0356               struct device_attribute *attr,
0357               char *buf)
0358 {
0359     unsigned long val;
0360     int index;
0361     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0362 
0363     spin_lock(&drvdata->spinlock);
0364     index = drvdata->config.ctiinout_sel;
0365     val = drvdata->config.ctiouten[index];
0366     spin_unlock(&drvdata->spinlock);
0367     return sprintf(buf, "%#lx\n", val);
0368 }
0369 
0370 static ssize_t outen_store(struct device *dev,
0371                struct device_attribute *attr,
0372                const char *buf, size_t size)
0373 {
0374     unsigned long val;
0375     int index;
0376     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0377     struct cti_config *config = &drvdata->config;
0378 
0379     if (kstrtoul(buf, 0, &val))
0380         return -EINVAL;
0381 
0382     spin_lock(&drvdata->spinlock);
0383     index = config->ctiinout_sel;
0384     config->ctiouten[index] = val;
0385 
0386     /* write through if enabled */
0387     if (cti_active(config))
0388         cti_write_single_reg(drvdata, CTIOUTEN(index), val);
0389     spin_unlock(&drvdata->spinlock);
0390     return size;
0391 }
0392 static DEVICE_ATTR_RW(outen);
0393 
0394 static ssize_t intack_store(struct device *dev,
0395                 struct device_attribute *attr,
0396                 const char *buf, size_t size)
0397 {
0398     unsigned long val;
0399 
0400     if (kstrtoul(buf, 0, &val))
0401         return -EINVAL;
0402 
0403     cti_write_intack(dev, val);
0404     return size;
0405 }
0406 static DEVICE_ATTR_WO(intack);
0407 
0408 cti_config_reg32_rw(gate, ctigate, CTIGATE);
0409 cti_config_reg32_rw(asicctl, asicctl, ASICCTL);
0410 cti_config_reg32_rw(appset, ctiappset, CTIAPPSET);
0411 
0412 static ssize_t appclear_store(struct device *dev,
0413                   struct device_attribute *attr,
0414                   const char *buf, size_t size)
0415 {
0416     unsigned long val;
0417     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0418     struct cti_config *config = &drvdata->config;
0419 
0420     if (kstrtoul(buf, 0, &val))
0421         return -EINVAL;
0422 
0423     spin_lock(&drvdata->spinlock);
0424 
0425     /* a 1'b1 in appclr clears down the same bit in appset*/
0426     config->ctiappset &= ~val;
0427 
0428     /* write through if enabled */
0429     if (cti_active(config))
0430         cti_write_single_reg(drvdata, CTIAPPCLEAR, val);
0431     spin_unlock(&drvdata->spinlock);
0432     return size;
0433 }
0434 static DEVICE_ATTR_WO(appclear);
0435 
0436 static ssize_t apppulse_store(struct device *dev,
0437                   struct device_attribute *attr,
0438                   const char *buf, size_t size)
0439 {
0440     unsigned long val;
0441     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0442     struct cti_config *config = &drvdata->config;
0443 
0444     if (kstrtoul(buf, 0, &val))
0445         return -EINVAL;
0446 
0447     spin_lock(&drvdata->spinlock);
0448 
0449     /* write through if enabled */
0450     if (cti_active(config))
0451         cti_write_single_reg(drvdata, CTIAPPPULSE, val);
0452     spin_unlock(&drvdata->spinlock);
0453     return size;
0454 }
0455 static DEVICE_ATTR_WO(apppulse);
0456 
0457 coresight_cti_reg(triginstatus, CTITRIGINSTATUS);
0458 coresight_cti_reg(trigoutstatus, CTITRIGOUTSTATUS);
0459 coresight_cti_reg(chinstatus, CTICHINSTATUS);
0460 coresight_cti_reg(choutstatus, CTICHOUTSTATUS);
0461 
0462 /*
0463  * Define CONFIG_CORESIGHT_CTI_INTEGRATION_REGS to enable the access to the
0464  * integration control registers. Normally only used to investigate connection
0465  * data.
0466  */
0467 #ifdef CONFIG_CORESIGHT_CTI_INTEGRATION_REGS
0468 
0469 /* macro to access RW registers with power check only (no enable check). */
0470 #define coresight_cti_reg_rw(name, offset)              \
0471 static ssize_t name##_show(struct device *dev,              \
0472                struct device_attribute *attr, char *buf)    \
0473 {                                   \
0474     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
0475     u32 val = 0;                            \
0476     pm_runtime_get_sync(dev->parent);               \
0477     spin_lock(&drvdata->spinlock);                  \
0478     if (drvdata->config.hw_powered)                 \
0479         val = readl_relaxed(drvdata->base + offset);        \
0480     spin_unlock(&drvdata->spinlock);                \
0481     pm_runtime_put_sync(dev->parent);               \
0482     return sprintf(buf, "0x%x\n", val);             \
0483 }                                   \
0484                                     \
0485 static ssize_t name##_store(struct device *dev,             \
0486                 struct device_attribute *attr,      \
0487                 const char *buf, size_t size)       \
0488 {                                   \
0489     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
0490     unsigned long val = 0;                      \
0491     if (kstrtoul(buf, 0, &val))                 \
0492         return -EINVAL;                     \
0493                                     \
0494     pm_runtime_get_sync(dev->parent);               \
0495     spin_lock(&drvdata->spinlock);                  \
0496     if (drvdata->config.hw_powered)                 \
0497         cti_write_single_reg(drvdata, offset, val);     \
0498     spin_unlock(&drvdata->spinlock);                \
0499     pm_runtime_put_sync(dev->parent);               \
0500     return size;                            \
0501 }                                   \
0502 static DEVICE_ATTR_RW(name)
0503 
0504 /* macro to access WO registers with power check only (no enable check). */
0505 #define coresight_cti_reg_wo(name, offset)              \
0506 static ssize_t name##_store(struct device *dev,             \
0507                 struct device_attribute *attr,      \
0508                 const char *buf, size_t size)       \
0509 {                                   \
0510     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); \
0511     unsigned long val = 0;                      \
0512     if (kstrtoul(buf, 0, &val))                 \
0513         return -EINVAL;                     \
0514                                     \
0515     pm_runtime_get_sync(dev->parent);               \
0516     spin_lock(&drvdata->spinlock);                  \
0517     if (drvdata->config.hw_powered)                 \
0518         cti_write_single_reg(drvdata, offset, val);     \
0519     spin_unlock(&drvdata->spinlock);                \
0520     pm_runtime_put_sync(dev->parent);               \
0521     return size;                            \
0522 }                                   \
0523 static DEVICE_ATTR_WO(name)
0524 
0525 coresight_cti_reg_rw(itchout, ITCHOUT);
0526 coresight_cti_reg_rw(ittrigout, ITTRIGOUT);
0527 coresight_cti_reg_rw(itctrl, CORESIGHT_ITCTRL);
0528 coresight_cti_reg_wo(itchinack, ITCHINACK);
0529 coresight_cti_reg_wo(ittriginack, ITTRIGINACK);
0530 coresight_cti_reg(ittrigin, ITTRIGIN);
0531 coresight_cti_reg(itchin, ITCHIN);
0532 coresight_cti_reg(itchoutack, ITCHOUTACK);
0533 coresight_cti_reg(ittrigoutack, ITTRIGOUTACK);
0534 
0535 #endif /* CORESIGHT_CTI_INTEGRATION_REGS */
0536 
0537 static struct attribute *coresight_cti_regs_attrs[] = {
0538     &dev_attr_inout_sel.attr,
0539     &dev_attr_inen.attr,
0540     &dev_attr_outen.attr,
0541     &dev_attr_gate.attr,
0542     &dev_attr_asicctl.attr,
0543     &dev_attr_intack.attr,
0544     &dev_attr_appset.attr,
0545     &dev_attr_appclear.attr,
0546     &dev_attr_apppulse.attr,
0547     &dev_attr_triginstatus.attr,
0548     &dev_attr_trigoutstatus.attr,
0549     &dev_attr_chinstatus.attr,
0550     &dev_attr_choutstatus.attr,
0551 #ifdef CONFIG_CORESIGHT_CTI_INTEGRATION_REGS
0552     &dev_attr_itctrl.attr,
0553     &dev_attr_ittrigin.attr,
0554     &dev_attr_itchin.attr,
0555     &dev_attr_ittrigout.attr,
0556     &dev_attr_itchout.attr,
0557     &dev_attr_itchoutack.attr,
0558     &dev_attr_ittrigoutack.attr,
0559     &dev_attr_ittriginack.attr,
0560     &dev_attr_itchinack.attr,
0561 #endif
0562     NULL,
0563 };
0564 
0565 /* CTI channel x-trigger programming */
0566 static int
0567 cti_trig_op_parse(struct device *dev, enum cti_chan_op op,
0568           enum cti_trig_dir dir, const char *buf, size_t size)
0569 {
0570     u32 chan_idx;
0571     u32 trig_idx;
0572     int items, err = -EINVAL;
0573 
0574     /* extract chan idx and trigger idx */
0575     items = sscanf(buf, "%d %d", &chan_idx, &trig_idx);
0576     if (items == 2) {
0577         err = cti_channel_trig_op(dev, op, dir, chan_idx, trig_idx);
0578         if (!err)
0579             err = size;
0580     }
0581     return err;
0582 }
0583 
0584 static ssize_t trigin_attach_store(struct device *dev,
0585                    struct device_attribute *attr,
0586                    const char *buf, size_t size)
0587 {
0588     return cti_trig_op_parse(dev, CTI_CHAN_ATTACH, CTI_TRIG_IN,
0589                  buf, size);
0590 }
0591 static DEVICE_ATTR_WO(trigin_attach);
0592 
0593 static ssize_t trigin_detach_store(struct device *dev,
0594                    struct device_attribute *attr,
0595                    const char *buf, size_t size)
0596 {
0597     return cti_trig_op_parse(dev, CTI_CHAN_DETACH, CTI_TRIG_IN,
0598                  buf, size);
0599 }
0600 static DEVICE_ATTR_WO(trigin_detach);
0601 
0602 static ssize_t trigout_attach_store(struct device *dev,
0603                     struct device_attribute *attr,
0604                     const char *buf, size_t size)
0605 {
0606     return cti_trig_op_parse(dev, CTI_CHAN_ATTACH, CTI_TRIG_OUT,
0607                  buf, size);
0608 }
0609 static DEVICE_ATTR_WO(trigout_attach);
0610 
0611 static ssize_t trigout_detach_store(struct device *dev,
0612                     struct device_attribute *attr,
0613                     const char *buf, size_t size)
0614 {
0615     return cti_trig_op_parse(dev, CTI_CHAN_DETACH, CTI_TRIG_OUT,
0616                  buf, size);
0617 }
0618 static DEVICE_ATTR_WO(trigout_detach);
0619 
0620 
0621 static ssize_t chan_gate_enable_store(struct device *dev,
0622                       struct device_attribute *attr,
0623                       const char *buf, size_t size)
0624 {
0625     int err = 0, channel = 0;
0626 
0627     if (kstrtoint(buf, 0, &channel))
0628         return -EINVAL;
0629 
0630     err = cti_channel_gate_op(dev, CTI_GATE_CHAN_ENABLE, channel);
0631     return err ? err : size;
0632 }
0633 
0634 static ssize_t chan_gate_enable_show(struct device *dev,
0635                      struct device_attribute *attr,
0636                      char *buf)
0637 {
0638     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0639     struct cti_config *cfg = &drvdata->config;
0640     unsigned long ctigate_bitmask = cfg->ctigate;
0641     int size = 0;
0642 
0643     if (cfg->ctigate == 0)
0644         size = sprintf(buf, "\n");
0645     else
0646         size = bitmap_print_to_pagebuf(true, buf, &ctigate_bitmask,
0647                            cfg->nr_ctm_channels);
0648     return size;
0649 }
0650 static DEVICE_ATTR_RW(chan_gate_enable);
0651 
0652 static ssize_t chan_gate_disable_store(struct device *dev,
0653                        struct device_attribute *attr,
0654                        const char *buf, size_t size)
0655 {
0656     int err = 0, channel = 0;
0657 
0658     if (kstrtoint(buf, 0, &channel))
0659         return -EINVAL;
0660 
0661     err = cti_channel_gate_op(dev, CTI_GATE_CHAN_DISABLE, channel);
0662     return err ? err : size;
0663 }
0664 static DEVICE_ATTR_WO(chan_gate_disable);
0665 
0666 static int
0667 chan_op_parse(struct device *dev, enum cti_chan_set_op op, const char *buf)
0668 {
0669     int err = 0, channel = 0;
0670 
0671     if (kstrtoint(buf, 0, &channel))
0672         return -EINVAL;
0673 
0674     err = cti_channel_setop(dev, op, channel);
0675     return err;
0676 
0677 }
0678 
0679 static ssize_t chan_set_store(struct device *dev,
0680                   struct device_attribute *attr,
0681                   const char *buf, size_t size)
0682 {
0683     int err = chan_op_parse(dev, CTI_CHAN_SET, buf);
0684 
0685     return err ? err : size;
0686 }
0687 static DEVICE_ATTR_WO(chan_set);
0688 
0689 static ssize_t chan_clear_store(struct device *dev,
0690                 struct device_attribute *attr,
0691                 const char *buf, size_t size)
0692 {
0693     int err = chan_op_parse(dev, CTI_CHAN_CLR, buf);
0694 
0695     return err ? err : size;
0696 }
0697 static DEVICE_ATTR_WO(chan_clear);
0698 
0699 static ssize_t chan_pulse_store(struct device *dev,
0700                 struct device_attribute *attr,
0701                 const char *buf, size_t size)
0702 {
0703     int err = chan_op_parse(dev, CTI_CHAN_PULSE, buf);
0704 
0705     return err ? err : size;
0706 }
0707 static DEVICE_ATTR_WO(chan_pulse);
0708 
0709 static ssize_t trig_filter_enable_show(struct device *dev,
0710                        struct device_attribute *attr,
0711                        char *buf)
0712 {
0713     u32 val;
0714     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0715 
0716     spin_lock(&drvdata->spinlock);
0717     val = drvdata->config.trig_filter_enable;
0718     spin_unlock(&drvdata->spinlock);
0719     return sprintf(buf, "%d\n", val);
0720 }
0721 
0722 static ssize_t trig_filter_enable_store(struct device *dev,
0723                     struct device_attribute *attr,
0724                     const char *buf, size_t size)
0725 {
0726     unsigned long val;
0727     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0728 
0729     if (kstrtoul(buf, 0, &val))
0730         return -EINVAL;
0731 
0732     spin_lock(&drvdata->spinlock);
0733     drvdata->config.trig_filter_enable = !!val;
0734     spin_unlock(&drvdata->spinlock);
0735     return size;
0736 }
0737 static DEVICE_ATTR_RW(trig_filter_enable);
0738 
0739 static ssize_t trigout_filtered_show(struct device *dev,
0740                      struct device_attribute *attr,
0741                      char *buf)
0742 {
0743     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0744     struct cti_config *cfg = &drvdata->config;
0745     int size = 0, nr_trig_max = cfg->nr_trig_max;
0746     unsigned long mask = cfg->trig_out_filter;
0747 
0748     if (mask)
0749         size = bitmap_print_to_pagebuf(true, buf, &mask, nr_trig_max);
0750     return size;
0751 }
0752 static DEVICE_ATTR_RO(trigout_filtered);
0753 
0754 /* clear all xtrigger / channel programming */
0755 static ssize_t chan_xtrigs_reset_store(struct device *dev,
0756                        struct device_attribute *attr,
0757                        const char *buf, size_t size)
0758 {
0759     int i;
0760     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0761     struct cti_config *config = &drvdata->config;
0762 
0763     spin_lock(&drvdata->spinlock);
0764 
0765     /* clear the CTI trigger / channel programming registers */
0766     for (i = 0; i < config->nr_trig_max; i++) {
0767         config->ctiinen[i] = 0;
0768         config->ctiouten[i] = 0;
0769     }
0770 
0771     /* clear the other regs */
0772     config->ctigate = GENMASK(config->nr_ctm_channels - 1, 0);
0773     config->asicctl = 0;
0774     config->ctiappset = 0;
0775     config->ctiinout_sel = 0;
0776     config->xtrig_rchan_sel = 0;
0777 
0778     /* if enabled then write through */
0779     if (cti_active(config))
0780         cti_write_all_hw_regs(drvdata);
0781 
0782     spin_unlock(&drvdata->spinlock);
0783     return size;
0784 }
0785 static DEVICE_ATTR_WO(chan_xtrigs_reset);
0786 
0787 /*
0788  * Write to select a channel to view, read to display the
0789  * cross triggers for the selected channel.
0790  */
0791 static ssize_t chan_xtrigs_sel_store(struct device *dev,
0792                      struct device_attribute *attr,
0793                      const char *buf, size_t size)
0794 {
0795     unsigned long val;
0796     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0797 
0798     if (kstrtoul(buf, 0, &val))
0799         return -EINVAL;
0800     if (val > (drvdata->config.nr_ctm_channels - 1))
0801         return -EINVAL;
0802 
0803     spin_lock(&drvdata->spinlock);
0804     drvdata->config.xtrig_rchan_sel = val;
0805     spin_unlock(&drvdata->spinlock);
0806     return size;
0807 }
0808 
0809 static ssize_t chan_xtrigs_sel_show(struct device *dev,
0810                     struct device_attribute *attr,
0811                     char *buf)
0812 {
0813     unsigned long val;
0814     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0815 
0816     spin_lock(&drvdata->spinlock);
0817     val = drvdata->config.xtrig_rchan_sel;
0818     spin_unlock(&drvdata->spinlock);
0819 
0820     return sprintf(buf, "%ld\n", val);
0821 }
0822 static DEVICE_ATTR_RW(chan_xtrigs_sel);
0823 
0824 static ssize_t chan_xtrigs_in_show(struct device *dev,
0825                    struct device_attribute *attr,
0826                    char *buf)
0827 {
0828     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0829     struct cti_config *cfg = &drvdata->config;
0830     int used = 0, reg_idx;
0831     int nr_trig_max = drvdata->config.nr_trig_max;
0832     u32 chan_mask = BIT(cfg->xtrig_rchan_sel);
0833 
0834     for (reg_idx = 0; reg_idx < nr_trig_max; reg_idx++) {
0835         if (chan_mask & cfg->ctiinen[reg_idx])
0836             used += sprintf(buf + used, "%d ", reg_idx);
0837     }
0838 
0839     used += sprintf(buf + used, "\n");
0840     return used;
0841 }
0842 static DEVICE_ATTR_RO(chan_xtrigs_in);
0843 
0844 static ssize_t chan_xtrigs_out_show(struct device *dev,
0845                     struct device_attribute *attr,
0846                     char *buf)
0847 {
0848     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0849     struct cti_config *cfg = &drvdata->config;
0850     int used = 0, reg_idx;
0851     int nr_trig_max = drvdata->config.nr_trig_max;
0852     u32 chan_mask = BIT(cfg->xtrig_rchan_sel);
0853 
0854     for (reg_idx = 0; reg_idx < nr_trig_max; reg_idx++) {
0855         if (chan_mask & cfg->ctiouten[reg_idx])
0856             used += sprintf(buf + used, "%d ", reg_idx);
0857     }
0858 
0859     used += sprintf(buf + used, "\n");
0860     return used;
0861 }
0862 static DEVICE_ATTR_RO(chan_xtrigs_out);
0863 
0864 static ssize_t print_chan_list(struct device *dev,
0865                    char *buf, bool inuse)
0866 {
0867     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0868     struct cti_config *config = &drvdata->config;
0869     int size, i;
0870     unsigned long inuse_bits = 0, chan_mask;
0871 
0872     /* scan regs to get bitmap of channels in use. */
0873     spin_lock(&drvdata->spinlock);
0874     for (i = 0; i < config->nr_trig_max; i++) {
0875         inuse_bits |= config->ctiinen[i];
0876         inuse_bits |= config->ctiouten[i];
0877     }
0878     spin_unlock(&drvdata->spinlock);
0879 
0880     /* inverse bits if printing free channels */
0881     if (!inuse)
0882         inuse_bits = ~inuse_bits;
0883 
0884     /* list of channels, or 'none' */
0885     chan_mask = GENMASK(config->nr_ctm_channels - 1, 0);
0886     if (inuse_bits & chan_mask)
0887         size = bitmap_print_to_pagebuf(true, buf, &inuse_bits,
0888                            config->nr_ctm_channels);
0889     else
0890         size = sprintf(buf, "\n");
0891     return size;
0892 }
0893 
0894 static ssize_t chan_inuse_show(struct device *dev,
0895                    struct device_attribute *attr,
0896                    char *buf)
0897 {
0898     return print_chan_list(dev, buf, true);
0899 }
0900 static DEVICE_ATTR_RO(chan_inuse);
0901 
0902 static ssize_t chan_free_show(struct device *dev,
0903                   struct device_attribute *attr,
0904                   char *buf)
0905 {
0906     return print_chan_list(dev, buf, false);
0907 }
0908 static DEVICE_ATTR_RO(chan_free);
0909 
0910 static struct attribute *coresight_cti_channel_attrs[] = {
0911     &dev_attr_trigin_attach.attr,
0912     &dev_attr_trigin_detach.attr,
0913     &dev_attr_trigout_attach.attr,
0914     &dev_attr_trigout_detach.attr,
0915     &dev_attr_trig_filter_enable.attr,
0916     &dev_attr_trigout_filtered.attr,
0917     &dev_attr_chan_gate_enable.attr,
0918     &dev_attr_chan_gate_disable.attr,
0919     &dev_attr_chan_set.attr,
0920     &dev_attr_chan_clear.attr,
0921     &dev_attr_chan_pulse.attr,
0922     &dev_attr_chan_inuse.attr,
0923     &dev_attr_chan_free.attr,
0924     &dev_attr_chan_xtrigs_sel.attr,
0925     &dev_attr_chan_xtrigs_in.attr,
0926     &dev_attr_chan_xtrigs_out.attr,
0927     &dev_attr_chan_xtrigs_reset.attr,
0928     NULL,
0929 };
0930 
0931 /* Create the connections trigger groups and attrs dynamically */
0932 /*
0933  * Each connection has dynamic group triggers<N> + name, trigin/out sigs/types
0934  * attributes, + each device has static nr_trigger_cons giving the number
0935  * of groups. e.g. in sysfs:-
0936  * /cti_<name>/triggers0
0937  * /cti_<name>/triggers1
0938  * /cti_<name>/nr_trigger_cons
0939  * where nr_trigger_cons = 2
0940  */
0941 static ssize_t con_name_show(struct device *dev,
0942                  struct device_attribute *attr,
0943                  char *buf)
0944 {
0945     struct dev_ext_attribute *ext_attr =
0946         container_of(attr, struct dev_ext_attribute, attr);
0947     struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
0948 
0949     return sprintf(buf, "%s\n", con->con_dev_name);
0950 }
0951 
0952 static ssize_t trigin_sig_show(struct device *dev,
0953                    struct device_attribute *attr,
0954                    char *buf)
0955 {
0956     struct dev_ext_attribute *ext_attr =
0957         container_of(attr, struct dev_ext_attribute, attr);
0958     struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
0959     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0960     struct cti_config *cfg = &drvdata->config;
0961     unsigned long mask = con->con_in->used_mask;
0962 
0963     return bitmap_print_to_pagebuf(true, buf, &mask, cfg->nr_trig_max);
0964 }
0965 
0966 static ssize_t trigout_sig_show(struct device *dev,
0967                 struct device_attribute *attr,
0968                 char *buf)
0969 {
0970     struct dev_ext_attribute *ext_attr =
0971         container_of(attr, struct dev_ext_attribute, attr);
0972     struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
0973     struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
0974     struct cti_config *cfg = &drvdata->config;
0975     unsigned long mask = con->con_out->used_mask;
0976 
0977     return bitmap_print_to_pagebuf(true, buf, &mask, cfg->nr_trig_max);
0978 }
0979 
0980 /* convert a sig type id to a name */
0981 static const char *
0982 cti_sig_type_name(struct cti_trig_con *con, int used_count, bool in)
0983 {
0984     int idx = 0;
0985     struct cti_trig_grp *grp = in ? con->con_in : con->con_out;
0986 
0987     if (used_count < grp->nr_sigs)
0988         idx = grp->sig_types[used_count];
0989     return sig_type_names[idx];
0990 }
0991 
0992 static ssize_t trigin_type_show(struct device *dev,
0993                 struct device_attribute *attr,
0994                 char *buf)
0995 {
0996     struct dev_ext_attribute *ext_attr =
0997         container_of(attr, struct dev_ext_attribute, attr);
0998     struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
0999     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 
1010 static 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  */
1032 static 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 
1040 static 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 
1078 static struct attribute_group *
1079 cti_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 */
1100 static 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 */
1155 static 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 
1169 int 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. */
1193 static const struct attribute_group coresight_cti_group = {
1194     .attrs = coresight_cti_attrs,
1195 };
1196 
1197 static const struct attribute_group coresight_cti_mgmt_group = {
1198     .attrs = coresight_cti_mgmt_attrs,
1199     .name = "mgmt",
1200 };
1201 
1202 static const struct attribute_group coresight_cti_regs_group = {
1203     .attrs = coresight_cti_regs_attrs,
1204     .name = "regs",
1205 };
1206 
1207 static const struct attribute_group coresight_cti_channels_group = {
1208     .attrs = coresight_cti_channel_attrs,
1209     .name = "channels",
1210 };
1211 
1212 const struct attribute_group *
1213 coresight_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 };