1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Intel(R) Trace Hub driver core 4 * 5 * Copyright (C) 2014-2015 Intel Corporation. 6 */ 7 8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 9 10 #include <linux/types.h> 11 #include <linux/module.h> 12 #include <linux/device.h> 13 #include <linux/sysfs.h> 14 #include <linux/kdev_t.h> 15 #include <linux/debugfs.h> 16 #include <linux/idr.h> 17 #include <linux/pci.h> 18 #include <linux/pm_runtime.h> 19 #include <linux/dma-mapping.h> 20 21 #include "intel_th.h" 22 #include "debug.h" 23 24 static bool host_mode __read_mostly; 25 module_param(host_mode, bool, 0444); 26 27 static DEFINE_IDA(intel_th_ida); 28 29 static int intel_th_match(struct device *dev, struct device_driver *driver) 30 { 31 struct intel_th_driver *thdrv = to_intel_th_driver(driver); 32 struct intel_th_device *thdev = to_intel_th_device(dev); 33 34 if (thdev->type == INTEL_TH_SWITCH && 35 (!thdrv->enable || !thdrv->disable)) 36 return 0; 37 38 return !strcmp(thdev->name, driver->name); 39 } 40 41 static int intel_th_child_remove(struct device *dev, void *data) 42 { 43 device_release_driver(dev); 44 45 return 0; 46 } 47 48 static int intel_th_probe(struct device *dev) 49 { 50 struct intel_th_driver *thdrv = to_intel_th_driver(dev->driver); 51 struct intel_th_device *thdev = to_intel_th_device(dev); 52 struct intel_th_driver *hubdrv; 53 struct intel_th_device *hub = NULL; 54 int ret; 55 56 if (thdev->type == INTEL_TH_SWITCH) 57 hub = thdev; 58 else if (dev->parent) 59 hub = to_intel_th_device(dev->parent); 60 61 if (!hub || !hub->dev.driver) 62 return -EPROBE_DEFER; 63 64 hubdrv = to_intel_th_driver(hub->dev.driver); 65 66 pm_runtime_set_active(dev); 67 pm_runtime_no_callbacks(dev); 68 pm_runtime_enable(dev); 69 70 ret = thdrv->probe(to_intel_th_device(dev)); 71 if (ret) 72 goto out_pm; 73 74 if (thdrv->attr_group) { 75 ret = sysfs_create_group(&thdev->dev.kobj, thdrv->attr_group); 76 if (ret) 77 goto out; 78 } 79 80 if (thdev->type == INTEL_TH_OUTPUT && 81 !intel_th_output_assigned(thdev)) 82 /* does not talk to hardware */ 83 ret = hubdrv->assign(hub, thdev); 84 85 out: 86 if (ret) 87 thdrv->remove(thdev); 88 89 out_pm: 90 if (ret) 91 pm_runtime_disable(dev); 92 93 return ret; 94 } 95 96 static void intel_th_device_remove(struct intel_th_device *thdev); 97 98 static int intel_th_remove(struct device *dev) 99 { 100 struct intel_th_driver *thdrv = to_intel_th_driver(dev->driver); 101 struct intel_th_device *thdev = to_intel_th_device(dev); 102 struct intel_th_device *hub = to_intel_th_hub(thdev); 103 int err; 104 105 if (thdev->type == INTEL_TH_SWITCH) { 106 struct intel_th *th = to_intel_th(hub); 107 int i, lowest; 108 109 /* disconnect outputs */ 110 err = device_for_each_child(dev, thdev, intel_th_child_remove); 111 if (err) 112 return err; 113 114 /* 115 * Remove outputs, that is, hub's children: they are created 116 * at hub's probe time by having the hub call 117 * intel_th_output_enable() for each of them. 118 */ 119 for (i = 0, lowest = -1; i < th->num_thdevs; i++) { 120 /* 121 * Move the non-output devices from higher up the 122 * th->thdev[] array to lower positions to maintain 123 * a contiguous array. 124 */ 125 if (th->thdev[i]->type != INTEL_TH_OUTPUT) { 126 if (lowest >= 0) { 127 th->thdev[lowest] = th->thdev[i]; 128 th->thdev[i] = NULL; 129 ++lowest; 130 } 131 132 continue; 133 } 134 135 if (lowest == -1) 136 lowest = i; 137 138 intel_th_device_remove(th->thdev[i]); 139 th->thdev[i] = NULL; 140 } 141 142 if (lowest >= 0) 143 th->num_thdevs = lowest; 144 } 145 146 if (thdrv->attr_group) 147 sysfs_remove_group(&thdev->dev.kobj, thdrv->attr_group); 148 149 pm_runtime_get_sync(dev); 150 151 thdrv->remove(thdev); 152 153 if (intel_th_output_assigned(thdev)) { 154 struct intel_th_driver *hubdrv = 155 to_intel_th_driver(dev->parent->driver); 156 157 if (hub->dev.driver) 158 /* does not talk to hardware */ 159 hubdrv->unassign(hub, thdev); 160 } 161 162 pm_runtime_disable(dev); 163 pm_runtime_set_active(dev); 164 pm_runtime_enable(dev); 165 166 return 0; 167 } 168 169 static struct bus_type intel_th_bus = { 170 .name = "intel_th", 171 .match = intel_th_match, 172 .probe = intel_th_probe, 173 .remove = intel_th_remove, 174 }; 175 176 static void intel_th_device_free(struct intel_th_device *thdev); 177 178 static void intel_th_device_release(struct device *dev) 179 { 180 intel_th_device_free(to_intel_th_device(dev)); 181 } 182 183 static struct device_type intel_th_source_device_type = { 184 .name = "intel_th_source_device", 185 .release = intel_th_device_release, 186 }; 187 188 static char *intel_th_output_devnode(struct device *dev, umode_t *mode, 189 kuid_t *uid, kgid_t *gid) 190 { 191 struct intel_th_device *thdev = to_intel_th_device(dev); 192 struct intel_th *th = to_intel_th(thdev); 193 char *node; 194 195 if (thdev->id >= 0) 196 node = kasprintf(GFP_KERNEL, "intel_th%d/%s%d", th->id, 197 thdev->name, thdev->id); 198 else 199 node = kasprintf(GFP_KERNEL, "intel_th%d/%s", th->id, 200 thdev->name); 201 202 return node; 203 } 204 205 static ssize_t port_show(struct device *dev, struct device_attribute *attr, 206 char *buf) 207 { 208 struct intel_th_device *thdev = to_intel_th_device(dev); 209 210 if (thdev->output.port >= 0) 211 return scnprintf(buf, PAGE_SIZE, "%u\n", thdev->output.port); 212 213 return scnprintf(buf, PAGE_SIZE, "unassigned\n"); 214 } 215 216 static DEVICE_ATTR_RO(port); 217 218 static int intel_th_output_activate(struct intel_th_device *thdev) 219 { 220 struct intel_th_driver *thdrv = 221 to_intel_th_driver_or_null(thdev->dev.driver); 222 struct intel_th *th = to_intel_th(thdev); 223 int ret = 0; 224 225 if (!thdrv) 226 return -ENODEV; 227 228 if (!try_module_get(thdrv->driver.owner)) 229 return -ENODEV; 230 231 pm_runtime_get_sync(&thdev->dev); 232 233 if (th->activate) 234 ret = th->activate(th); 235 if (ret) 236 goto fail_put; 237 238 if (thdrv->activate) 239 ret = thdrv->activate(thdev); 240 else 241 intel_th_trace_enable(thdev); 242 243 if (ret) 244 goto fail_deactivate; 245 246 return 0; 247 248 fail_deactivate: 249 if (th->deactivate) 250 th->deactivate(th); 251 252 fail_put: 253 pm_runtime_put(&thdev->dev); 254 module_put(thdrv->driver.owner); 255 256 return ret; 257 } 258 259 static void intel_th_output_deactivate(struct intel_th_device *thdev) 260 { 261 struct intel_th_driver *thdrv = 262 to_intel_th_driver_or_null(thdev->dev.driver); 263 struct intel_th *th = to_intel_th(thdev); 264 265 if (!thdrv) 266 return; 267 268 if (thdrv->deactivate) 269 thdrv->deactivate(thdev); 270 else 271 intel_th_trace_disable(thdev); 272 273 if (th->deactivate) 274 th->deactivate(th); 275 276 pm_runtime_put(&thdev->dev); 277 module_put(thdrv->driver.owner); 278 } 279 280 static ssize_t active_show(struct device *dev, struct device_attribute *attr, 281 char *buf) 282 { 283 struct intel_th_device *thdev = to_intel_th_device(dev); 284 285 return scnprintf(buf, PAGE_SIZE, "%d\n", thdev->output.active); 286 } 287 288 static ssize_t active_store(struct device *dev, struct device_attribute *attr, 289 const char *buf, size_t size) 290 { 291 struct intel_th_device *thdev = to_intel_th_device(dev); 292 unsigned long val; 293 int ret; 294 295 ret = kstrtoul(buf, 10, &val); 296 if (ret) 297 return ret; 298 299 if (!!val != thdev->output.active) { 300 if (val) 301 ret = intel_th_output_activate(thdev); 302 else 303 intel_th_output_deactivate(thdev); 304 } 305 306 return ret ? ret : size; 307 } 308 309 static DEVICE_ATTR_RW(active); 310 311 static struct attribute *intel_th_output_attrs[] = { 312 &dev_attr_port.attr, 313 &dev_attr_active.attr, 314 NULL, 315 }; 316 317 ATTRIBUTE_GROUPS(intel_th_output); 318 319 static struct device_type intel_th_output_device_type = { 320 .name = "intel_th_output_device", 321 .groups = intel_th_output_groups, 322 .release = intel_th_device_release, 323 .devnode = intel_th_output_devnode, 324 }; 325 326 static struct device_type intel_th_switch_device_type = { 327 .name = "intel_th_switch_device", 328 .release = intel_th_device_release, 329 }; 330 331 static struct device_type *intel_th_device_type[] = { 332 [INTEL_TH_SOURCE] = &intel_th_source_device_type, 333 [INTEL_TH_OUTPUT] = &intel_th_output_device_type, 334 [INTEL_TH_SWITCH] = &intel_th_switch_device_type, 335 }; 336 337 int intel_th_driver_register(struct intel_th_driver *thdrv) 338 { 339 if (!thdrv->probe || !thdrv->remove) 340 return -EINVAL; 341 342 thdrv->driver.bus = &intel_th_bus; 343 344 return driver_register(&thdrv->driver); 345 } 346 EXPORT_SYMBOL_GPL(intel_th_driver_register); 347 348 void intel_th_driver_unregister(struct intel_th_driver *thdrv) 349 { 350 driver_unregister(&thdrv->driver); 351 } 352 EXPORT_SYMBOL_GPL(intel_th_driver_unregister); 353 354 static struct intel_th_device * 355 intel_th_device_alloc(struct intel_th *th, unsigned int type, const char *name, 356 int id) 357 { 358 struct device *parent; 359 struct intel_th_device *thdev; 360 361 if (type == INTEL_TH_OUTPUT) 362 parent = &th->hub->dev; 363 else 364 parent = th->dev; 365 366 thdev = kzalloc(sizeof(*thdev) + strlen(name) + 1, GFP_KERNEL); 367 if (!thdev) 368 return NULL; 369 370 thdev->id = id; 371 thdev->type = type; 372 373 strcpy(thdev->name, name); 374 device_initialize(&thdev->dev); 375 thdev->dev.bus = &intel_th_bus; 376 thdev->dev.type = intel_th_device_type[type]; 377 thdev->dev.parent = parent; 378 thdev->dev.dma_mask = parent->dma_mask; 379 thdev->dev.dma_parms = parent->dma_parms; 380 dma_set_coherent_mask(&thdev->dev, parent->coherent_dma_mask); 381 if (id >= 0) 382 dev_set_name(&thdev->dev, "%d-%s%d", th->id, name, id); 383 else 384 dev_set_name(&thdev->dev, "%d-%s", th->id, name); 385 386 return thdev; 387 } 388 389 static int intel_th_device_add_resources(struct intel_th_device *thdev, 390 struct resource *res, int nres) 391 { 392 struct resource *r; 393 394 r = kmemdup(res, sizeof(*res) * nres, GFP_KERNEL); 395 if (!r) 396 return -ENOMEM; 397 398 thdev->resource = r; 399 thdev->num_resources = nres; 400 401 return 0; 402 } 403 404 static void intel_th_device_remove(struct intel_th_device *thdev) 405 { 406 device_del(&thdev->dev); 407 put_device(&thdev->dev); 408 } 409 410 static void intel_th_device_free(struct intel_th_device *thdev) 411 { 412 kfree(thdev->resource); 413 kfree(thdev); 414 } 415 416 /* 417 * Intel(R) Trace Hub subdevices 418 */ 419 static const struct intel_th_subdevice { 420 const char *name; 421 struct resource res[3]; 422 unsigned nres; 423 unsigned type; 424 unsigned otype; 425 bool mknode; 426 unsigned scrpd; 427 int id; 428 } intel_th_subdevices[] = { 429 { 430 .nres = 1, 431 .res = { 432 { 433 /* Handle TSCU and CTS from GTH driver */ 434 .start = REG_GTH_OFFSET, 435 .end = REG_CTS_OFFSET + REG_CTS_LENGTH - 1, 436 .flags = IORESOURCE_MEM, 437 }, 438 }, 439 .name = "gth", 440 .type = INTEL_TH_SWITCH, 441 .id = -1, 442 }, 443 { 444 .nres = 2, 445 .res = { 446 { 447 .start = REG_MSU_OFFSET, 448 .end = REG_MSU_OFFSET + REG_MSU_LENGTH - 1, 449 .flags = IORESOURCE_MEM, 450 }, 451 { 452 .start = BUF_MSU_OFFSET, 453 .end = BUF_MSU_OFFSET + BUF_MSU_LENGTH - 1, 454 .flags = IORESOURCE_MEM, 455 }, 456 }, 457 .name = "msc", 458 .id = 0, 459 .type = INTEL_TH_OUTPUT, 460 .mknode = true, 461 .otype = GTH_MSU, 462 .scrpd = SCRPD_MEM_IS_PRIM_DEST | SCRPD_MSC0_IS_ENABLED, 463 }, 464 { 465 .nres = 2, 466 .res = { 467 { 468 .start = REG_MSU_OFFSET, 469 .end = REG_MSU_OFFSET + REG_MSU_LENGTH - 1, 470 .flags = IORESOURCE_MEM, 471 }, 472 { 473 .start = BUF_MSU_OFFSET, 474 .end = BUF_MSU_OFFSET + BUF_MSU_LENGTH - 1, 475 .flags = IORESOURCE_MEM, 476 }, 477 }, 478 .name = "msc", 479 .id = 1, 480 .type = INTEL_TH_OUTPUT, 481 .mknode = true, 482 .otype = GTH_MSU, 483 .scrpd = SCRPD_MEM_IS_PRIM_DEST | SCRPD_MSC1_IS_ENABLED, 484 }, 485 { 486 .nres = 2, 487 .res = { 488 { 489 .start = REG_STH_OFFSET, 490 .end = REG_STH_OFFSET + REG_STH_LENGTH - 1, 491 .flags = IORESOURCE_MEM, 492 }, 493 { 494 .start = TH_MMIO_SW, 495 .end = 0, 496 .flags = IORESOURCE_MEM, 497 }, 498 }, 499 .id = -1, 500 .name = "sth", 501 .type = INTEL_TH_SOURCE, 502 }, 503 { 504 .nres = 2, 505 .res = { 506 { 507 .start = REG_STH_OFFSET, 508 .end = REG_STH_OFFSET + REG_STH_LENGTH - 1, 509 .flags = IORESOURCE_MEM, 510 }, 511 { 512 .start = TH_MMIO_RTIT, 513 .end = 0, 514 .flags = IORESOURCE_MEM, 515 }, 516 }, 517 .id = -1, 518 .name = "rtit", 519 .type = INTEL_TH_SOURCE, 520 }, 521 { 522 .nres = 1, 523 .res = { 524 { 525 .start = REG_PTI_OFFSET, 526 .end = REG_PTI_OFFSET + REG_PTI_LENGTH - 1, 527 .flags = IORESOURCE_MEM, 528 }, 529 }, 530 .id = -1, 531 .name = "pti", 532 .type = INTEL_TH_OUTPUT, 533 .otype = GTH_PTI, 534 .scrpd = SCRPD_PTI_IS_PRIM_DEST, 535 }, 536 { 537 .nres = 1, 538 .res = { 539 { 540 .start = REG_PTI_OFFSET, 541 .end = REG_PTI_OFFSET + REG_PTI_LENGTH - 1, 542 .flags = IORESOURCE_MEM, 543 }, 544 }, 545 .id = -1, 546 .name = "lpp", 547 .type = INTEL_TH_OUTPUT, 548 .otype = GTH_LPP, 549 .scrpd = SCRPD_PTI_IS_PRIM_DEST, 550 }, 551 { 552 .nres = 1, 553 .res = { 554 { 555 .start = REG_DCIH_OFFSET, 556 .end = REG_DCIH_OFFSET + REG_DCIH_LENGTH - 1, 557 .flags = IORESOURCE_MEM, 558 }, 559 }, 560 .id = -1, 561 .name = "dcih", 562 .type = INTEL_TH_OUTPUT, 563 }, 564 }; 565 566 #ifdef CONFIG_MODULES 567 static void __intel_th_request_hub_module(struct work_struct *work) 568 { 569 struct intel_th *th = container_of(work, struct intel_th, 570 request_module_work); 571 572 request_module("intel_th_%s", th->hub->name); 573 } 574 575 static int intel_th_request_hub_module(struct intel_th *th) 576 { 577 INIT_WORK(&th->request_module_work, __intel_th_request_hub_module); 578 schedule_work(&th->request_module_work); 579 580 return 0; 581 } 582 583 static void intel_th_request_hub_module_flush(struct intel_th *th) 584 { 585 flush_work(&th->request_module_work); 586 } 587 #else 588 static inline int intel_th_request_hub_module(struct intel_th *th) 589 { 590 return -EINVAL; 591 } 592 593 static inline void intel_th_request_hub_module_flush(struct intel_th *th) 594 { 595 } 596 #endif /* CONFIG_MODULES */ 597 598 static struct intel_th_device * 599 intel_th_subdevice_alloc(struct intel_th *th, 600 const struct intel_th_subdevice *subdev) 601 { 602 struct intel_th_device *thdev; 603 struct resource res[3]; 604 unsigned int req = 0; 605 int r, err; 606 607 thdev = intel_th_device_alloc(th, subdev->type, subdev->name, 608 subdev->id); 609 if (!thdev) 610 return ERR_PTR(-ENOMEM); 611 612 thdev->drvdata = th->drvdata; 613 614 memcpy(res, subdev->res, 615 sizeof(struct resource) * subdev->nres); 616 617 for (r = 0; r < subdev->nres; r++) { 618 struct resource *devres = th->resource; 619 int bar = TH_MMIO_CONFIG; 620 621 /* 622 * Take .end == 0 to mean 'take the whole bar', 623 * .start then tells us which bar it is. Default to 624 * TH_MMIO_CONFIG. 625 */ 626 if (!res[r].end && res[r].flags == IORESOURCE_MEM) { 627 bar = res[r].start; 628 err = -ENODEV; 629 if (bar >= th->num_resources) 630 goto fail_put_device; 631 res[r].start = 0; 632 res[r].end = resource_size(&devres[bar]) - 1; 633 } 634 635 if (res[r].flags & IORESOURCE_MEM) { 636 res[r].start += devres[bar].start; 637 res[r].end += devres[bar].start; 638 639 dev_dbg(th->dev, "%s:%d @ %pR\n", 640 subdev->name, r, &res[r]); 641 } else if (res[r].flags & IORESOURCE_IRQ) { 642 /* 643 * Only pass on the IRQ if we have useful interrupts: 644 * the ones that can be configured via MINTCTL. 645 */ 646 if (INTEL_TH_CAP(th, has_mintctl) && th->irq != -1) 647 res[r].start = th->irq; 648 } 649 } 650 651 err = intel_th_device_add_resources(thdev, res, subdev->nres); 652 if (err) { 653 put_device(&thdev->dev); 654 goto fail_put_device; 655 } 656 657 if (subdev->type == INTEL_TH_OUTPUT) { 658 if (subdev->mknode) 659 thdev->dev.devt = MKDEV(th->major, th->num_thdevs); 660 thdev->output.type = subdev->otype; 661 thdev->output.port = -1; 662 thdev->output.scratchpad = subdev->scrpd; 663 } else if (subdev->type == INTEL_TH_SWITCH) { 664 thdev->host_mode = 665 INTEL_TH_CAP(th, host_mode_only) ? true : host_mode; 666 th->hub = thdev; 667 } 668 669 err = device_add(&thdev->dev); 670 if (err) { 671 put_device(&thdev->dev); 672 goto fail_free_res; 673 } 674 675 /* need switch driver to be loaded to enumerate the rest */ 676 if (subdev->type == INTEL_TH_SWITCH && !req) { 677 err = intel_th_request_hub_module(th); 678 if (!err) 679 req++; 680 } 681 682 return thdev; 683 684 fail_free_res: 685 kfree(thdev->resource); 686 687 fail_put_device: 688 put_device(&thdev->dev); 689 690 return ERR_PTR(err); 691 } 692 693 /** 694 * intel_th_output_enable() - find and enable a device for a given output type 695 * @th: Intel TH instance 696 * @otype: output type 697 * 698 * Go through the unallocated output devices, find the first one whos type 699 * matches @otype and instantiate it. These devices are removed when the hub 700 * device is removed, see intel_th_remove(). 701 */ 702 int intel_th_output_enable(struct intel_th *th, unsigned int otype) 703 { 704 struct intel_th_device *thdev; 705 int src = 0, dst = 0; 706 707 for (src = 0, dst = 0; dst <= th->num_thdevs; src++, dst++) { 708 for (; src < ARRAY_SIZE(intel_th_subdevices); src++) { 709 if (intel_th_subdevices[src].type != INTEL_TH_OUTPUT) 710 continue; 711 712 if (intel_th_subdevices[src].otype != otype) 713 continue; 714 715 break; 716 } 717 718 /* no unallocated matching subdevices */ 719 if (src == ARRAY_SIZE(intel_th_subdevices)) 720 return -ENODEV; 721 722 for (; dst < th->num_thdevs; dst++) { 723 if (th->thdev[dst]->type != INTEL_TH_OUTPUT) 724 continue; 725 726 if (th->thdev[dst]->output.type != otype) 727 continue; 728 729 break; 730 } 731 732 /* 733 * intel_th_subdevices[src] matches our requirements and is 734 * not matched in th::thdev[] 735 */ 736 if (dst == th->num_thdevs) 737 goto found; 738 } 739 740 return -ENODEV; 741 742 found: 743 thdev = intel_th_subdevice_alloc(th, &intel_th_subdevices[src]); 744 if (IS_ERR(thdev)) 745 return PTR_ERR(thdev); 746 747 th->thdev[th->num_thdevs++] = thdev; 748 749 return 0; 750 } 751 EXPORT_SYMBOL_GPL(intel_th_output_enable); 752 753 static int intel_th_populate(struct intel_th *th) 754 { 755 int src; 756 757 /* create devices for each intel_th_subdevice */ 758 for (src = 0; src < ARRAY_SIZE(intel_th_subdevices); src++) { 759 const struct intel_th_subdevice *subdev = 760 &intel_th_subdevices[src]; 761 struct intel_th_device *thdev; 762 763 /* only allow SOURCE and SWITCH devices in host mode */ 764 if ((INTEL_TH_CAP(th, host_mode_only) || host_mode) && 765 subdev->type == INTEL_TH_OUTPUT) 766 continue; 767 768 /* 769 * don't enable port OUTPUTs in this path; SWITCH enables them 770 * via intel_th_output_enable() 771 */ 772 if (subdev->type == INTEL_TH_OUTPUT && 773 subdev->otype != GTH_NONE) 774 continue; 775 776 thdev = intel_th_subdevice_alloc(th, subdev); 777 /* note: caller should free subdevices from th::thdev[] */ 778 if (IS_ERR(thdev)) { 779 /* ENODEV for individual subdevices is allowed */ 780 if (PTR_ERR(thdev) == -ENODEV) 781 continue; 782 783 return PTR_ERR(thdev); 784 } 785 786 th->thdev[th->num_thdevs++] = thdev; 787 } 788 789 return 0; 790 } 791 792 static int match_devt(struct device *dev, void *data) 793 { 794 dev_t devt = (dev_t)(unsigned long)data; 795 796 return dev->devt == devt; 797 } 798 799 static int intel_th_output_open(struct inode *inode, struct file *file) 800 { 801 const struct file_operations *fops; 802 struct intel_th_driver *thdrv; 803 struct device *dev; 804 int err; 805 806 dev = bus_find_device(&intel_th_bus, NULL, 807 (void *)(unsigned long)inode->i_rdev, 808 match_devt); 809 if (!dev || !dev->driver) 810 return -ENODEV; 811 812 thdrv = to_intel_th_driver(dev->driver); 813 fops = fops_get(thdrv->fops); 814 if (!fops) 815 return -ENODEV; 816 817 replace_fops(file, fops); 818 819 file->private_data = to_intel_th_device(dev); 820 821 if (file->f_op->open) { 822 err = file->f_op->open(inode, file); 823 return err; 824 } 825 826 return 0; 827 } 828 829 static const struct file_operations intel_th_output_fops = { 830 .open = intel_th_output_open, 831 .llseek = noop_llseek, 832 }; 833 834 static irqreturn_t intel_th_irq(int irq, void *data) 835 { 836 struct intel_th *th = data; 837 irqreturn_t ret = IRQ_NONE; 838 struct intel_th_driver *d; 839 int i; 840 841 for (i = 0; i < th->num_thdevs; i++) { 842 if (th->thdev[i]->type != INTEL_TH_OUTPUT) 843 continue; 844 845 d = to_intel_th_driver(th->thdev[i]->dev.driver); 846 if (d && d->irq) 847 ret |= d->irq(th->thdev[i]); 848 } 849 850 if (ret == IRQ_NONE) 851 pr_warn_ratelimited("nobody cared for irq\n"); 852 853 return ret; 854 } 855 856 /** 857 * intel_th_alloc() - allocate a new Intel TH device and its subdevices 858 * @dev: parent device 859 * @devres: resources indexed by th_mmio_idx 860 * @irq: irq number 861 */ 862 struct intel_th * 863 intel_th_alloc(struct device *dev, struct intel_th_drvdata *drvdata, 864 struct resource *devres, unsigned int ndevres) 865 { 866 int err, r, nr_mmios = 0; 867 struct intel_th *th; 868 869 th = kzalloc(sizeof(*th), GFP_KERNEL); 870 if (!th) 871 return ERR_PTR(-ENOMEM); 872 873 th->id = ida_simple_get(&intel_th_ida, 0, 0, GFP_KERNEL); 874 if (th->id < 0) { 875 err = th->id; 876 goto err_alloc; 877 } 878 879 th->major = __register_chrdev(0, 0, TH_POSSIBLE_OUTPUTS, 880 "intel_th/output", &intel_th_output_fops); 881 if (th->major < 0) { 882 err = th->major; 883 goto err_ida; 884 } 885 th->irq = -1; 886 th->dev = dev; 887 th->drvdata = drvdata; 888 889 for (r = 0; r < ndevres; r++) 890 switch (devres[r].flags & IORESOURCE_TYPE_BITS) { 891 case IORESOURCE_MEM: 892 th->resource[nr_mmios++] = devres[r]; 893 break; 894 case IORESOURCE_IRQ: 895 err = devm_request_irq(dev, devres[r].start, 896 intel_th_irq, IRQF_SHARED, 897 dev_name(dev), th); 898 if (err) 899 goto err_chrdev; 900 901 if (th->irq == -1) 902 th->irq = devres[r].start; 903 break; 904 default: 905 dev_warn(dev, "Unknown resource type %lx\n", 906 devres[r].flags); 907 break; 908 } 909 910 th->num_resources = nr_mmios; 911 912 dev_set_drvdata(dev, th); 913 914 pm_runtime_no_callbacks(dev); 915 pm_runtime_put(dev); 916 pm_runtime_allow(dev); 917 918 err = intel_th_populate(th); 919 if (err) { 920 /* free the subdevices and undo everything */ 921 intel_th_free(th); 922 return ERR_PTR(err); 923 } 924 925 return th; 926 927 err_chrdev: 928 __unregister_chrdev(th->major, 0, TH_POSSIBLE_OUTPUTS, 929 "intel_th/output"); 930 931 err_ida: 932 ida_simple_remove(&intel_th_ida, th->id); 933 934 err_alloc: 935 kfree(th); 936 937 return ERR_PTR(err); 938 } 939 EXPORT_SYMBOL_GPL(intel_th_alloc); 940 941 void intel_th_free(struct intel_th *th) 942 { 943 int i; 944 945 intel_th_request_hub_module_flush(th); 946 947 intel_th_device_remove(th->hub); 948 for (i = 0; i < th->num_thdevs; i++) { 949 if (th->thdev[i] != th->hub) 950 intel_th_device_remove(th->thdev[i]); 951 th->thdev[i] = NULL; 952 } 953 954 th->num_thdevs = 0; 955 956 pm_runtime_get_sync(th->dev); 957 pm_runtime_forbid(th->dev); 958 959 __unregister_chrdev(th->major, 0, TH_POSSIBLE_OUTPUTS, 960 "intel_th/output"); 961 962 ida_simple_remove(&intel_th_ida, th->id); 963 964 kfree(th); 965 } 966 EXPORT_SYMBOL_GPL(intel_th_free); 967 968 /** 969 * intel_th_trace_enable() - enable tracing for an output device 970 * @thdev: output device that requests tracing be enabled 971 */ 972 int intel_th_trace_enable(struct intel_th_device *thdev) 973 { 974 struct intel_th_device *hub = to_intel_th_device(thdev->dev.parent); 975 struct intel_th_driver *hubdrv = to_intel_th_driver(hub->dev.driver); 976 977 if (WARN_ON_ONCE(hub->type != INTEL_TH_SWITCH)) 978 return -EINVAL; 979 980 if (WARN_ON_ONCE(thdev->type != INTEL_TH_OUTPUT)) 981 return -EINVAL; 982 983 pm_runtime_get_sync(&thdev->dev); 984 hubdrv->enable(hub, &thdev->output); 985 986 return 0; 987 } 988 EXPORT_SYMBOL_GPL(intel_th_trace_enable); 989 990 /** 991 * intel_th_trace_switch() - execute a switch sequence 992 * @thdev: output device that requests tracing switch 993 */ 994 int intel_th_trace_switch(struct intel_th_device *thdev) 995 { 996 struct intel_th_device *hub = to_intel_th_device(thdev->dev.parent); 997 struct intel_th_driver *hubdrv = to_intel_th_driver(hub->dev.driver); 998 999 if (WARN_ON_ONCE(hub->type != INTEL_TH_SWITCH)) 1000 return -EINVAL; 1001 1002 if (WARN_ON_ONCE(thdev->type != INTEL_TH_OUTPUT)) 1003 return -EINVAL; 1004 1005 hubdrv->trig_switch(hub, &thdev->output); 1006 1007 return 0; 1008 } 1009 EXPORT_SYMBOL_GPL(intel_th_trace_switch); 1010 1011 /** 1012 * intel_th_trace_disable() - disable tracing for an output device 1013 * @thdev: output device that requests tracing be disabled 1014 */ 1015 int intel_th_trace_disable(struct intel_th_device *thdev) 1016 { 1017 struct intel_th_device *hub = to_intel_th_device(thdev->dev.parent); 1018 struct intel_th_driver *hubdrv = to_intel_th_driver(hub->dev.driver); 1019 1020 WARN_ON_ONCE(hub->type != INTEL_TH_SWITCH); 1021 if (WARN_ON_ONCE(thdev->type != INTEL_TH_OUTPUT)) 1022 return -EINVAL; 1023 1024 hubdrv->disable(hub, &thdev->output); 1025 pm_runtime_put(&thdev->dev); 1026 1027 return 0; 1028 } 1029 EXPORT_SYMBOL_GPL(intel_th_trace_disable); 1030 1031 int intel_th_set_output(struct intel_th_device *thdev, 1032 unsigned int master) 1033 { 1034 struct intel_th_device *hub = to_intel_th_hub(thdev); 1035 struct intel_th_driver *hubdrv = to_intel_th_driver(hub->dev.driver); 1036 1037 /* In host mode, this is up to the external debugger, do nothing. */ 1038 if (hub->host_mode) 1039 return 0; 1040 1041 if (!hubdrv->set_output) 1042 return -ENOTSUPP; 1043 1044 return hubdrv->set_output(hub, master); 1045 } 1046 EXPORT_SYMBOL_GPL(intel_th_set_output); 1047 1048 static int __init intel_th_init(void) 1049 { 1050 intel_th_debug_init(); 1051 1052 return bus_register(&intel_th_bus); 1053 } 1054 subsys_initcall(intel_th_init); 1055 1056 static void __exit intel_th_exit(void) 1057 { 1058 intel_th_debug_done(); 1059 1060 bus_unregister(&intel_th_bus); 1061 } 1062 module_exit(intel_th_exit); 1063 1064 MODULE_LICENSE("GPL v2"); 1065 MODULE_DESCRIPTION("Intel(R) Trace Hub controller driver"); 1066 MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@linux.intel.com>"); 1067