1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 */ 5 6 #include <linux/amba/bus.h> 7 #include <linux/bitfield.h> 8 #include <linux/bitmap.h> 9 #include <linux/coresight.h> 10 #include <linux/coresight-pmu.h> 11 #include <linux/device.h> 12 #include <linux/err.h> 13 #include <linux/fs.h> 14 #include <linux/io.h> 15 #include <linux/kernel.h> 16 #include <linux/module.h> 17 #include <linux/of.h> 18 19 #include "coresight-priv.h" 20 #include "coresight-tpdm.h" 21 22 DEFINE_CORESIGHT_DEVLIST(tpdm_devs, "tpdm"); 23 24 /* Read dataset array member with the index number */ 25 static ssize_t tpdm_simple_dataset_show(struct device *dev, 26 struct device_attribute *attr, 27 char *buf) 28 { 29 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 30 struct tpdm_dataset_attribute *tpdm_attr = 31 container_of(attr, struct tpdm_dataset_attribute, attr); 32 33 switch (tpdm_attr->mem) { 34 case DSB_EDGE_CTRL: 35 if (tpdm_attr->idx >= TPDM_DSB_MAX_EDCR) 36 return -EINVAL; 37 return sysfs_emit(buf, "0x%x\n", 38 drvdata->dsb->edge_ctrl[tpdm_attr->idx]); 39 case DSB_EDGE_CTRL_MASK: 40 if (tpdm_attr->idx >= TPDM_DSB_MAX_EDCMR) 41 return -EINVAL; 42 return sysfs_emit(buf, "0x%x\n", 43 drvdata->dsb->edge_ctrl_mask[tpdm_attr->idx]); 44 case DSB_TRIG_PATT: 45 if (tpdm_attr->idx >= TPDM_DSB_MAX_PATT) 46 return -EINVAL; 47 return sysfs_emit(buf, "0x%x\n", 48 drvdata->dsb->trig_patt[tpdm_attr->idx]); 49 case DSB_TRIG_PATT_MASK: 50 if (tpdm_attr->idx >= TPDM_DSB_MAX_PATT) 51 return -EINVAL; 52 return sysfs_emit(buf, "0x%x\n", 53 drvdata->dsb->trig_patt_mask[tpdm_attr->idx]); 54 case DSB_PATT: 55 if (tpdm_attr->idx >= TPDM_DSB_MAX_PATT) 56 return -EINVAL; 57 return sysfs_emit(buf, "0x%x\n", 58 drvdata->dsb->patt_val[tpdm_attr->idx]); 59 case DSB_PATT_MASK: 60 if (tpdm_attr->idx >= TPDM_DSB_MAX_PATT) 61 return -EINVAL; 62 return sysfs_emit(buf, "0x%x\n", 63 drvdata->dsb->patt_mask[tpdm_attr->idx]); 64 case DSB_MSR: 65 if (tpdm_attr->idx >= drvdata->dsb_msr_num) 66 return -EINVAL; 67 return sysfs_emit(buf, "0x%x\n", 68 drvdata->dsb->msr[tpdm_attr->idx]); 69 case CMB_TRIG_PATT: 70 if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT) 71 return -EINVAL; 72 return sysfs_emit(buf, "0x%x\n", 73 drvdata->cmb->trig_patt[tpdm_attr->idx]); 74 case CMB_TRIG_PATT_MASK: 75 if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT) 76 return -EINVAL; 77 return sysfs_emit(buf, "0x%x\n", 78 drvdata->cmb->trig_patt_mask[tpdm_attr->idx]); 79 case CMB_PATT: 80 if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT) 81 return -EINVAL; 82 return sysfs_emit(buf, "0x%x\n", 83 drvdata->cmb->patt_val[tpdm_attr->idx]); 84 case CMB_PATT_MASK: 85 if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT) 86 return -EINVAL; 87 return sysfs_emit(buf, "0x%x\n", 88 drvdata->cmb->patt_mask[tpdm_attr->idx]); 89 case CMB_MSR: 90 if (tpdm_attr->idx >= drvdata->cmb_msr_num) 91 return -EINVAL; 92 return sysfs_emit(buf, "0x%x\n", 93 drvdata->cmb->msr[tpdm_attr->idx]); 94 } 95 return -EINVAL; 96 } 97 98 /* Write dataset array member with the index number */ 99 static ssize_t tpdm_simple_dataset_store(struct device *dev, 100 struct device_attribute *attr, 101 const char *buf, 102 size_t size) 103 { 104 unsigned long val; 105 ssize_t ret = -EINVAL; 106 107 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 108 struct tpdm_dataset_attribute *tpdm_attr = 109 container_of(attr, struct tpdm_dataset_attribute, attr); 110 111 if (kstrtoul(buf, 0, &val)) 112 return ret; 113 114 guard(spinlock)(&drvdata->spinlock); 115 switch (tpdm_attr->mem) { 116 case DSB_TRIG_PATT: 117 if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) { 118 drvdata->dsb->trig_patt[tpdm_attr->idx] = val; 119 ret = size; 120 } 121 break; 122 case DSB_TRIG_PATT_MASK: 123 if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) { 124 drvdata->dsb->trig_patt_mask[tpdm_attr->idx] = val; 125 ret = size; 126 } 127 break; 128 case DSB_PATT: 129 if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) { 130 drvdata->dsb->patt_val[tpdm_attr->idx] = val; 131 ret = size; 132 } 133 break; 134 case DSB_PATT_MASK: 135 if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) { 136 drvdata->dsb->patt_mask[tpdm_attr->idx] = val; 137 ret = size; 138 } 139 break; 140 case DSB_MSR: 141 if (tpdm_attr->idx < drvdata->dsb_msr_num) { 142 drvdata->dsb->msr[tpdm_attr->idx] = val; 143 ret = size; 144 } 145 break; 146 case CMB_TRIG_PATT: 147 if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) { 148 drvdata->cmb->trig_patt[tpdm_attr->idx] = val; 149 ret = size; 150 } 151 break; 152 case CMB_TRIG_PATT_MASK: 153 if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) { 154 drvdata->cmb->trig_patt_mask[tpdm_attr->idx] = val; 155 ret = size; 156 } 157 break; 158 case CMB_PATT: 159 if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) { 160 drvdata->cmb->patt_val[tpdm_attr->idx] = val; 161 ret = size; 162 } 163 break; 164 case CMB_PATT_MASK: 165 if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) { 166 drvdata->cmb->patt_mask[tpdm_attr->idx] = val; 167 ret = size; 168 } 169 break; 170 case CMB_MSR: 171 if (tpdm_attr->idx < drvdata->cmb_msr_num) { 172 drvdata->cmb->msr[tpdm_attr->idx] = val; 173 ret = size; 174 } 175 break; 176 default: 177 break; 178 } 179 180 return ret; 181 } 182 183 static umode_t tpdm_dsb_is_visible(struct kobject *kobj, 184 struct attribute *attr, int n) 185 { 186 struct device *dev = kobj_to_dev(kobj); 187 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 188 189 if (drvdata && tpdm_has_dsb_dataset(drvdata)) 190 return attr->mode; 191 192 return 0; 193 } 194 195 static umode_t tpdm_cmb_is_visible(struct kobject *kobj, 196 struct attribute *attr, int n) 197 { 198 struct device *dev = kobj_to_dev(kobj); 199 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 200 201 if (drvdata && tpdm_has_cmb_dataset(drvdata)) 202 return attr->mode; 203 204 return 0; 205 } 206 207 static umode_t tpdm_dsb_msr_is_visible(struct kobject *kobj, 208 struct attribute *attr, int n) 209 { 210 struct device *dev = kobj_to_dev(kobj); 211 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 212 struct device_attribute *dev_attr = 213 container_of(attr, struct device_attribute, attr); 214 struct tpdm_dataset_attribute *tpdm_attr = 215 container_of(dev_attr, struct tpdm_dataset_attribute, attr); 216 217 if (tpdm_attr->idx < drvdata->dsb_msr_num) 218 return attr->mode; 219 220 return 0; 221 } 222 223 static umode_t tpdm_cmb_msr_is_visible(struct kobject *kobj, 224 struct attribute *attr, int n) 225 { 226 struct device *dev = kobj_to_dev(kobj); 227 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 228 229 struct device_attribute *dev_attr = 230 container_of(attr, struct device_attribute, attr); 231 struct tpdm_dataset_attribute *tpdm_attr = 232 container_of(dev_attr, struct tpdm_dataset_attribute, attr); 233 234 if (tpdm_attr->idx < drvdata->cmb_msr_num) 235 return attr->mode; 236 237 return 0; 238 } 239 240 static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata) 241 { 242 if (tpdm_has_dsb_dataset(drvdata)) { 243 memset(drvdata->dsb, 0, sizeof(struct dsb_dataset)); 244 245 drvdata->dsb->trig_ts = true; 246 drvdata->dsb->trig_type = false; 247 } 248 249 if (drvdata->cmb) 250 memset(drvdata->cmb, 0, sizeof(struct cmb_dataset)); 251 } 252 253 static void set_dsb_mode(struct tpdm_drvdata *drvdata, u32 *val) 254 { 255 u32 mode; 256 257 /* Set the test accurate mode */ 258 mode = TPDM_DSB_MODE_TEST(drvdata->dsb->mode); 259 *val &= ~TPDM_DSB_CR_TEST_MODE; 260 *val |= FIELD_PREP(TPDM_DSB_CR_TEST_MODE, mode); 261 262 /* Set the byte lane for high-performance mode */ 263 mode = TPDM_DSB_MODE_HPBYTESEL(drvdata->dsb->mode); 264 *val &= ~TPDM_DSB_CR_HPSEL; 265 *val |= FIELD_PREP(TPDM_DSB_CR_HPSEL, mode); 266 267 /* Set the performance mode */ 268 if (drvdata->dsb->mode & TPDM_DSB_MODE_PERF) 269 *val |= TPDM_DSB_CR_MODE; 270 else 271 *val &= ~TPDM_DSB_CR_MODE; 272 } 273 274 static void set_dsb_tier(struct tpdm_drvdata *drvdata) 275 { 276 u32 val; 277 278 val = readl_relaxed(drvdata->base + TPDM_DSB_TIER); 279 280 /* Clear all relevant fields */ 281 val &= ~(TPDM_DSB_TIER_PATT_TSENAB | TPDM_DSB_TIER_PATT_TYPE | 282 TPDM_DSB_TIER_XTRIG_TSENAB); 283 284 /* Set pattern timestamp type and enablement */ 285 if (drvdata->dsb->patt_ts) { 286 val |= TPDM_DSB_TIER_PATT_TSENAB; 287 if (drvdata->dsb->patt_type) 288 val |= TPDM_DSB_TIER_PATT_TYPE; 289 else 290 val &= ~TPDM_DSB_TIER_PATT_TYPE; 291 } else { 292 val &= ~TPDM_DSB_TIER_PATT_TSENAB; 293 } 294 295 /* Set trigger timestamp */ 296 if (drvdata->dsb->trig_ts) 297 val |= TPDM_DSB_TIER_XTRIG_TSENAB; 298 else 299 val &= ~TPDM_DSB_TIER_XTRIG_TSENAB; 300 301 writel_relaxed(val, drvdata->base + TPDM_DSB_TIER); 302 } 303 304 static void set_dsb_msr(struct tpdm_drvdata *drvdata) 305 { 306 int i; 307 308 for (i = 0; i < drvdata->dsb_msr_num; i++) 309 writel_relaxed(drvdata->dsb->msr[i], 310 drvdata->base + TPDM_DSB_MSR(i)); 311 } 312 313 static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata) 314 { 315 u32 val, i; 316 317 if (!tpdm_has_dsb_dataset(drvdata)) 318 return; 319 320 for (i = 0; i < TPDM_DSB_MAX_EDCR; i++) 321 writel_relaxed(drvdata->dsb->edge_ctrl[i], 322 drvdata->base + TPDM_DSB_EDCR(i)); 323 for (i = 0; i < TPDM_DSB_MAX_EDCMR; i++) 324 writel_relaxed(drvdata->dsb->edge_ctrl_mask[i], 325 drvdata->base + TPDM_DSB_EDCMR(i)); 326 for (i = 0; i < TPDM_DSB_MAX_PATT; i++) { 327 writel_relaxed(drvdata->dsb->patt_val[i], 328 drvdata->base + TPDM_DSB_TPR(i)); 329 writel_relaxed(drvdata->dsb->patt_mask[i], 330 drvdata->base + TPDM_DSB_TPMR(i)); 331 writel_relaxed(drvdata->dsb->trig_patt[i], 332 drvdata->base + TPDM_DSB_XPR(i)); 333 writel_relaxed(drvdata->dsb->trig_patt_mask[i], 334 drvdata->base + TPDM_DSB_XPMR(i)); 335 } 336 337 set_dsb_tier(drvdata); 338 set_dsb_msr(drvdata); 339 340 val = readl_relaxed(drvdata->base + TPDM_DSB_CR); 341 /* Set the mode of DSB dataset */ 342 set_dsb_mode(drvdata, &val); 343 /* Set trigger type */ 344 if (drvdata->dsb->trig_type) 345 val |= TPDM_DSB_CR_TRIG_TYPE; 346 else 347 val &= ~TPDM_DSB_CR_TRIG_TYPE; 348 /* Set the enable bit of DSB control register to 1 */ 349 val |= TPDM_DSB_CR_ENA; 350 writel_relaxed(val, drvdata->base + TPDM_DSB_CR); 351 } 352 353 static void set_cmb_tier(struct tpdm_drvdata *drvdata) 354 { 355 u32 val; 356 357 val = readl_relaxed(drvdata->base + TPDM_CMB_TIER); 358 359 /* Clear all relevant fields */ 360 val &= ~(TPDM_CMB_TIER_PATT_TSENAB | TPDM_CMB_TIER_TS_ALL | 361 TPDM_CMB_TIER_XTRIG_TSENAB); 362 363 /* Set pattern timestamp type and enablement */ 364 if (drvdata->cmb->patt_ts) 365 val |= TPDM_CMB_TIER_PATT_TSENAB; 366 367 /* Set trigger timestamp */ 368 if (drvdata->cmb->trig_ts) 369 val |= TPDM_CMB_TIER_XTRIG_TSENAB; 370 371 /* Set all timestamp enablement*/ 372 if (drvdata->cmb->ts_all) 373 val |= TPDM_CMB_TIER_TS_ALL; 374 375 writel_relaxed(val, drvdata->base + TPDM_CMB_TIER); 376 } 377 378 static void set_cmb_msr(struct tpdm_drvdata *drvdata) 379 { 380 int i; 381 382 for (i = 0; i < drvdata->cmb_msr_num; i++) 383 writel_relaxed(drvdata->cmb->msr[i], 384 drvdata->base + TPDM_CMB_MSR(i)); 385 } 386 387 static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata) 388 { 389 u32 val, i; 390 391 if (!tpdm_has_cmb_dataset(drvdata)) 392 return; 393 394 /* Configure pattern registers */ 395 for (i = 0; i < TPDM_CMB_MAX_PATT; i++) { 396 writel_relaxed(drvdata->cmb->patt_val[i], 397 drvdata->base + TPDM_CMB_TPR(i)); 398 writel_relaxed(drvdata->cmb->patt_mask[i], 399 drvdata->base + TPDM_CMB_TPMR(i)); 400 writel_relaxed(drvdata->cmb->trig_patt[i], 401 drvdata->base + TPDM_CMB_XPR(i)); 402 writel_relaxed(drvdata->cmb->trig_patt_mask[i], 403 drvdata->base + TPDM_CMB_XPMR(i)); 404 } 405 406 set_cmb_tier(drvdata); 407 set_cmb_msr(drvdata); 408 409 val = readl_relaxed(drvdata->base + TPDM_CMB_CR); 410 /* 411 * Set to 0 for continuous CMB collection mode, 412 * 1 for trace-on-change CMB collection mode. 413 */ 414 if (drvdata->cmb->trace_mode) 415 val |= TPDM_CMB_CR_MODE; 416 else 417 val &= ~TPDM_CMB_CR_MODE; 418 /* Set the enable bit of CMB control register to 1 */ 419 val |= TPDM_CMB_CR_ENA; 420 writel_relaxed(val, drvdata->base + TPDM_CMB_CR); 421 } 422 423 /* 424 * TPDM enable operations 425 * The TPDM or Monitor serves as data collection component for various 426 * dataset types. It covers Basic Counts(BC), Tenure Counts(TC), 427 * Continuous Multi-Bit(CMB), Multi-lane CMB(MCMB) and Discrete Single 428 * Bit(DSB). This function will initialize the configuration according 429 * to the dataset type supported by the TPDM. 430 */ 431 static void __tpdm_enable(struct tpdm_drvdata *drvdata) 432 { 433 CS_UNLOCK(drvdata->base); 434 435 tpdm_enable_dsb(drvdata); 436 tpdm_enable_cmb(drvdata); 437 438 CS_LOCK(drvdata->base); 439 } 440 441 static int tpdm_enable(struct coresight_device *csdev, struct perf_event *event, 442 enum cs_mode mode, 443 __maybe_unused struct coresight_trace_id_map *id_map) 444 { 445 struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 446 447 spin_lock(&drvdata->spinlock); 448 if (drvdata->enable) { 449 spin_unlock(&drvdata->spinlock); 450 return -EBUSY; 451 } 452 453 if (!coresight_take_mode(csdev, mode)) { 454 spin_unlock(&drvdata->spinlock); 455 return -EBUSY; 456 } 457 458 __tpdm_enable(drvdata); 459 drvdata->enable = true; 460 spin_unlock(&drvdata->spinlock); 461 462 dev_dbg(drvdata->dev, "TPDM tracing enabled\n"); 463 return 0; 464 } 465 466 static void tpdm_disable_dsb(struct tpdm_drvdata *drvdata) 467 { 468 u32 val; 469 470 if (!tpdm_has_dsb_dataset(drvdata)) 471 return; 472 473 /* Set the enable bit of DSB control register to 0 */ 474 val = readl_relaxed(drvdata->base + TPDM_DSB_CR); 475 val &= ~TPDM_DSB_CR_ENA; 476 writel_relaxed(val, drvdata->base + TPDM_DSB_CR); 477 } 478 479 static void tpdm_disable_cmb(struct tpdm_drvdata *drvdata) 480 { 481 u32 val; 482 483 if (!tpdm_has_cmb_dataset(drvdata)) 484 return; 485 486 val = readl_relaxed(drvdata->base + TPDM_CMB_CR); 487 /* Set the enable bit of CMB control register to 0 */ 488 val &= ~TPDM_CMB_CR_ENA; 489 writel_relaxed(val, drvdata->base + TPDM_CMB_CR); 490 } 491 492 /* TPDM disable operations */ 493 static void __tpdm_disable(struct tpdm_drvdata *drvdata) 494 { 495 CS_UNLOCK(drvdata->base); 496 497 tpdm_disable_dsb(drvdata); 498 tpdm_disable_cmb(drvdata); 499 500 CS_LOCK(drvdata->base); 501 } 502 503 static void tpdm_disable(struct coresight_device *csdev, 504 struct perf_event *event) 505 { 506 struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 507 508 spin_lock(&drvdata->spinlock); 509 if (!drvdata->enable) { 510 spin_unlock(&drvdata->spinlock); 511 return; 512 } 513 514 __tpdm_disable(drvdata); 515 coresight_set_mode(csdev, CS_MODE_DISABLED); 516 drvdata->enable = false; 517 spin_unlock(&drvdata->spinlock); 518 519 dev_dbg(drvdata->dev, "TPDM tracing disabled\n"); 520 } 521 522 static const struct coresight_ops_source tpdm_source_ops = { 523 .enable = tpdm_enable, 524 .disable = tpdm_disable, 525 }; 526 527 static const struct coresight_ops tpdm_cs_ops = { 528 .source_ops = &tpdm_source_ops, 529 }; 530 531 static int tpdm_datasets_setup(struct tpdm_drvdata *drvdata) 532 { 533 u32 pidr; 534 535 /* Get the datasets present on the TPDM. */ 536 pidr = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR0); 537 drvdata->datasets |= pidr & GENMASK(TPDM_DATASETS - 1, 0); 538 539 if (tpdm_has_dsb_dataset(drvdata) && (!drvdata->dsb)) { 540 drvdata->dsb = devm_kzalloc(drvdata->dev, 541 sizeof(*drvdata->dsb), GFP_KERNEL); 542 if (!drvdata->dsb) 543 return -ENOMEM; 544 } 545 if (tpdm_has_cmb_dataset(drvdata) && (!drvdata->cmb)) { 546 drvdata->cmb = devm_kzalloc(drvdata->dev, 547 sizeof(*drvdata->cmb), GFP_KERNEL); 548 if (!drvdata->cmb) 549 return -ENOMEM; 550 } 551 tpdm_reset_datasets(drvdata); 552 553 return 0; 554 } 555 556 static ssize_t reset_dataset_store(struct device *dev, 557 struct device_attribute *attr, 558 const char *buf, 559 size_t size) 560 { 561 int ret = 0; 562 unsigned long val; 563 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 564 565 ret = kstrtoul(buf, 0, &val); 566 if (ret || val != 1) 567 return -EINVAL; 568 569 spin_lock(&drvdata->spinlock); 570 tpdm_reset_datasets(drvdata); 571 spin_unlock(&drvdata->spinlock); 572 573 return size; 574 } 575 static DEVICE_ATTR_WO(reset_dataset); 576 577 /* 578 * value 1: 64 bits test data 579 * value 2: 32 bits test data 580 */ 581 static ssize_t integration_test_store(struct device *dev, 582 struct device_attribute *attr, 583 const char *buf, 584 size_t size) 585 { 586 int i, ret = 0; 587 unsigned long val; 588 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 589 590 ret = kstrtoul(buf, 10, &val); 591 if (ret) 592 return ret; 593 594 if (val != 1 && val != 2) 595 return -EINVAL; 596 597 if (!drvdata->enable) 598 return -EINVAL; 599 600 if (val == 1) 601 val = ATBCNTRL_VAL_64; 602 else 603 val = ATBCNTRL_VAL_32; 604 CS_UNLOCK(drvdata->base); 605 writel_relaxed(0x1, drvdata->base + TPDM_ITCNTRL); 606 607 for (i = 0; i < INTEGRATION_TEST_CYCLE; i++) 608 writel_relaxed(val, drvdata->base + TPDM_ITATBCNTRL); 609 610 writel_relaxed(0, drvdata->base + TPDM_ITCNTRL); 611 CS_LOCK(drvdata->base); 612 return size; 613 } 614 static DEVICE_ATTR_WO(integration_test); 615 616 static struct attribute *tpdm_attrs[] = { 617 &dev_attr_reset_dataset.attr, 618 &dev_attr_integration_test.attr, 619 NULL, 620 }; 621 622 static struct attribute_group tpdm_attr_grp = { 623 .attrs = tpdm_attrs, 624 }; 625 626 static ssize_t dsb_mode_show(struct device *dev, 627 struct device_attribute *attr, 628 char *buf) 629 { 630 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 631 632 return sysfs_emit(buf, "%x\n", drvdata->dsb->mode); 633 } 634 635 static ssize_t dsb_mode_store(struct device *dev, 636 struct device_attribute *attr, 637 const char *buf, 638 size_t size) 639 { 640 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 641 unsigned long val; 642 643 if ((kstrtoul(buf, 0, &val)) || (val < 0) || 644 (val & ~TPDM_DSB_MODE_MASK)) 645 return -EINVAL; 646 647 spin_lock(&drvdata->spinlock); 648 drvdata->dsb->mode = val & TPDM_DSB_MODE_MASK; 649 spin_unlock(&drvdata->spinlock); 650 return size; 651 } 652 static DEVICE_ATTR_RW(dsb_mode); 653 654 static ssize_t ctrl_idx_show(struct device *dev, 655 struct device_attribute *attr, 656 char *buf) 657 { 658 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 659 660 return sysfs_emit(buf, "%u\n", 661 (unsigned int)drvdata->dsb->edge_ctrl_idx); 662 } 663 664 /* 665 * The EDCR registers can include up to 16 32-bit registers, and each 666 * one can be configured to control up to 16 edge detections(2 bits 667 * control one edge detection). So a total 256 edge detections can be 668 * configured. This function provides a way to set the index number of 669 * the edge detection which needs to be configured. 670 */ 671 static ssize_t ctrl_idx_store(struct device *dev, 672 struct device_attribute *attr, 673 const char *buf, 674 size_t size) 675 { 676 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 677 unsigned long val; 678 679 if ((kstrtoul(buf, 0, &val)) || (val >= TPDM_DSB_MAX_LINES)) 680 return -EINVAL; 681 682 spin_lock(&drvdata->spinlock); 683 drvdata->dsb->edge_ctrl_idx = val; 684 spin_unlock(&drvdata->spinlock); 685 686 return size; 687 } 688 static DEVICE_ATTR_RW(ctrl_idx); 689 690 /* 691 * This function is used to control the edge detection according 692 * to the index number that has been set. 693 * "edge_ctrl" should be one of the following values. 694 * 0 - Rising edge detection 695 * 1 - Falling edge detection 696 * 2 - Rising and falling edge detection (toggle detection) 697 */ 698 static ssize_t ctrl_val_store(struct device *dev, 699 struct device_attribute *attr, 700 const char *buf, 701 size_t size) 702 { 703 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 704 unsigned long val, edge_ctrl; 705 int reg; 706 707 if ((kstrtoul(buf, 0, &edge_ctrl)) || (edge_ctrl > 0x2)) 708 return -EINVAL; 709 710 spin_lock(&drvdata->spinlock); 711 /* 712 * There are 2 bit per DSB Edge Control line. 713 * Thus we have 16 lines in a 32bit word. 714 */ 715 reg = EDCR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx); 716 val = drvdata->dsb->edge_ctrl[reg]; 717 val &= ~EDCR_TO_WORD_MASK(drvdata->dsb->edge_ctrl_idx); 718 val |= EDCR_TO_WORD_VAL(edge_ctrl, drvdata->dsb->edge_ctrl_idx); 719 drvdata->dsb->edge_ctrl[reg] = val; 720 spin_unlock(&drvdata->spinlock); 721 722 return size; 723 } 724 static DEVICE_ATTR_WO(ctrl_val); 725 726 static ssize_t ctrl_mask_store(struct device *dev, 727 struct device_attribute *attr, 728 const char *buf, 729 size_t size) 730 { 731 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 732 unsigned long val; 733 u32 set; 734 int reg; 735 736 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) 737 return -EINVAL; 738 739 spin_lock(&drvdata->spinlock); 740 /* 741 * There is 1 bit per DSB Edge Control Mark line. 742 * Thus we have 32 lines in a 32bit word. 743 */ 744 reg = EDCMR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx); 745 set = drvdata->dsb->edge_ctrl_mask[reg]; 746 if (val) 747 set |= BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx)); 748 else 749 set &= ~BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx)); 750 drvdata->dsb->edge_ctrl_mask[reg] = set; 751 spin_unlock(&drvdata->spinlock); 752 753 return size; 754 } 755 static DEVICE_ATTR_WO(ctrl_mask); 756 757 static ssize_t enable_ts_show(struct device *dev, 758 struct device_attribute *attr, 759 char *buf) 760 { 761 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 762 struct tpdm_dataset_attribute *tpdm_attr = 763 container_of(attr, struct tpdm_dataset_attribute, attr); 764 ssize_t size = -EINVAL; 765 766 if (tpdm_attr->mem == DSB_PATT) 767 size = sysfs_emit(buf, "%u\n", 768 (unsigned int)drvdata->dsb->patt_ts); 769 else if (tpdm_attr->mem == CMB_PATT) 770 size = sysfs_emit(buf, "%u\n", 771 (unsigned int)drvdata->cmb->patt_ts); 772 773 return size; 774 } 775 776 /* 777 * value 1: Enable/Disable DSB pattern timestamp 778 */ 779 static ssize_t enable_ts_store(struct device *dev, 780 struct device_attribute *attr, 781 const char *buf, 782 size_t size) 783 { 784 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 785 struct tpdm_dataset_attribute *tpdm_attr = 786 container_of(attr, struct tpdm_dataset_attribute, attr); 787 unsigned long val; 788 789 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) 790 return -EINVAL; 791 792 guard(spinlock)(&drvdata->spinlock); 793 if (tpdm_attr->mem == DSB_PATT) 794 drvdata->dsb->patt_ts = !!val; 795 else if (tpdm_attr->mem == CMB_PATT) 796 drvdata->cmb->patt_ts = !!val; 797 else 798 return -EINVAL; 799 800 return size; 801 } 802 803 static ssize_t set_type_show(struct device *dev, 804 struct device_attribute *attr, 805 char *buf) 806 { 807 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 808 809 return sysfs_emit(buf, "%u\n", 810 (unsigned int)drvdata->dsb->patt_type); 811 } 812 813 /* 814 * value 1: Set DSB pattern type 815 */ 816 static ssize_t set_type_store(struct device *dev, 817 struct device_attribute *attr, 818 const char *buf, size_t size) 819 { 820 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 821 unsigned long val; 822 823 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) 824 return -EINVAL; 825 826 spin_lock(&drvdata->spinlock); 827 drvdata->dsb->patt_type = val; 828 spin_unlock(&drvdata->spinlock); 829 return size; 830 } 831 static DEVICE_ATTR_RW(set_type); 832 833 static ssize_t dsb_trig_type_show(struct device *dev, 834 struct device_attribute *attr, char *buf) 835 { 836 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 837 838 return sysfs_emit(buf, "%u\n", 839 (unsigned int)drvdata->dsb->trig_type); 840 } 841 842 /* 843 * Trigger type (boolean): 844 * false - Disable trigger type. 845 * true - Enable trigger type. 846 */ 847 static ssize_t dsb_trig_type_store(struct device *dev, 848 struct device_attribute *attr, 849 const char *buf, 850 size_t size) 851 { 852 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 853 unsigned long val; 854 855 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) 856 return -EINVAL; 857 858 spin_lock(&drvdata->spinlock); 859 if (val) 860 drvdata->dsb->trig_type = true; 861 else 862 drvdata->dsb->trig_type = false; 863 spin_unlock(&drvdata->spinlock); 864 return size; 865 } 866 static DEVICE_ATTR_RW(dsb_trig_type); 867 868 static ssize_t dsb_trig_ts_show(struct device *dev, 869 struct device_attribute *attr, 870 char *buf) 871 { 872 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 873 874 return sysfs_emit(buf, "%u\n", 875 (unsigned int)drvdata->dsb->trig_ts); 876 } 877 878 /* 879 * Trigger timestamp (boolean): 880 * false - Disable trigger timestamp. 881 * true - Enable trigger timestamp. 882 */ 883 static ssize_t dsb_trig_ts_store(struct device *dev, 884 struct device_attribute *attr, 885 const char *buf, 886 size_t size) 887 { 888 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 889 unsigned long val; 890 891 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) 892 return -EINVAL; 893 894 spin_lock(&drvdata->spinlock); 895 if (val) 896 drvdata->dsb->trig_ts = true; 897 else 898 drvdata->dsb->trig_ts = false; 899 spin_unlock(&drvdata->spinlock); 900 return size; 901 } 902 static DEVICE_ATTR_RW(dsb_trig_ts); 903 904 static ssize_t cmb_mode_show(struct device *dev, 905 struct device_attribute *attr, 906 char *buf) 907 { 908 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 909 910 return sysfs_emit(buf, "%x\n", drvdata->cmb->trace_mode); 911 912 } 913 914 static ssize_t cmb_mode_store(struct device *dev, 915 struct device_attribute *attr, 916 const char *buf, 917 size_t size) 918 { 919 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 920 unsigned long trace_mode; 921 922 if (kstrtoul(buf, 0, &trace_mode) || (trace_mode & ~1UL)) 923 return -EINVAL; 924 925 spin_lock(&drvdata->spinlock); 926 drvdata->cmb->trace_mode = trace_mode; 927 spin_unlock(&drvdata->spinlock); 928 return size; 929 } 930 static DEVICE_ATTR_RW(cmb_mode); 931 932 static ssize_t cmb_ts_all_show(struct device *dev, 933 struct device_attribute *attr, 934 char *buf) 935 { 936 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 937 938 return sysfs_emit(buf, "%u\n", 939 (unsigned int)drvdata->cmb->ts_all); 940 } 941 942 static ssize_t cmb_ts_all_store(struct device *dev, 943 struct device_attribute *attr, 944 const char *buf, 945 size_t size) 946 { 947 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 948 unsigned long val; 949 950 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) 951 return -EINVAL; 952 953 guard(spinlock)(&drvdata->spinlock); 954 if (val) 955 drvdata->cmb->ts_all = true; 956 else 957 drvdata->cmb->ts_all = false; 958 959 return size; 960 } 961 static DEVICE_ATTR_RW(cmb_ts_all); 962 963 static ssize_t cmb_trig_ts_show(struct device *dev, 964 struct device_attribute *attr, 965 char *buf) 966 { 967 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 968 969 return sysfs_emit(buf, "%u\n", 970 (unsigned int)drvdata->cmb->trig_ts); 971 } 972 973 static ssize_t cmb_trig_ts_store(struct device *dev, 974 struct device_attribute *attr, 975 const char *buf, 976 size_t size) 977 { 978 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 979 unsigned long val; 980 981 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) 982 return -EINVAL; 983 984 guard(spinlock)(&drvdata->spinlock); 985 if (val) 986 drvdata->cmb->trig_ts = true; 987 else 988 drvdata->cmb->trig_ts = false; 989 990 return size; 991 } 992 static DEVICE_ATTR_RW(cmb_trig_ts); 993 994 static struct attribute *tpdm_dsb_edge_attrs[] = { 995 &dev_attr_ctrl_idx.attr, 996 &dev_attr_ctrl_val.attr, 997 &dev_attr_ctrl_mask.attr, 998 DSB_EDGE_CTRL_ATTR(0), 999 DSB_EDGE_CTRL_ATTR(1), 1000 DSB_EDGE_CTRL_ATTR(2), 1001 DSB_EDGE_CTRL_ATTR(3), 1002 DSB_EDGE_CTRL_ATTR(4), 1003 DSB_EDGE_CTRL_ATTR(5), 1004 DSB_EDGE_CTRL_ATTR(6), 1005 DSB_EDGE_CTRL_ATTR(7), 1006 DSB_EDGE_CTRL_ATTR(8), 1007 DSB_EDGE_CTRL_ATTR(9), 1008 DSB_EDGE_CTRL_ATTR(10), 1009 DSB_EDGE_CTRL_ATTR(11), 1010 DSB_EDGE_CTRL_ATTR(12), 1011 DSB_EDGE_CTRL_ATTR(13), 1012 DSB_EDGE_CTRL_ATTR(14), 1013 DSB_EDGE_CTRL_ATTR(15), 1014 DSB_EDGE_CTRL_MASK_ATTR(0), 1015 DSB_EDGE_CTRL_MASK_ATTR(1), 1016 DSB_EDGE_CTRL_MASK_ATTR(2), 1017 DSB_EDGE_CTRL_MASK_ATTR(3), 1018 DSB_EDGE_CTRL_MASK_ATTR(4), 1019 DSB_EDGE_CTRL_MASK_ATTR(5), 1020 DSB_EDGE_CTRL_MASK_ATTR(6), 1021 DSB_EDGE_CTRL_MASK_ATTR(7), 1022 NULL, 1023 }; 1024 1025 static struct attribute *tpdm_dsb_trig_patt_attrs[] = { 1026 DSB_TRIG_PATT_ATTR(0), 1027 DSB_TRIG_PATT_ATTR(1), 1028 DSB_TRIG_PATT_ATTR(2), 1029 DSB_TRIG_PATT_ATTR(3), 1030 DSB_TRIG_PATT_ATTR(4), 1031 DSB_TRIG_PATT_ATTR(5), 1032 DSB_TRIG_PATT_ATTR(6), 1033 DSB_TRIG_PATT_ATTR(7), 1034 DSB_TRIG_PATT_MASK_ATTR(0), 1035 DSB_TRIG_PATT_MASK_ATTR(1), 1036 DSB_TRIG_PATT_MASK_ATTR(2), 1037 DSB_TRIG_PATT_MASK_ATTR(3), 1038 DSB_TRIG_PATT_MASK_ATTR(4), 1039 DSB_TRIG_PATT_MASK_ATTR(5), 1040 DSB_TRIG_PATT_MASK_ATTR(6), 1041 DSB_TRIG_PATT_MASK_ATTR(7), 1042 NULL, 1043 }; 1044 1045 static struct attribute *tpdm_dsb_patt_attrs[] = { 1046 DSB_PATT_ATTR(0), 1047 DSB_PATT_ATTR(1), 1048 DSB_PATT_ATTR(2), 1049 DSB_PATT_ATTR(3), 1050 DSB_PATT_ATTR(4), 1051 DSB_PATT_ATTR(5), 1052 DSB_PATT_ATTR(6), 1053 DSB_PATT_ATTR(7), 1054 DSB_PATT_MASK_ATTR(0), 1055 DSB_PATT_MASK_ATTR(1), 1056 DSB_PATT_MASK_ATTR(2), 1057 DSB_PATT_MASK_ATTR(3), 1058 DSB_PATT_MASK_ATTR(4), 1059 DSB_PATT_MASK_ATTR(5), 1060 DSB_PATT_MASK_ATTR(6), 1061 DSB_PATT_MASK_ATTR(7), 1062 DSB_PATT_ENABLE_TS, 1063 &dev_attr_set_type.attr, 1064 NULL, 1065 }; 1066 1067 static struct attribute *tpdm_dsb_msr_attrs[] = { 1068 DSB_MSR_ATTR(0), 1069 DSB_MSR_ATTR(1), 1070 DSB_MSR_ATTR(2), 1071 DSB_MSR_ATTR(3), 1072 DSB_MSR_ATTR(4), 1073 DSB_MSR_ATTR(5), 1074 DSB_MSR_ATTR(6), 1075 DSB_MSR_ATTR(7), 1076 DSB_MSR_ATTR(8), 1077 DSB_MSR_ATTR(9), 1078 DSB_MSR_ATTR(10), 1079 DSB_MSR_ATTR(11), 1080 DSB_MSR_ATTR(12), 1081 DSB_MSR_ATTR(13), 1082 DSB_MSR_ATTR(14), 1083 DSB_MSR_ATTR(15), 1084 DSB_MSR_ATTR(16), 1085 DSB_MSR_ATTR(17), 1086 DSB_MSR_ATTR(18), 1087 DSB_MSR_ATTR(19), 1088 DSB_MSR_ATTR(20), 1089 DSB_MSR_ATTR(21), 1090 DSB_MSR_ATTR(22), 1091 DSB_MSR_ATTR(23), 1092 DSB_MSR_ATTR(24), 1093 DSB_MSR_ATTR(25), 1094 DSB_MSR_ATTR(26), 1095 DSB_MSR_ATTR(27), 1096 DSB_MSR_ATTR(28), 1097 DSB_MSR_ATTR(29), 1098 DSB_MSR_ATTR(30), 1099 DSB_MSR_ATTR(31), 1100 NULL, 1101 }; 1102 1103 static struct attribute *tpdm_cmb_trig_patt_attrs[] = { 1104 CMB_TRIG_PATT_ATTR(0), 1105 CMB_TRIG_PATT_ATTR(1), 1106 CMB_TRIG_PATT_MASK_ATTR(0), 1107 CMB_TRIG_PATT_MASK_ATTR(1), 1108 NULL, 1109 }; 1110 1111 static struct attribute *tpdm_cmb_patt_attrs[] = { 1112 CMB_PATT_ATTR(0), 1113 CMB_PATT_ATTR(1), 1114 CMB_PATT_MASK_ATTR(0), 1115 CMB_PATT_MASK_ATTR(1), 1116 CMB_PATT_ENABLE_TS, 1117 NULL, 1118 }; 1119 1120 static struct attribute *tpdm_cmb_msr_attrs[] = { 1121 CMB_MSR_ATTR(0), 1122 CMB_MSR_ATTR(1), 1123 CMB_MSR_ATTR(2), 1124 CMB_MSR_ATTR(3), 1125 CMB_MSR_ATTR(4), 1126 CMB_MSR_ATTR(5), 1127 CMB_MSR_ATTR(6), 1128 CMB_MSR_ATTR(7), 1129 CMB_MSR_ATTR(8), 1130 CMB_MSR_ATTR(9), 1131 CMB_MSR_ATTR(10), 1132 CMB_MSR_ATTR(11), 1133 CMB_MSR_ATTR(12), 1134 CMB_MSR_ATTR(13), 1135 CMB_MSR_ATTR(14), 1136 CMB_MSR_ATTR(15), 1137 CMB_MSR_ATTR(16), 1138 CMB_MSR_ATTR(17), 1139 CMB_MSR_ATTR(18), 1140 CMB_MSR_ATTR(19), 1141 CMB_MSR_ATTR(20), 1142 CMB_MSR_ATTR(21), 1143 CMB_MSR_ATTR(22), 1144 CMB_MSR_ATTR(23), 1145 CMB_MSR_ATTR(24), 1146 CMB_MSR_ATTR(25), 1147 CMB_MSR_ATTR(26), 1148 CMB_MSR_ATTR(27), 1149 CMB_MSR_ATTR(28), 1150 CMB_MSR_ATTR(29), 1151 CMB_MSR_ATTR(30), 1152 CMB_MSR_ATTR(31), 1153 NULL, 1154 }; 1155 1156 static struct attribute *tpdm_dsb_attrs[] = { 1157 &dev_attr_dsb_mode.attr, 1158 &dev_attr_dsb_trig_ts.attr, 1159 &dev_attr_dsb_trig_type.attr, 1160 NULL, 1161 }; 1162 1163 static struct attribute *tpdm_cmb_attrs[] = { 1164 &dev_attr_cmb_mode.attr, 1165 &dev_attr_cmb_ts_all.attr, 1166 &dev_attr_cmb_trig_ts.attr, 1167 NULL, 1168 }; 1169 1170 static struct attribute_group tpdm_dsb_attr_grp = { 1171 .attrs = tpdm_dsb_attrs, 1172 .is_visible = tpdm_dsb_is_visible, 1173 }; 1174 1175 static struct attribute_group tpdm_dsb_edge_grp = { 1176 .attrs = tpdm_dsb_edge_attrs, 1177 .is_visible = tpdm_dsb_is_visible, 1178 .name = "dsb_edge", 1179 }; 1180 1181 static struct attribute_group tpdm_dsb_trig_patt_grp = { 1182 .attrs = tpdm_dsb_trig_patt_attrs, 1183 .is_visible = tpdm_dsb_is_visible, 1184 .name = "dsb_trig_patt", 1185 }; 1186 1187 static struct attribute_group tpdm_dsb_patt_grp = { 1188 .attrs = tpdm_dsb_patt_attrs, 1189 .is_visible = tpdm_dsb_is_visible, 1190 .name = "dsb_patt", 1191 }; 1192 1193 static struct attribute_group tpdm_dsb_msr_grp = { 1194 .attrs = tpdm_dsb_msr_attrs, 1195 .is_visible = tpdm_dsb_msr_is_visible, 1196 .name = "dsb_msr", 1197 }; 1198 1199 static struct attribute_group tpdm_cmb_attr_grp = { 1200 .attrs = tpdm_cmb_attrs, 1201 .is_visible = tpdm_cmb_is_visible, 1202 }; 1203 1204 static struct attribute_group tpdm_cmb_trig_patt_grp = { 1205 .attrs = tpdm_cmb_trig_patt_attrs, 1206 .is_visible = tpdm_cmb_is_visible, 1207 .name = "cmb_trig_patt", 1208 }; 1209 1210 static struct attribute_group tpdm_cmb_patt_grp = { 1211 .attrs = tpdm_cmb_patt_attrs, 1212 .is_visible = tpdm_cmb_is_visible, 1213 .name = "cmb_patt", 1214 }; 1215 1216 static struct attribute_group tpdm_cmb_msr_grp = { 1217 .attrs = tpdm_cmb_msr_attrs, 1218 .is_visible = tpdm_cmb_msr_is_visible, 1219 .name = "cmb_msr", 1220 }; 1221 1222 static const struct attribute_group *tpdm_attr_grps[] = { 1223 &tpdm_attr_grp, 1224 &tpdm_dsb_attr_grp, 1225 &tpdm_dsb_edge_grp, 1226 &tpdm_dsb_trig_patt_grp, 1227 &tpdm_dsb_patt_grp, 1228 &tpdm_dsb_msr_grp, 1229 &tpdm_cmb_attr_grp, 1230 &tpdm_cmb_trig_patt_grp, 1231 &tpdm_cmb_patt_grp, 1232 &tpdm_cmb_msr_grp, 1233 NULL, 1234 }; 1235 1236 static int tpdm_probe(struct amba_device *adev, const struct amba_id *id) 1237 { 1238 void __iomem *base; 1239 struct device *dev = &adev->dev; 1240 struct coresight_platform_data *pdata; 1241 struct tpdm_drvdata *drvdata; 1242 struct coresight_desc desc = { 0 }; 1243 int ret; 1244 1245 pdata = coresight_get_platform_data(dev); 1246 if (IS_ERR(pdata)) 1247 return PTR_ERR(pdata); 1248 adev->dev.platform_data = pdata; 1249 1250 /* driver data*/ 1251 drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); 1252 if (!drvdata) 1253 return -ENOMEM; 1254 drvdata->dev = &adev->dev; 1255 dev_set_drvdata(dev, drvdata); 1256 1257 base = devm_ioremap_resource(dev, &adev->res); 1258 if (IS_ERR(base)) 1259 return PTR_ERR(base); 1260 1261 drvdata->base = base; 1262 1263 ret = tpdm_datasets_setup(drvdata); 1264 if (ret) 1265 return ret; 1266 1267 if (drvdata && tpdm_has_dsb_dataset(drvdata)) 1268 of_property_read_u32(drvdata->dev->of_node, 1269 "qcom,dsb-msrs-num", &drvdata->dsb_msr_num); 1270 1271 if (drvdata && tpdm_has_cmb_dataset(drvdata)) 1272 of_property_read_u32(drvdata->dev->of_node, 1273 "qcom,cmb-msrs-num", &drvdata->cmb_msr_num); 1274 1275 /* Set up coresight component description */ 1276 desc.name = coresight_alloc_device_name(&tpdm_devs, dev); 1277 if (!desc.name) 1278 return -ENOMEM; 1279 desc.type = CORESIGHT_DEV_TYPE_SOURCE; 1280 desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM; 1281 desc.ops = &tpdm_cs_ops; 1282 desc.pdata = adev->dev.platform_data; 1283 desc.dev = &adev->dev; 1284 desc.access = CSDEV_ACCESS_IOMEM(base); 1285 desc.groups = tpdm_attr_grps; 1286 drvdata->csdev = coresight_register(&desc); 1287 if (IS_ERR(drvdata->csdev)) 1288 return PTR_ERR(drvdata->csdev); 1289 1290 spin_lock_init(&drvdata->spinlock); 1291 1292 /* Decrease pm refcount when probe is done.*/ 1293 pm_runtime_put(&adev->dev); 1294 1295 return 0; 1296 } 1297 1298 static void tpdm_remove(struct amba_device *adev) 1299 { 1300 struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev); 1301 1302 coresight_unregister(drvdata->csdev); 1303 } 1304 1305 /* 1306 * Different TPDM has different periph id. 1307 * The difference is 0-7 bits' value. So ignore 0-7 bits. 1308 */ 1309 static struct amba_id tpdm_ids[] = { 1310 { 1311 .id = 0x000f0e00, 1312 .mask = 0x000fff00, 1313 }, 1314 { 0, 0, NULL }, 1315 }; 1316 1317 static struct amba_driver tpdm_driver = { 1318 .drv = { 1319 .name = "coresight-tpdm", 1320 .suppress_bind_attrs = true, 1321 }, 1322 .probe = tpdm_probe, 1323 .id_table = tpdm_ids, 1324 .remove = tpdm_remove, 1325 }; 1326 1327 module_amba_driver(tpdm_driver); 1328 1329 MODULE_LICENSE("GPL"); 1330 MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver"); 1331