1 /* 2 * Intel(R) Trace Hub Global Trace Hub 3 * 4 * Copyright (C) 2014-2015 Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 */ 15 16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 17 18 #include <linux/types.h> 19 #include <linux/module.h> 20 #include <linux/device.h> 21 #include <linux/io.h> 22 #include <linux/mm.h> 23 #include <linux/slab.h> 24 #include <linux/bitmap.h> 25 #include <linux/pm_runtime.h> 26 27 #include "intel_th.h" 28 #include "gth.h" 29 30 struct gth_device; 31 32 /** 33 * struct gth_output - GTH view on an output port 34 * @gth: backlink to the GTH device 35 * @output: link to output device's output descriptor 36 * @index: output port number 37 * @port_type: one of GTH_* port type values 38 * @master: bitmap of masters configured for this output 39 */ 40 struct gth_output { 41 struct gth_device *gth; 42 struct intel_th_output *output; 43 unsigned int index; 44 unsigned int port_type; 45 DECLARE_BITMAP(master, TH_CONFIGURABLE_MASTERS + 1); 46 }; 47 48 /** 49 * struct gth_device - GTH device 50 * @dev: driver core's device 51 * @base: register window base address 52 * @output_group: attributes describing output ports 53 * @master_group: attributes describing master assignments 54 * @output: output ports 55 * @master: master/output port assignments 56 * @gth_lock: serializes accesses to GTH bits 57 */ 58 struct gth_device { 59 struct device *dev; 60 void __iomem *base; 61 62 struct attribute_group output_group; 63 struct attribute_group master_group; 64 struct gth_output output[TH_POSSIBLE_OUTPUTS]; 65 signed char master[TH_CONFIGURABLE_MASTERS + 1]; 66 spinlock_t gth_lock; 67 }; 68 69 static void gth_output_set(struct gth_device *gth, int port, 70 unsigned int config) 71 { 72 unsigned long reg = port & 4 ? REG_GTH_GTHOPT1 : REG_GTH_GTHOPT0; 73 u32 val; 74 int shift = (port & 3) * 8; 75 76 val = ioread32(gth->base + reg); 77 val &= ~(0xff << shift); 78 val |= config << shift; 79 iowrite32(val, gth->base + reg); 80 } 81 82 static unsigned int gth_output_get(struct gth_device *gth, int port) 83 { 84 unsigned long reg = port & 4 ? REG_GTH_GTHOPT1 : REG_GTH_GTHOPT0; 85 u32 val; 86 int shift = (port & 3) * 8; 87 88 val = ioread32(gth->base + reg); 89 val &= 0xff << shift; 90 val >>= shift; 91 92 return val; 93 } 94 95 static void gth_smcfreq_set(struct gth_device *gth, int port, 96 unsigned int freq) 97 { 98 unsigned long reg = REG_GTH_SMCR0 + ((port / 2) * 4); 99 int shift = (port & 1) * 16; 100 u32 val; 101 102 val = ioread32(gth->base + reg); 103 val &= ~(0xffff << shift); 104 val |= freq << shift; 105 iowrite32(val, gth->base + reg); 106 } 107 108 static unsigned int gth_smcfreq_get(struct gth_device *gth, int port) 109 { 110 unsigned long reg = REG_GTH_SMCR0 + ((port / 2) * 4); 111 int shift = (port & 1) * 16; 112 u32 val; 113 114 val = ioread32(gth->base + reg); 115 val &= 0xffff << shift; 116 val >>= shift; 117 118 return val; 119 } 120 121 /* 122 * "masters" attribute group 123 */ 124 125 struct master_attribute { 126 struct device_attribute attr; 127 struct gth_device *gth; 128 unsigned int master; 129 }; 130 131 static void 132 gth_master_set(struct gth_device *gth, unsigned int master, int port) 133 { 134 unsigned int reg = REG_GTH_SWDEST0 + ((master >> 1) & ~3u); 135 unsigned int shift = (master & 0x7) * 4; 136 u32 val; 137 138 if (master >= 256) { 139 reg = REG_GTH_GSWTDEST; 140 shift = 0; 141 } 142 143 val = ioread32(gth->base + reg); 144 val &= ~(0xf << shift); 145 if (port >= 0) 146 val |= (0x8 | port) << shift; 147 iowrite32(val, gth->base + reg); 148 } 149 150 static ssize_t master_attr_show(struct device *dev, 151 struct device_attribute *attr, 152 char *buf) 153 { 154 struct master_attribute *ma = 155 container_of(attr, struct master_attribute, attr); 156 struct gth_device *gth = ma->gth; 157 size_t count; 158 int port; 159 160 spin_lock(>h->gth_lock); 161 port = gth->master[ma->master]; 162 spin_unlock(>h->gth_lock); 163 164 if (port >= 0) 165 count = snprintf(buf, PAGE_SIZE, "%x\n", port); 166 else 167 count = snprintf(buf, PAGE_SIZE, "disabled\n"); 168 169 return count; 170 } 171 172 static ssize_t master_attr_store(struct device *dev, 173 struct device_attribute *attr, 174 const char *buf, size_t count) 175 { 176 struct master_attribute *ma = 177 container_of(attr, struct master_attribute, attr); 178 struct gth_device *gth = ma->gth; 179 int old_port, port; 180 181 if (kstrtoint(buf, 10, &port) < 0) 182 return -EINVAL; 183 184 if (port >= TH_POSSIBLE_OUTPUTS || port < -1) 185 return -EINVAL; 186 187 spin_lock(>h->gth_lock); 188 189 /* disconnect from the previous output port, if any */ 190 old_port = gth->master[ma->master]; 191 if (old_port >= 0) { 192 gth->master[ma->master] = -1; 193 clear_bit(ma->master, gth->output[old_port].master); 194 195 /* 196 * if the port is active, program this setting, 197 * implies that runtime PM is on 198 */ 199 if (gth->output[old_port].output->active) 200 gth_master_set(gth, ma->master, -1); 201 } 202 203 /* connect to the new output port, if any */ 204 if (port >= 0) { 205 /* check if there's a driver for this port */ 206 if (!gth->output[port].output) { 207 count = -ENODEV; 208 goto unlock; 209 } 210 211 set_bit(ma->master, gth->output[port].master); 212 213 /* if the port is active, program this setting, see above */ 214 if (gth->output[port].output->active) 215 gth_master_set(gth, ma->master, port); 216 } 217 218 gth->master[ma->master] = port; 219 220 unlock: 221 spin_unlock(>h->gth_lock); 222 223 return count; 224 } 225 226 struct output_attribute { 227 struct device_attribute attr; 228 struct gth_device *gth; 229 unsigned int port; 230 unsigned int parm; 231 }; 232 233 #define OUTPUT_PARM(_name, _mask, _r, _w, _what) \ 234 [TH_OUTPUT_PARM(_name)] = { .name = __stringify(_name), \ 235 .get = gth_ ## _what ## _get, \ 236 .set = gth_ ## _what ## _set, \ 237 .mask = (_mask), \ 238 .readable = (_r), \ 239 .writable = (_w) } 240 241 static const struct output_parm { 242 const char *name; 243 unsigned int (*get)(struct gth_device *gth, int port); 244 void (*set)(struct gth_device *gth, int port, 245 unsigned int val); 246 unsigned int mask; 247 unsigned int readable : 1, 248 writable : 1; 249 } output_parms[] = { 250 OUTPUT_PARM(port, 0x7, 1, 0, output), 251 OUTPUT_PARM(null, BIT(3), 1, 1, output), 252 OUTPUT_PARM(drop, BIT(4), 1, 1, output), 253 OUTPUT_PARM(reset, BIT(5), 1, 0, output), 254 OUTPUT_PARM(flush, BIT(7), 0, 1, output), 255 OUTPUT_PARM(smcfreq, 0xffff, 1, 1, smcfreq), 256 }; 257 258 static void 259 gth_output_parm_set(struct gth_device *gth, int port, unsigned int parm, 260 unsigned int val) 261 { 262 unsigned int config = output_parms[parm].get(gth, port); 263 unsigned int mask = output_parms[parm].mask; 264 unsigned int shift = __ffs(mask); 265 266 config &= ~mask; 267 config |= (val << shift) & mask; 268 output_parms[parm].set(gth, port, config); 269 } 270 271 static unsigned int 272 gth_output_parm_get(struct gth_device *gth, int port, unsigned int parm) 273 { 274 unsigned int config = output_parms[parm].get(gth, port); 275 unsigned int mask = output_parms[parm].mask; 276 unsigned int shift = __ffs(mask); 277 278 config &= mask; 279 config >>= shift; 280 return config; 281 } 282 283 /* 284 * Reset outputs and sources 285 */ 286 static int intel_th_gth_reset(struct gth_device *gth) 287 { 288 u32 reg; 289 int port, i; 290 291 reg = ioread32(gth->base + REG_GTH_SCRPD0); 292 if (reg & SCRPD_DEBUGGER_IN_USE) 293 return -EBUSY; 294 295 /* Always save/restore STH and TU registers in S0ix entry/exit */ 296 reg |= SCRPD_STH_IS_ENABLED | SCRPD_TRIGGER_IS_ENABLED; 297 iowrite32(reg, gth->base + REG_GTH_SCRPD0); 298 299 /* output ports */ 300 for (port = 0; port < 8; port++) { 301 if (gth_output_parm_get(gth, port, TH_OUTPUT_PARM(port)) == 302 GTH_NONE) 303 continue; 304 305 gth_output_set(gth, port, 0); 306 gth_smcfreq_set(gth, port, 16); 307 } 308 /* disable overrides */ 309 iowrite32(0, gth->base + REG_GTH_DESTOVR); 310 311 /* masters swdest_0~31 and gswdest */ 312 for (i = 0; i < 33; i++) 313 iowrite32(0, gth->base + REG_GTH_SWDEST0 + i * 4); 314 315 /* sources */ 316 iowrite32(0, gth->base + REG_GTH_SCR); 317 iowrite32(0xfc, gth->base + REG_GTH_SCR2); 318 319 return 0; 320 } 321 322 /* 323 * "outputs" attribute group 324 */ 325 326 static ssize_t output_attr_show(struct device *dev, 327 struct device_attribute *attr, 328 char *buf) 329 { 330 struct output_attribute *oa = 331 container_of(attr, struct output_attribute, attr); 332 struct gth_device *gth = oa->gth; 333 size_t count; 334 335 pm_runtime_get_sync(dev); 336 337 spin_lock(>h->gth_lock); 338 count = snprintf(buf, PAGE_SIZE, "%x\n", 339 gth_output_parm_get(gth, oa->port, oa->parm)); 340 spin_unlock(>h->gth_lock); 341 342 pm_runtime_put(dev); 343 344 return count; 345 } 346 347 static ssize_t output_attr_store(struct device *dev, 348 struct device_attribute *attr, 349 const char *buf, size_t count) 350 { 351 struct output_attribute *oa = 352 container_of(attr, struct output_attribute, attr); 353 struct gth_device *gth = oa->gth; 354 unsigned int config; 355 356 if (kstrtouint(buf, 16, &config) < 0) 357 return -EINVAL; 358 359 pm_runtime_get_sync(dev); 360 361 spin_lock(>h->gth_lock); 362 gth_output_parm_set(gth, oa->port, oa->parm, config); 363 spin_unlock(>h->gth_lock); 364 365 pm_runtime_put(dev); 366 367 return count; 368 } 369 370 static int intel_th_master_attributes(struct gth_device *gth) 371 { 372 struct master_attribute *master_attrs; 373 struct attribute **attrs; 374 int i, nattrs = TH_CONFIGURABLE_MASTERS + 2; 375 376 attrs = devm_kcalloc(gth->dev, nattrs, sizeof(void *), GFP_KERNEL); 377 if (!attrs) 378 return -ENOMEM; 379 380 master_attrs = devm_kcalloc(gth->dev, nattrs, 381 sizeof(struct master_attribute), 382 GFP_KERNEL); 383 if (!master_attrs) 384 return -ENOMEM; 385 386 for (i = 0; i < TH_CONFIGURABLE_MASTERS + 1; i++) { 387 char *name; 388 389 name = devm_kasprintf(gth->dev, GFP_KERNEL, "%d%s", i, 390 i == TH_CONFIGURABLE_MASTERS ? "+" : ""); 391 if (!name) 392 return -ENOMEM; 393 394 master_attrs[i].attr.attr.name = name; 395 master_attrs[i].attr.attr.mode = S_IRUGO | S_IWUSR; 396 master_attrs[i].attr.show = master_attr_show; 397 master_attrs[i].attr.store = master_attr_store; 398 399 sysfs_attr_init(&master_attrs[i].attr.attr); 400 attrs[i] = &master_attrs[i].attr.attr; 401 402 master_attrs[i].gth = gth; 403 master_attrs[i].master = i; 404 } 405 406 gth->master_group.name = "masters"; 407 gth->master_group.attrs = attrs; 408 409 return sysfs_create_group(>h->dev->kobj, >h->master_group); 410 } 411 412 static int intel_th_output_attributes(struct gth_device *gth) 413 { 414 struct output_attribute *out_attrs; 415 struct attribute **attrs; 416 int i, j, nouts = TH_POSSIBLE_OUTPUTS; 417 int nparms = ARRAY_SIZE(output_parms); 418 int nattrs = nouts * nparms + 1; 419 420 attrs = devm_kcalloc(gth->dev, nattrs, sizeof(void *), GFP_KERNEL); 421 if (!attrs) 422 return -ENOMEM; 423 424 out_attrs = devm_kcalloc(gth->dev, nattrs, 425 sizeof(struct output_attribute), 426 GFP_KERNEL); 427 if (!out_attrs) 428 return -ENOMEM; 429 430 for (i = 0; i < nouts; i++) { 431 for (j = 0; j < nparms; j++) { 432 unsigned int idx = i * nparms + j; 433 char *name; 434 435 name = devm_kasprintf(gth->dev, GFP_KERNEL, "%d_%s", i, 436 output_parms[j].name); 437 if (!name) 438 return -ENOMEM; 439 440 out_attrs[idx].attr.attr.name = name; 441 442 if (output_parms[j].readable) { 443 out_attrs[idx].attr.attr.mode |= S_IRUGO; 444 out_attrs[idx].attr.show = output_attr_show; 445 } 446 447 if (output_parms[j].writable) { 448 out_attrs[idx].attr.attr.mode |= S_IWUSR; 449 out_attrs[idx].attr.store = output_attr_store; 450 } 451 452 sysfs_attr_init(&out_attrs[idx].attr.attr); 453 attrs[idx] = &out_attrs[idx].attr.attr; 454 455 out_attrs[idx].gth = gth; 456 out_attrs[idx].port = i; 457 out_attrs[idx].parm = j; 458 } 459 } 460 461 gth->output_group.name = "outputs"; 462 gth->output_group.attrs = attrs; 463 464 return sysfs_create_group(>h->dev->kobj, >h->output_group); 465 } 466 467 /** 468 * intel_th_gth_disable() - disable tracing to an output device 469 * @thdev: GTH device 470 * @output: output device's descriptor 471 * 472 * This will deconfigure all masters set to output to this device, 473 * disable tracing using force storeEn off signal and wait for the 474 * "pipeline empty" bit for corresponding output port. 475 */ 476 static void intel_th_gth_disable(struct intel_th_device *thdev, 477 struct intel_th_output *output) 478 { 479 struct gth_device *gth = dev_get_drvdata(&thdev->dev); 480 unsigned long count; 481 int master; 482 u32 reg; 483 484 spin_lock(>h->gth_lock); 485 output->active = false; 486 487 for_each_set_bit(master, gth->output[output->port].master, 488 TH_CONFIGURABLE_MASTERS) { 489 gth_master_set(gth, master, -1); 490 } 491 spin_unlock(>h->gth_lock); 492 493 iowrite32(0, gth->base + REG_GTH_SCR); 494 iowrite32(0xfd, gth->base + REG_GTH_SCR2); 495 496 /* wait on pipeline empty for the given port */ 497 for (reg = 0, count = GTH_PLE_WAITLOOP_DEPTH; 498 count && !(reg & BIT(output->port)); count--) { 499 reg = ioread32(gth->base + REG_GTH_STAT); 500 cpu_relax(); 501 } 502 503 /* clear force capture done for next captures */ 504 iowrite32(0xfc, gth->base + REG_GTH_SCR2); 505 506 if (!count) 507 dev_dbg(&thdev->dev, "timeout waiting for GTH[%d] PLE\n", 508 output->port); 509 510 reg = ioread32(gth->base + REG_GTH_SCRPD0); 511 reg &= ~output->scratchpad; 512 iowrite32(reg, gth->base + REG_GTH_SCRPD0); 513 } 514 515 static void gth_tscu_resync(struct gth_device *gth) 516 { 517 u32 reg; 518 519 reg = ioread32(gth->base + REG_TSCU_TSUCTRL); 520 reg &= ~TSUCTRL_CTCRESYNC; 521 iowrite32(reg, gth->base + REG_TSCU_TSUCTRL); 522 } 523 524 /** 525 * intel_th_gth_enable() - enable tracing to an output device 526 * @thdev: GTH device 527 * @output: output device's descriptor 528 * 529 * This will configure all masters set to output to this device and 530 * enable tracing using force storeEn signal. 531 */ 532 static void intel_th_gth_enable(struct intel_th_device *thdev, 533 struct intel_th_output *output) 534 { 535 struct gth_device *gth = dev_get_drvdata(&thdev->dev); 536 struct intel_th *th = to_intel_th(thdev); 537 u32 scr = 0xfc0000, scrpd; 538 int master; 539 540 spin_lock(>h->gth_lock); 541 for_each_set_bit(master, gth->output[output->port].master, 542 TH_CONFIGURABLE_MASTERS + 1) { 543 gth_master_set(gth, master, output->port); 544 } 545 546 if (output->multiblock) 547 scr |= 0xff; 548 549 output->active = true; 550 spin_unlock(>h->gth_lock); 551 552 if (INTEL_TH_CAP(th, tscu_enable)) 553 gth_tscu_resync(gth); 554 555 scrpd = ioread32(gth->base + REG_GTH_SCRPD0); 556 scrpd |= output->scratchpad; 557 iowrite32(scrpd, gth->base + REG_GTH_SCRPD0); 558 559 iowrite32(scr, gth->base + REG_GTH_SCR); 560 iowrite32(0, gth->base + REG_GTH_SCR2); 561 } 562 563 /** 564 * intel_th_gth_assign() - assign output device to a GTH output port 565 * @thdev: GTH device 566 * @othdev: output device 567 * 568 * This will match a given output device parameters against present 569 * output ports on the GTH and fill out relevant bits in output device's 570 * descriptor. 571 * 572 * Return: 0 on success, -errno on error. 573 */ 574 static int intel_th_gth_assign(struct intel_th_device *thdev, 575 struct intel_th_device *othdev) 576 { 577 struct gth_device *gth = dev_get_drvdata(&thdev->dev); 578 int i, id; 579 580 if (thdev->host_mode) 581 return -EBUSY; 582 583 if (othdev->type != INTEL_TH_OUTPUT) 584 return -EINVAL; 585 586 for (i = 0, id = 0; i < TH_POSSIBLE_OUTPUTS; i++) { 587 if (gth->output[i].port_type != othdev->output.type) 588 continue; 589 590 if (othdev->id == -1 || othdev->id == id) 591 goto found; 592 593 id++; 594 } 595 596 return -ENOENT; 597 598 found: 599 spin_lock(>h->gth_lock); 600 othdev->output.port = i; 601 othdev->output.active = false; 602 gth->output[i].output = &othdev->output; 603 spin_unlock(>h->gth_lock); 604 605 return 0; 606 } 607 608 /** 609 * intel_th_gth_unassign() - deassociate an output device from its output port 610 * @thdev: GTH device 611 * @othdev: output device 612 */ 613 static void intel_th_gth_unassign(struct intel_th_device *thdev, 614 struct intel_th_device *othdev) 615 { 616 struct gth_device *gth = dev_get_drvdata(&thdev->dev); 617 int port = othdev->output.port; 618 619 if (thdev->host_mode) 620 return; 621 622 spin_lock(>h->gth_lock); 623 othdev->output.port = -1; 624 othdev->output.active = false; 625 gth->output[port].output = NULL; 626 spin_unlock(>h->gth_lock); 627 } 628 629 static int 630 intel_th_gth_set_output(struct intel_th_device *thdev, unsigned int master) 631 { 632 struct gth_device *gth = dev_get_drvdata(&thdev->dev); 633 int port = 0; /* FIXME: make default output configurable */ 634 635 /* 636 * everything above TH_CONFIGURABLE_MASTERS is controlled by the 637 * same register 638 */ 639 if (master > TH_CONFIGURABLE_MASTERS) 640 master = TH_CONFIGURABLE_MASTERS; 641 642 spin_lock(>h->gth_lock); 643 if (gth->master[master] == -1) { 644 set_bit(master, gth->output[port].master); 645 gth->master[master] = port; 646 } 647 spin_unlock(>h->gth_lock); 648 649 return 0; 650 } 651 652 static int intel_th_gth_probe(struct intel_th_device *thdev) 653 { 654 struct device *dev = &thdev->dev; 655 struct intel_th *th = dev_get_drvdata(dev->parent); 656 struct gth_device *gth; 657 struct resource *res; 658 void __iomem *base; 659 int i, ret; 660 661 res = intel_th_device_get_resource(thdev, IORESOURCE_MEM, 0); 662 if (!res) 663 return -ENODEV; 664 665 base = devm_ioremap(dev, res->start, resource_size(res)); 666 if (!base) 667 return -ENOMEM; 668 669 gth = devm_kzalloc(dev, sizeof(*gth), GFP_KERNEL); 670 if (!gth) 671 return -ENOMEM; 672 673 gth->dev = dev; 674 gth->base = base; 675 spin_lock_init(>h->gth_lock); 676 677 dev_set_drvdata(dev, gth); 678 679 /* 680 * Host mode can be signalled via SW means or via SCRPD_DEBUGGER_IN_USE 681 * bit. Either way, don't reset HW in this case, and don't export any 682 * capture configuration attributes. Also, refuse to assign output 683 * drivers to ports, see intel_th_gth_assign(). 684 */ 685 if (thdev->host_mode) 686 return 0; 687 688 ret = intel_th_gth_reset(gth); 689 if (ret) { 690 if (ret != -EBUSY) 691 return ret; 692 693 thdev->host_mode = true; 694 695 return 0; 696 } 697 698 for (i = 0; i < TH_CONFIGURABLE_MASTERS + 1; i++) 699 gth->master[i] = -1; 700 701 for (i = 0; i < TH_POSSIBLE_OUTPUTS; i++) { 702 gth->output[i].gth = gth; 703 gth->output[i].index = i; 704 gth->output[i].port_type = 705 gth_output_parm_get(gth, i, TH_OUTPUT_PARM(port)); 706 if (gth->output[i].port_type == GTH_NONE) 707 continue; 708 709 ret = intel_th_output_enable(th, gth->output[i].port_type); 710 /* -ENODEV is ok, we just won't have that device enumerated */ 711 if (ret && ret != -ENODEV) 712 return ret; 713 } 714 715 if (intel_th_output_attributes(gth) || 716 intel_th_master_attributes(gth)) { 717 pr_warn("Can't initialize sysfs attributes\n"); 718 719 if (gth->output_group.attrs) 720 sysfs_remove_group(>h->dev->kobj, >h->output_group); 721 return -ENOMEM; 722 } 723 724 return 0; 725 } 726 727 static void intel_th_gth_remove(struct intel_th_device *thdev) 728 { 729 struct gth_device *gth = dev_get_drvdata(&thdev->dev); 730 731 sysfs_remove_group(>h->dev->kobj, >h->output_group); 732 sysfs_remove_group(>h->dev->kobj, >h->master_group); 733 } 734 735 static struct intel_th_driver intel_th_gth_driver = { 736 .probe = intel_th_gth_probe, 737 .remove = intel_th_gth_remove, 738 .assign = intel_th_gth_assign, 739 .unassign = intel_th_gth_unassign, 740 .set_output = intel_th_gth_set_output, 741 .enable = intel_th_gth_enable, 742 .disable = intel_th_gth_disable, 743 .driver = { 744 .name = "gth", 745 .owner = THIS_MODULE, 746 }, 747 }; 748 749 module_driver(intel_th_gth_driver, 750 intel_th_driver_register, 751 intel_th_driver_unregister); 752 753 MODULE_ALIAS("intel_th_switch"); 754 MODULE_LICENSE("GPL v2"); 755 MODULE_DESCRIPTION("Intel(R) Trace Hub Global Trace Hub driver"); 756 MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@linux.intel.com>"); 757