0001
0002
0003
0004
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
0019
0020
0021 #define CORESIGHT_CTI_STATIC_GROUPS_MAX 5
0022
0023
0024
0025
0026
0027 static const char * const sig_type_names[] = {
0028 "genio",
0029 "intreq",
0030 "intack",
0031 "haltreq",
0032 "restartreq",
0033 "pe_edbgreq",
0034 "pe_dbgrestart",
0035 "pe_ctiirq",
0036 "pe_pmuirq",
0037 "pe_dbgtrigger",
0038 "etm_extout",
0039 "etm_extin",
0040 "snk_full",
0041 "snk_acqcomp",
0042 "snk_flushcomp",
0043 "snk_flushin",
0044 "snk_trigin",
0045 "stm_asyncout",
0046 "stm_tout_spte",
0047 "stm_tout_sw",
0048 "stm_tout_hete",
0049 "stm_hwevent",
0050 "ela_tstart",
0051 "ela_tstop",
0052 "ela_dbgreq",
0053 };
0054
0055
0056 typedef ssize_t (*p_show_fn)(struct device *dev, struct device_attribute *attr,
0057 char *buf);
0058
0059
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
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
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
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
0165
0166
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
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
0212
0213
0214
0215
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
0240
0241
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
0255 if (pcached_val)
0256 *pcached_val = (u32)val;
0257
0258
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
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
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
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
0426 config->ctiappset &= ~val;
0427
0428
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
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
0464
0465
0466
0467 #ifdef CONFIG_CORESIGHT_CTI_INTEGRATION_REGS
0468
0469
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
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
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
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
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
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
0766 for (i = 0; i < config->nr_trig_max; i++) {
0767 config->ctiinen[i] = 0;
0768 config->ctiouten[i] = 0;
0769 }
0770
0771
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
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
0789
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
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
0881 if (!inuse)
0882 inuse_bits = ~inuse_bits;
0883
0884
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
0932
0933
0934
0935
0936
0937
0938
0939
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
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
1030
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
1055 eattr->attr.attr.name = name;
1056 eattr->attr.attr.mode = 0444;
1057
1058
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
1070
1071
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
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
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
1155 static int cti_create_cons_groups(struct device *dev, struct cti_device *ctidev)
1156 {
1157 int nr_groups;
1158
1159
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
1180 for (i = 0; i < (CORESIGHT_CTI_STATIC_GROUPS_MAX - 1); i++)
1181 ctidev->con_groups[i] = coresight_cti_groups[i];
1182
1183
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
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 };