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