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 th->num_thdevs = lowest; 143 } 144 145 if (thdrv->attr_group) 146 sysfs_remove_group(&thdev->dev.kobj, thdrv->attr_group); 147 148 pm_runtime_get_sync(dev); 149 150 thdrv->remove(thdev); 151 152 if (intel_th_output_assigned(thdev)) { 153 struct intel_th_driver *hubdrv = 154 to_intel_th_driver(dev->parent->driver); 155 156 if (hub->dev.driver) 157 /* does not talk to hardware */ 158 hubdrv->unassign(hub, thdev); 159 } 160 161 pm_runtime_disable(dev); 162 pm_runtime_set_active(dev); 163 pm_runtime_enable(dev); 164 165 return 0; 166 } 167 168 static struct bus_type intel_th_bus = { 169 .name = "intel_th", 170 .match = intel_th_match, 171 .probe = intel_th_probe, 172 .remove = intel_th_remove, 173 }; 174 175 static void intel_th_device_free(struct intel_th_device *thdev); 176 177 static void intel_th_device_release(struct device *dev) 178 { 179 intel_th_device_free(to_intel_th_device(dev)); 180 } 181 182 static struct device_type intel_th_source_device_type = { 183 .name = "intel_th_source_device", 184 .release = intel_th_device_release, 185 }; 186 187 static char *intel_th_output_devnode(struct device *dev, umode_t *mode, 188 kuid_t *uid, kgid_t *gid) 189 { 190 struct intel_th_device *thdev = to_intel_th_device(dev); 191 struct intel_th *th = to_intel_th(thdev); 192 char *node; 193 194 if (thdev->id >= 0) 195 node = kasprintf(GFP_KERNEL, "intel_th%d/%s%d", th->id, 196 thdev->name, thdev->id); 197 else 198 node = kasprintf(GFP_KERNEL, "intel_th%d/%s", th->id, 199 thdev->name); 200 201 return node; 202 } 203 204 static ssize_t port_show(struct device *dev, struct device_attribute *attr, 205 char *buf) 206 { 207 struct intel_th_device *thdev = to_intel_th_device(dev); 208 209 if (thdev->output.port >= 0) 210 return scnprintf(buf, PAGE_SIZE, "%u\n", thdev->output.port); 211 212 return scnprintf(buf, PAGE_SIZE, "unassigned\n"); 213 } 214 215 static DEVICE_ATTR_RO(port); 216 217 static int intel_th_output_activate(struct intel_th_device *thdev) 218 { 219 struct intel_th_driver *thdrv = 220 to_intel_th_driver_or_null(thdev->dev.driver); 221 struct intel_th *th = to_intel_th(thdev); 222 int ret = 0; 223 224 if (!thdrv) 225 return -ENODEV; 226 227 if (!try_module_get(thdrv->driver.owner)) 228 return -ENODEV; 229 230 pm_runtime_get_sync(&thdev->dev); 231 232 if (th->activate) 233 ret = th->activate(th); 234 if (ret) 235 goto fail_put; 236 237 if (thdrv->activate) 238 ret = thdrv->activate(thdev); 239 else 240 intel_th_trace_enable(thdev); 241 242 if (ret) 243 goto fail_deactivate; 244 245 return 0; 246 247 fail_deactivate: 248 if (th->deactivate) 249 th->deactivate(th); 250 251 fail_put: 252 pm_runtime_put(&thdev->dev); 253 module_put(thdrv->driver.owner); 254 255 return ret; 256 } 257 258 static void intel_th_output_deactivate(struct intel_th_device *thdev) 259 { 260 struct intel_th_driver *thdrv = 261 to_intel_th_driver_or_null(thdev->dev.driver); 262 struct intel_th *th = to_intel_th(thdev); 263 264 if (!thdrv) 265 return; 266 267 if (thdrv->deactivate) 268 thdrv->deactivate(thdev); 269 else 270 intel_th_trace_disable(thdev); 271 272 if (th->deactivate) 273 th->deactivate(th); 274 275 pm_runtime_put(&thdev->dev); 276 module_put(thdrv->driver.owner); 277 } 278 279 static ssize_t active_show(struct device *dev, struct device_attribute *attr, 280 char *buf) 281 { 282 struct intel_th_device *thdev = to_intel_th_device(dev); 283 284 return scnprintf(buf, PAGE_SIZE, "%d\n", thdev->output.active); 285 } 286 287 static ssize_t active_store(struct device *dev, struct device_attribute *attr, 288 const char *buf, size_t size) 289 { 290 struct intel_th_device *thdev = to_intel_th_device(dev); 291 unsigned long val; 292 int ret; 293 294 ret = kstrtoul(buf, 10, &val); 295 if (ret) 296 return ret; 297 298 if (!!val != thdev->output.active) { 299 if (val) 300 ret = intel_th_output_activate(thdev); 301 else 302 intel_th_output_deactivate(thdev); 303 } 304 305 return ret ? ret : size; 306 } 307 308 static DEVICE_ATTR_RW(active); 309 310 static struct attribute *intel_th_output_attrs[] = { 311 &dev_attr_port.attr, 312 &dev_attr_active.attr, 313 NULL, 314 }; 315 316 ATTRIBUTE_GROUPS(intel_th_output); 317 318 static struct device_type intel_th_output_device_type = { 319 .name = "intel_th_output_device", 320 .groups = intel_th_output_groups, 321 .release = intel_th_device_release, 322 .devnode = intel_th_output_devnode, 323 }; 324 325 static struct device_type intel_th_switch_device_type = { 326 .name = "intel_th_switch_device", 327 .release = intel_th_device_release, 328 }; 329 330 static struct device_type *intel_th_device_type[] = { 331 [INTEL_TH_SOURCE] = &intel_th_source_device_type, 332 [INTEL_TH_OUTPUT] = &intel_th_output_device_type, 333 [INTEL_TH_SWITCH] = &intel_th_switch_device_type, 334 }; 335 336 int intel_th_driver_register(struct intel_th_driver *thdrv) 337 { 338 if (!thdrv->probe || !thdrv->remove) 339 return -EINVAL; 340 341 thdrv->driver.bus = &intel_th_bus; 342 343 return driver_register(&thdrv->driver); 344 } 345 EXPORT_SYMBOL_GPL(intel_th_driver_register); 346 347 void intel_th_driver_unregister(struct intel_th_driver *thdrv) 348 { 349 driver_unregister(&thdrv->driver); 350 } 351 EXPORT_SYMBOL_GPL(intel_th_driver_unregister); 352 353 static struct intel_th_device * 354 intel_th_device_alloc(struct intel_th *th, unsigned int type, const char *name, 355 int id) 356 { 357 struct device *parent; 358 struct intel_th_device *thdev; 359 360 if (type == INTEL_TH_OUTPUT) 361 parent = &th->hub->dev; 362 else 363 parent = th->dev; 364 365 thdev = kzalloc(sizeof(*thdev) + strlen(name) + 1, GFP_KERNEL); 366 if (!thdev) 367 return NULL; 368 369 thdev->id = id; 370 thdev->type = type; 371 372 strcpy(thdev->name, name); 373 device_initialize(&thdev->dev); 374 thdev->dev.bus = &intel_th_bus; 375 thdev->dev.type = intel_th_device_type[type]; 376 thdev->dev.parent = parent; 377 thdev->dev.dma_mask = parent->dma_mask; 378 thdev->dev.dma_parms = parent->dma_parms; 379 dma_set_coherent_mask(&thdev->dev, parent->coherent_dma_mask); 380 if (id >= 0) 381 dev_set_name(&thdev->dev, "%d-%s%d", th->id, name, id); 382 else 383 dev_set_name(&thdev->dev, "%d-%s", th->id, name); 384 385 return thdev; 386 } 387 388 static int intel_th_device_add_resources(struct intel_th_device *thdev, 389 struct resource *res, int nres) 390 { 391 struct resource *r; 392 393 r = kmemdup(res, sizeof(*res) * nres, GFP_KERNEL); 394 if (!r) 395 return -ENOMEM; 396 397 thdev->resource = r; 398 thdev->num_resources = nres; 399 400 return 0; 401 } 402 403 static void intel_th_device_remove(struct intel_th_device *thdev) 404 { 405 device_del(&thdev->dev); 406 put_device(&thdev->dev); 407 } 408 409 static void intel_th_device_free(struct intel_th_device *thdev) 410 { 411 kfree(thdev->resource); 412 kfree(thdev); 413 } 414 415 /* 416 * Intel(R) Trace Hub subdevices 417 */ 418 static const struct intel_th_subdevice { 419 const char *name; 420 struct resource res[3]; 421 unsigned nres; 422 unsigned type; 423 unsigned otype; 424 unsigned scrpd; 425 int id; 426 } intel_th_subdevices[] = { 427 { 428 .nres = 1, 429 .res = { 430 { 431 /* Handle TSCU from GTH driver */ 432 .start = REG_GTH_OFFSET, 433 .end = REG_TSCU_OFFSET + REG_TSCU_LENGTH - 1, 434 .flags = IORESOURCE_MEM, 435 }, 436 }, 437 .name = "gth", 438 .type = INTEL_TH_SWITCH, 439 .id = -1, 440 }, 441 { 442 .nres = 2, 443 .res = { 444 { 445 .start = REG_MSU_OFFSET, 446 .end = REG_MSU_OFFSET + REG_MSU_LENGTH - 1, 447 .flags = IORESOURCE_MEM, 448 }, 449 { 450 .start = BUF_MSU_OFFSET, 451 .end = BUF_MSU_OFFSET + BUF_MSU_LENGTH - 1, 452 .flags = IORESOURCE_MEM, 453 }, 454 }, 455 .name = "msc", 456 .id = 0, 457 .type = INTEL_TH_OUTPUT, 458 .otype = GTH_MSU, 459 .scrpd = SCRPD_MEM_IS_PRIM_DEST | SCRPD_MSC0_IS_ENABLED, 460 }, 461 { 462 .nres = 2, 463 .res = { 464 { 465 .start = REG_MSU_OFFSET, 466 .end = REG_MSU_OFFSET + REG_MSU_LENGTH - 1, 467 .flags = IORESOURCE_MEM, 468 }, 469 { 470 .start = BUF_MSU_OFFSET, 471 .end = BUF_MSU_OFFSET + BUF_MSU_LENGTH - 1, 472 .flags = IORESOURCE_MEM, 473 }, 474 }, 475 .name = "msc", 476 .id = 1, 477 .type = INTEL_TH_OUTPUT, 478 .otype = GTH_MSU, 479 .scrpd = SCRPD_MEM_IS_PRIM_DEST | SCRPD_MSC1_IS_ENABLED, 480 }, 481 { 482 .nres = 2, 483 .res = { 484 { 485 .start = REG_STH_OFFSET, 486 .end = REG_STH_OFFSET + REG_STH_LENGTH - 1, 487 .flags = IORESOURCE_MEM, 488 }, 489 { 490 .start = TH_MMIO_SW, 491 .end = 0, 492 .flags = IORESOURCE_MEM, 493 }, 494 }, 495 .id = -1, 496 .name = "sth", 497 .type = INTEL_TH_SOURCE, 498 }, 499 { 500 .nres = 1, 501 .res = { 502 { 503 .start = REG_PTI_OFFSET, 504 .end = REG_PTI_OFFSET + REG_PTI_LENGTH - 1, 505 .flags = IORESOURCE_MEM, 506 }, 507 }, 508 .id = -1, 509 .name = "pti", 510 .type = INTEL_TH_OUTPUT, 511 .otype = GTH_PTI, 512 .scrpd = SCRPD_PTI_IS_PRIM_DEST, 513 }, 514 { 515 .nres = 1, 516 .res = { 517 { 518 .start = REG_PTI_OFFSET, 519 .end = REG_PTI_OFFSET + REG_PTI_LENGTH - 1, 520 .flags = IORESOURCE_MEM, 521 }, 522 }, 523 .id = -1, 524 .name = "lpp", 525 .type = INTEL_TH_OUTPUT, 526 .otype = GTH_LPP, 527 .scrpd = SCRPD_PTI_IS_PRIM_DEST, 528 }, 529 { 530 .nres = 1, 531 .res = { 532 { 533 .start = REG_DCIH_OFFSET, 534 .end = REG_DCIH_OFFSET + REG_DCIH_LENGTH - 1, 535 .flags = IORESOURCE_MEM, 536 }, 537 }, 538 .id = -1, 539 .name = "dcih", 540 .type = INTEL_TH_OUTPUT, 541 }, 542 }; 543 544 #ifdef CONFIG_MODULES 545 static void __intel_th_request_hub_module(struct work_struct *work) 546 { 547 struct intel_th *th = container_of(work, struct intel_th, 548 request_module_work); 549 550 request_module("intel_th_%s", th->hub->name); 551 } 552 553 static int intel_th_request_hub_module(struct intel_th *th) 554 { 555 INIT_WORK(&th->request_module_work, __intel_th_request_hub_module); 556 schedule_work(&th->request_module_work); 557 558 return 0; 559 } 560 561 static void intel_th_request_hub_module_flush(struct intel_th *th) 562 { 563 flush_work(&th->request_module_work); 564 } 565 #else 566 static inline int intel_th_request_hub_module(struct intel_th *th) 567 { 568 return -EINVAL; 569 } 570 571 static inline void intel_th_request_hub_module_flush(struct intel_th *th) 572 { 573 } 574 #endif /* CONFIG_MODULES */ 575 576 static struct intel_th_device * 577 intel_th_subdevice_alloc(struct intel_th *th, 578 const struct intel_th_subdevice *subdev) 579 { 580 struct intel_th_device *thdev; 581 struct resource res[3]; 582 unsigned int req = 0; 583 int r, err; 584 585 thdev = intel_th_device_alloc(th, subdev->type, subdev->name, 586 subdev->id); 587 if (!thdev) 588 return ERR_PTR(-ENOMEM); 589 590 thdev->drvdata = th->drvdata; 591 592 memcpy(res, subdev->res, 593 sizeof(struct resource) * subdev->nres); 594 595 for (r = 0; r < subdev->nres; r++) { 596 struct resource *devres = th->resource; 597 int bar = TH_MMIO_CONFIG; 598 599 /* 600 * Take .end == 0 to mean 'take the whole bar', 601 * .start then tells us which bar it is. Default to 602 * TH_MMIO_CONFIG. 603 */ 604 if (!res[r].end && res[r].flags == IORESOURCE_MEM) { 605 bar = res[r].start; 606 res[r].start = 0; 607 res[r].end = resource_size(&devres[bar]) - 1; 608 } 609 610 if (res[r].flags & IORESOURCE_MEM) { 611 res[r].start += devres[bar].start; 612 res[r].end += devres[bar].start; 613 614 dev_dbg(th->dev, "%s:%d @ %pR\n", 615 subdev->name, r, &res[r]); 616 } else if (res[r].flags & IORESOURCE_IRQ) { 617 res[r].start = th->irq; 618 } 619 } 620 621 err = intel_th_device_add_resources(thdev, res, subdev->nres); 622 if (err) { 623 put_device(&thdev->dev); 624 goto fail_put_device; 625 } 626 627 if (subdev->type == INTEL_TH_OUTPUT) { 628 thdev->dev.devt = MKDEV(th->major, th->num_thdevs); 629 thdev->output.type = subdev->otype; 630 thdev->output.port = -1; 631 thdev->output.scratchpad = subdev->scrpd; 632 } else if (subdev->type == INTEL_TH_SWITCH) { 633 thdev->host_mode = 634 INTEL_TH_CAP(th, host_mode_only) ? true : host_mode; 635 th->hub = thdev; 636 } 637 638 err = device_add(&thdev->dev); 639 if (err) { 640 put_device(&thdev->dev); 641 goto fail_free_res; 642 } 643 644 /* need switch driver to be loaded to enumerate the rest */ 645 if (subdev->type == INTEL_TH_SWITCH && !req) { 646 err = intel_th_request_hub_module(th); 647 if (!err) 648 req++; 649 } 650 651 return thdev; 652 653 fail_free_res: 654 kfree(thdev->resource); 655 656 fail_put_device: 657 put_device(&thdev->dev); 658 659 return ERR_PTR(err); 660 } 661 662 /** 663 * intel_th_output_enable() - find and enable a device for a given output type 664 * @th: Intel TH instance 665 * @otype: output type 666 * 667 * Go through the unallocated output devices, find the first one whos type 668 * matches @otype and instantiate it. These devices are removed when the hub 669 * device is removed, see intel_th_remove(). 670 */ 671 int intel_th_output_enable(struct intel_th *th, unsigned int otype) 672 { 673 struct intel_th_device *thdev; 674 int src = 0, dst = 0; 675 676 for (src = 0, dst = 0; dst <= th->num_thdevs; src++, dst++) { 677 for (; src < ARRAY_SIZE(intel_th_subdevices); src++) { 678 if (intel_th_subdevices[src].type != INTEL_TH_OUTPUT) 679 continue; 680 681 if (intel_th_subdevices[src].otype != otype) 682 continue; 683 684 break; 685 } 686 687 /* no unallocated matching subdevices */ 688 if (src == ARRAY_SIZE(intel_th_subdevices)) 689 return -ENODEV; 690 691 for (; dst < th->num_thdevs; dst++) { 692 if (th->thdev[dst]->type != INTEL_TH_OUTPUT) 693 continue; 694 695 if (th->thdev[dst]->output.type != otype) 696 continue; 697 698 break; 699 } 700 701 /* 702 * intel_th_subdevices[src] matches our requirements and is 703 * not matched in th::thdev[] 704 */ 705 if (dst == th->num_thdevs) 706 goto found; 707 } 708 709 return -ENODEV; 710 711 found: 712 thdev = intel_th_subdevice_alloc(th, &intel_th_subdevices[src]); 713 if (IS_ERR(thdev)) 714 return PTR_ERR(thdev); 715 716 th->thdev[th->num_thdevs++] = thdev; 717 718 return 0; 719 } 720 EXPORT_SYMBOL_GPL(intel_th_output_enable); 721 722 static int intel_th_populate(struct intel_th *th) 723 { 724 int src; 725 726 /* create devices for each intel_th_subdevice */ 727 for (src = 0; src < ARRAY_SIZE(intel_th_subdevices); src++) { 728 const struct intel_th_subdevice *subdev = 729 &intel_th_subdevices[src]; 730 struct intel_th_device *thdev; 731 732 /* only allow SOURCE and SWITCH devices in host mode */ 733 if ((INTEL_TH_CAP(th, host_mode_only) || host_mode) && 734 subdev->type == INTEL_TH_OUTPUT) 735 continue; 736 737 /* 738 * don't enable port OUTPUTs in this path; SWITCH enables them 739 * via intel_th_output_enable() 740 */ 741 if (subdev->type == INTEL_TH_OUTPUT && 742 subdev->otype != GTH_NONE) 743 continue; 744 745 thdev = intel_th_subdevice_alloc(th, subdev); 746 /* note: caller should free subdevices from th::thdev[] */ 747 if (IS_ERR(thdev)) 748 return PTR_ERR(thdev); 749 750 th->thdev[th->num_thdevs++] = thdev; 751 } 752 753 return 0; 754 } 755 756 static int match_devt(struct device *dev, void *data) 757 { 758 dev_t devt = (dev_t)(unsigned long)data; 759 760 return dev->devt == devt; 761 } 762 763 static int intel_th_output_open(struct inode *inode, struct file *file) 764 { 765 const struct file_operations *fops; 766 struct intel_th_driver *thdrv; 767 struct device *dev; 768 int err; 769 770 dev = bus_find_device(&intel_th_bus, NULL, 771 (void *)(unsigned long)inode->i_rdev, 772 match_devt); 773 if (!dev || !dev->driver) 774 return -ENODEV; 775 776 thdrv = to_intel_th_driver(dev->driver); 777 fops = fops_get(thdrv->fops); 778 if (!fops) 779 return -ENODEV; 780 781 replace_fops(file, fops); 782 783 file->private_data = to_intel_th_device(dev); 784 785 if (file->f_op->open) { 786 err = file->f_op->open(inode, file); 787 return err; 788 } 789 790 return 0; 791 } 792 793 static const struct file_operations intel_th_output_fops = { 794 .open = intel_th_output_open, 795 .llseek = noop_llseek, 796 }; 797 798 /** 799 * intel_th_alloc() - allocate a new Intel TH device and its subdevices 800 * @dev: parent device 801 * @devres: parent's resources 802 * @ndevres: number of resources 803 * @irq: irq number 804 */ 805 struct intel_th * 806 intel_th_alloc(struct device *dev, struct intel_th_drvdata *drvdata, 807 struct resource *devres, unsigned int ndevres, int irq) 808 { 809 struct intel_th *th; 810 int err, r; 811 812 if (irq == -1) 813 for (r = 0; r < ndevres; r++) 814 if (devres[r].flags & IORESOURCE_IRQ) { 815 irq = devres[r].start; 816 break; 817 } 818 819 th = kzalloc(sizeof(*th), GFP_KERNEL); 820 if (!th) 821 return ERR_PTR(-ENOMEM); 822 823 th->id = ida_simple_get(&intel_th_ida, 0, 0, GFP_KERNEL); 824 if (th->id < 0) { 825 err = th->id; 826 goto err_alloc; 827 } 828 829 th->major = __register_chrdev(0, 0, TH_POSSIBLE_OUTPUTS, 830 "intel_th/output", &intel_th_output_fops); 831 if (th->major < 0) { 832 err = th->major; 833 goto err_ida; 834 } 835 th->dev = dev; 836 th->drvdata = drvdata; 837 838 th->resource = devres; 839 th->num_resources = ndevres; 840 th->irq = irq; 841 842 dev_set_drvdata(dev, th); 843 844 pm_runtime_no_callbacks(dev); 845 pm_runtime_put(dev); 846 pm_runtime_allow(dev); 847 848 err = intel_th_populate(th); 849 if (err) { 850 /* free the subdevices and undo everything */ 851 intel_th_free(th); 852 return ERR_PTR(err); 853 } 854 855 return th; 856 857 err_ida: 858 ida_simple_remove(&intel_th_ida, th->id); 859 860 err_alloc: 861 kfree(th); 862 863 return ERR_PTR(err); 864 } 865 EXPORT_SYMBOL_GPL(intel_th_alloc); 866 867 void intel_th_free(struct intel_th *th) 868 { 869 int i; 870 871 intel_th_request_hub_module_flush(th); 872 873 intel_th_device_remove(th->hub); 874 for (i = 0; i < th->num_thdevs; i++) { 875 if (th->thdev[i] != th->hub) 876 intel_th_device_remove(th->thdev[i]); 877 th->thdev[i] = NULL; 878 } 879 880 th->num_thdevs = 0; 881 882 pm_runtime_get_sync(th->dev); 883 pm_runtime_forbid(th->dev); 884 885 __unregister_chrdev(th->major, 0, TH_POSSIBLE_OUTPUTS, 886 "intel_th/output"); 887 888 ida_simple_remove(&intel_th_ida, th->id); 889 890 kfree(th); 891 } 892 EXPORT_SYMBOL_GPL(intel_th_free); 893 894 /** 895 * intel_th_trace_enable() - enable tracing for an output device 896 * @thdev: output device that requests tracing be enabled 897 */ 898 int intel_th_trace_enable(struct intel_th_device *thdev) 899 { 900 struct intel_th_device *hub = to_intel_th_device(thdev->dev.parent); 901 struct intel_th_driver *hubdrv = to_intel_th_driver(hub->dev.driver); 902 903 if (WARN_ON_ONCE(hub->type != INTEL_TH_SWITCH)) 904 return -EINVAL; 905 906 if (WARN_ON_ONCE(thdev->type != INTEL_TH_OUTPUT)) 907 return -EINVAL; 908 909 pm_runtime_get_sync(&thdev->dev); 910 hubdrv->enable(hub, &thdev->output); 911 912 return 0; 913 } 914 EXPORT_SYMBOL_GPL(intel_th_trace_enable); 915 916 /** 917 * intel_th_trace_disable() - disable tracing for an output device 918 * @thdev: output device that requests tracing be disabled 919 */ 920 int intel_th_trace_disable(struct intel_th_device *thdev) 921 { 922 struct intel_th_device *hub = to_intel_th_device(thdev->dev.parent); 923 struct intel_th_driver *hubdrv = to_intel_th_driver(hub->dev.driver); 924 925 WARN_ON_ONCE(hub->type != INTEL_TH_SWITCH); 926 if (WARN_ON_ONCE(thdev->type != INTEL_TH_OUTPUT)) 927 return -EINVAL; 928 929 hubdrv->disable(hub, &thdev->output); 930 pm_runtime_put(&thdev->dev); 931 932 return 0; 933 } 934 EXPORT_SYMBOL_GPL(intel_th_trace_disable); 935 936 int intel_th_set_output(struct intel_th_device *thdev, 937 unsigned int master) 938 { 939 struct intel_th_device *hub = to_intel_th_hub(thdev); 940 struct intel_th_driver *hubdrv = to_intel_th_driver(hub->dev.driver); 941 942 /* In host mode, this is up to the external debugger, do nothing. */ 943 if (hub->host_mode) 944 return 0; 945 946 if (!hubdrv->set_output) 947 return -ENOTSUPP; 948 949 return hubdrv->set_output(hub, master); 950 } 951 EXPORT_SYMBOL_GPL(intel_th_set_output); 952 953 static int __init intel_th_init(void) 954 { 955 intel_th_debug_init(); 956 957 return bus_register(&intel_th_bus); 958 } 959 subsys_initcall(intel_th_init); 960 961 static void __exit intel_th_exit(void) 962 { 963 intel_th_debug_done(); 964 965 bus_unregister(&intel_th_bus); 966 } 967 module_exit(intel_th_exit); 968 969 MODULE_LICENSE("GPL v2"); 970 MODULE_DESCRIPTION("Intel(R) Trace Hub controller driver"); 971 MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@linux.intel.com>"); 972