[SPARC64]: of_device layer IRQ resolution

Do IRQ determination generically by parsing the PROM properties,
and using IRQ controller drivers for final resolution.

One immediate positive effect is that all of the IRQ frobbing
in the EBUS, ISA, and PCI controller layers has been eliminated.
We just look up the of_device and use the properly computed
value.

The PCI controller irq_build() routines are gone and no longer
used. Unfortunately sbus_build_irq() has to remain as there is
a direct reference to this in the sunzilog driver. That can be
killed off once the sparc32 side of this is written and the
sunzilog driver is transformed into an "of" bus driver.

Signed-off-by: David S. Miller <davem@davemloft.net>

authored by David S. Miller and committed by David S. Miller 2b1e5978 c3a8b85f

+1104 -1049
+32 -116
arch/sparc64/kernel/ebus.c
··· 20 20 #include <asm/pbm.h> 21 21 #include <asm/ebus.h> 22 22 #include <asm/oplib.h> 23 + #include <asm/prom.h> 24 + #include <asm/of_device.h> 23 25 #include <asm/bpp.h> 24 26 #include <asm/irq.h> 25 27 ··· 281 279 return mem; 282 280 } 283 281 284 - int __init ebus_intmap_match(struct linux_ebus *ebus, 285 - struct linux_prom_registers *reg, 286 - int *interrupt) 282 + static void __init fill_ebus_child(struct device_node *dp, 283 + struct linux_ebus_child *dev, 284 + int non_standard_regs) 287 285 { 288 - struct linux_prom_ebus_intmap *imap; 289 - struct linux_prom_ebus_intmask *imask; 290 - unsigned int hi, lo, irq; 291 - int i, len, n_imap; 292 - 293 - imap = of_get_property(ebus->prom_node, "interrupt-map", &len); 294 - if (!imap) 295 - return 0; 296 - n_imap = len / sizeof(imap[0]); 297 - 298 - imask = of_get_property(ebus->prom_node, "interrupt-map-mask", NULL); 299 - if (!imask) 300 - return 0; 301 - 302 - hi = reg->which_io & imask->phys_hi; 303 - lo = reg->phys_addr & imask->phys_lo; 304 - irq = *interrupt & imask->interrupt; 305 - for (i = 0; i < n_imap; i++) { 306 - if ((imap[i].phys_hi == hi) && 307 - (imap[i].phys_lo == lo) && 308 - (imap[i].interrupt == irq)) { 309 - *interrupt = imap[i].cinterrupt; 310 - return 0; 311 - } 312 - } 313 - return -1; 314 - } 315 - 316 - void __init fill_ebus_child(struct device_node *dp, 317 - struct linux_prom_registers *preg, 318 - struct linux_ebus_child *dev, 319 - int non_standard_regs) 320 - { 286 + struct of_device *op; 321 287 int *regs; 322 - int *irqs; 323 288 int i, len; 324 289 325 290 dev->prom_node = dp; ··· 323 354 } 324 355 } 325 356 326 - for (i = 0; i < PROMINTR_MAX; i++) 327 - dev->irqs[i] = PCI_IRQ_NONE; 328 - 329 - irqs = of_get_property(dp, "interrupts", &len); 330 - if (!irqs) { 357 + op = of_find_device_by_node(dp); 358 + if (!op) { 331 359 dev->num_irqs = 0; 360 + } else { 361 + dev->num_irqs = op->num_irqs; 362 + for (i = 0; i < dev->num_irqs; i++) 363 + dev->irqs[i] = op->irqs[i]; 364 + } 365 + 366 + if (!dev->num_irqs) { 332 367 /* 333 368 * Oh, well, some PROMs don't export interrupts 334 369 * property to children of EBus devices... ··· 348 375 dev->irqs[0] = dev->parent->irqs[1]; 349 376 } 350 377 } 351 - } else { 352 - dev->num_irqs = len / sizeof(irqs[0]); 353 - for (i = 0; i < dev->num_irqs; i++) { 354 - struct pci_pbm_info *pbm = dev->bus->parent; 355 - struct pci_controller_info *p = pbm->parent; 356 - 357 - if (ebus_intmap_match(dev->bus, preg, &irqs[i]) != -1) { 358 - dev->irqs[i] = p->irq_build(pbm, 359 - dev->bus->self, 360 - irqs[i]); 361 - } else { 362 - /* If we get a bogus interrupt property, just 363 - * record the raw value instead of punting. 364 - */ 365 - dev->irqs[i] = irqs[i]; 366 - } 367 - } 368 378 } 369 379 } 370 380 ··· 359 403 return 0; 360 404 } 361 405 362 - void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev) 406 + static void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev) 363 407 { 364 - struct linux_prom_registers *regs; 365 408 struct linux_ebus_child *child; 366 - int *irqs; 367 - int i, n, len; 409 + struct of_device *op; 410 + int i, len; 368 411 369 412 dev->prom_node = dp; 370 413 371 414 printk(" [%s", dp->name); 372 415 373 - regs = of_get_property(dp, "reg", &len); 374 - if (!regs) { 416 + op = of_find_device_by_node(dp); 417 + if (!op) { 375 418 dev->num_addrs = 0; 376 - goto probe_interrupts; 377 - } 378 - 379 - if (len % sizeof(struct linux_prom_registers)) { 380 - prom_printf("UGH: proplen for %s was %d, need multiple of %d\n", 381 - dev->prom_node->name, len, 382 - (int)sizeof(struct linux_prom_registers)); 383 - prom_halt(); 384 - } 385 - dev->num_addrs = len / sizeof(struct linux_prom_registers); 386 - 387 - for (i = 0; i < dev->num_addrs; i++) { 388 - /* XXX Learn how to interpret ebus ranges... -DaveM */ 389 - if (regs[i].which_io >= 0x10) 390 - n = (regs[i].which_io - 0x10) >> 2; 391 - else 392 - n = regs[i].which_io; 393 - 394 - dev->resource[i].start = dev->bus->self->resource[n].start; 395 - dev->resource[i].start += (unsigned long)regs[i].phys_addr; 396 - dev->resource[i].end = 397 - (dev->resource[i].start + (unsigned long)regs[i].reg_size - 1UL); 398 - dev->resource[i].flags = IORESOURCE_MEM; 399 - dev->resource[i].name = dev->prom_node->name; 400 - request_resource(&dev->bus->self->resource[n], 401 - &dev->resource[i]); 402 - } 403 - 404 - probe_interrupts: 405 - for (i = 0; i < PROMINTR_MAX; i++) 406 - dev->irqs[i] = PCI_IRQ_NONE; 407 - 408 - irqs = of_get_property(dp, "interrupts", &len); 409 - if (!irqs) { 410 419 dev->num_irqs = 0; 411 420 } else { 412 - dev->num_irqs = len / sizeof(irqs[0]); 413 - for (i = 0; i < dev->num_irqs; i++) { 414 - struct pci_pbm_info *pbm = dev->bus->parent; 415 - struct pci_controller_info *p = pbm->parent; 421 + (void) of_get_property(dp, "reg", &len); 422 + dev->num_addrs = len / sizeof(struct linux_prom_registers); 416 423 417 - if (ebus_intmap_match(dev->bus, &regs[0], &irqs[i]) != -1) { 418 - dev->irqs[i] = p->irq_build(pbm, 419 - dev->bus->self, 420 - irqs[i]); 421 - } else { 422 - /* If we get a bogus interrupt property, just 423 - * record the raw value instead of punting. 424 - */ 425 - dev->irqs[i] = irqs[i]; 426 - } 427 - } 424 + for (i = 0; i < dev->num_addrs; i++) 425 + memcpy(&dev->resource[i], 426 + &op->resource[i], 427 + sizeof(struct resource)); 428 + 429 + dev->num_irqs = op->num_irqs; 430 + for (i = 0; i < dev->num_irqs; i++) 431 + dev->irqs[i] = op->irqs[i]; 428 432 } 429 433 430 434 dev->ofdev.node = dp; ··· 406 490 child->next = NULL; 407 491 child->parent = dev; 408 492 child->bus = dev->bus; 409 - fill_ebus_child(dp, regs, child, 493 + fill_ebus_child(dp, child, 410 494 child_regs_nonstandard(dev)); 411 495 412 496 while ((dp = dp->sibling) != NULL) { ··· 416 500 child->next = NULL; 417 501 child->parent = dev; 418 502 child->bus = dev->bus; 419 - fill_ebus_child(dp, regs, child, 503 + fill_ebus_child(dp, child, 420 504 child_regs_nonstandard(dev)); 421 505 } 422 506 }
+6 -95
arch/sparc64/kernel/isa.c
··· 3 3 #include <linux/pci.h> 4 4 #include <linux/slab.h> 5 5 #include <asm/oplib.h> 6 + #include <asm/prom.h> 7 + #include <asm/of_device.h> 6 8 #include <asm/isa.h> 7 9 8 10 struct sparc_isa_bridge *isa_chain; ··· 48 46 return pregs; 49 47 } 50 48 51 - /* I can't believe they didn't put a real INO in the isa device 52 - * interrupts property. The whole point of the OBP properties 53 - * is to shield the kernel from IRQ routing details. 54 - * 55 - * The P1275 standard for ISA devices seems to also have been 56 - * totally ignored. 57 - * 58 - * On later systems, an interrupt-map and interrupt-map-mask scheme 59 - * akin to EBUS is used. 60 - */ 61 - static struct { 62 - int obp_irq; 63 - int pci_ino; 64 - } grover_irq_table[] = { 65 - { 1, 0x00 }, /* dma, unknown ino at this point */ 66 - { 2, 0x27 }, /* floppy */ 67 - { 3, 0x22 }, /* parallel */ 68 - { 4, 0x2b }, /* serial */ 69 - { 5, 0x25 }, /* acpi power management */ 70 - 71 - { 0, 0x00 } /* end of table */ 72 - }; 73 - 74 - static int __init isa_dev_get_irq_using_imap(struct sparc_isa_device *isa_dev, 75 - struct sparc_isa_bridge *isa_br, 76 - int *interrupt, 77 - struct linux_prom_registers *reg) 78 - { 79 - struct linux_prom_ebus_intmap *imap; 80 - struct linux_prom_ebus_intmask *imask; 81 - unsigned int hi, lo, irq; 82 - int i, len, n_imap; 83 - 84 - imap = of_get_property(isa_br->prom_node, "interrupt-map", &len); 85 - if (!imap) 86 - return 0; 87 - n_imap = len / sizeof(imap[0]); 88 - 89 - imask = of_get_property(isa_br->prom_node, "interrupt-map-mask", NULL); 90 - if (!imask) 91 - return 0; 92 - 93 - hi = reg->which_io & imask->phys_hi; 94 - lo = reg->phys_addr & imask->phys_lo; 95 - irq = *interrupt & imask->interrupt; 96 - for (i = 0; i < n_imap; i++) { 97 - if ((imap[i].phys_hi == hi) && 98 - (imap[i].phys_lo == lo) && 99 - (imap[i].interrupt == irq)) { 100 - *interrupt = imap[i].cinterrupt; 101 - return 0; 102 - } 103 - } 104 - return -1; 105 - } 106 - 107 49 static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev, 108 50 struct linux_prom_registers *pregs) 109 51 { 110 - int irq_prop; 52 + struct of_device *op = of_find_device_by_node(isa_dev->prom_node); 111 53 112 - irq_prop = of_getintprop_default(isa_dev->prom_node, 113 - "interrupts", -1); 114 - if (irq_prop <= 0) { 115 - goto no_irq; 54 + if (!op || !op->num_irqs) { 55 + isa_dev->irq = PCI_IRQ_NONE; 116 56 } else { 117 - struct pci_controller_info *pcic; 118 - struct pci_pbm_info *pbm; 119 - int i; 120 - 121 - if (of_find_property(isa_dev->bus->prom_node, 122 - "interrupt-map", NULL)) { 123 - if (!isa_dev_get_irq_using_imap(isa_dev, 124 - isa_dev->bus, 125 - &irq_prop, 126 - pregs)) 127 - goto route_irq; 128 - } 129 - 130 - for (i = 0; grover_irq_table[i].obp_irq != 0; i++) { 131 - if (grover_irq_table[i].obp_irq == irq_prop) { 132 - int ino = grover_irq_table[i].pci_ino; 133 - 134 - if (ino == 0) 135 - goto no_irq; 136 - 137 - irq_prop = ino; 138 - goto route_irq; 139 - } 140 - } 141 - goto no_irq; 142 - 143 - route_irq: 144 - pbm = isa_dev->bus->parent; 145 - pcic = pbm->parent; 146 - isa_dev->irq = pcic->irq_build(pbm, NULL, irq_prop); 147 - return; 57 + isa_dev->irq = op->irqs[0]; 148 58 } 149 - 150 - no_irq: 151 - isa_dev->irq = PCI_IRQ_NONE; 152 59 } 153 60 154 61 static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
+188 -6
arch/sparc64/kernel/of_device.c
··· 146 146 } 147 147 EXPORT_SYMBOL(of_iounmap); 148 148 149 + static int node_match(struct device *dev, void *data) 150 + { 151 + struct of_device *op = to_of_device(dev); 152 + struct device_node *dp = data; 153 + 154 + return (op->node == dp); 155 + } 156 + 157 + struct of_device *of_find_device_by_node(struct device_node *dp) 158 + { 159 + struct device *dev = bus_find_device(&of_bus_type, NULL, 160 + dp, node_match); 161 + 162 + if (dev) 163 + return to_of_device(dev); 164 + 165 + return NULL; 166 + } 167 + EXPORT_SYMBOL(of_find_device_by_node); 168 + 149 169 #ifdef CONFIG_PCI 150 170 struct bus_type isa_bus_type = { 151 171 .name = "isa", ··· 280 260 { 281 261 return IORESOURCE_MEM; 282 262 } 283 - 284 263 285 264 /* 286 265 * PCI bus specific translator ··· 613 594 } 614 595 } 615 596 597 + static struct device_node * __init 598 + apply_interrupt_map(struct device_node *dp, struct device_node *pp, 599 + u32 *imap, int imlen, u32 *imask, 600 + unsigned int *irq_p) 601 + { 602 + struct device_node *cp; 603 + unsigned int irq = *irq_p; 604 + struct of_bus *bus; 605 + phandle handle; 606 + u32 *reg; 607 + int na, num_reg, i; 608 + 609 + bus = of_match_bus(pp); 610 + bus->count_cells(dp, &na, NULL); 611 + 612 + reg = of_get_property(dp, "reg", &num_reg); 613 + if (!reg || !num_reg) 614 + return NULL; 615 + 616 + imlen /= ((na + 3) * 4); 617 + handle = 0; 618 + for (i = 0; i < imlen; i++) { 619 + int j; 620 + 621 + for (j = 0; j < na; j++) { 622 + if ((reg[j] & imask[j]) != imap[j]) 623 + goto next; 624 + } 625 + if (imap[na] == irq) { 626 + handle = imap[na + 1]; 627 + irq = imap[na + 2]; 628 + break; 629 + } 630 + 631 + next: 632 + imap += (na + 3); 633 + } 634 + if (i == imlen) 635 + return NULL; 636 + 637 + *irq_p = irq; 638 + cp = of_find_node_by_phandle(handle); 639 + 640 + return cp; 641 + } 642 + 643 + static unsigned int __init pci_irq_swizzle(struct device_node *dp, 644 + struct device_node *pp, 645 + unsigned int irq) 646 + { 647 + struct linux_prom_pci_registers *regs; 648 + unsigned int devfn, slot, ret; 649 + 650 + if (irq < 1 || irq > 4) 651 + return irq; 652 + 653 + regs = of_get_property(dp, "reg", NULL); 654 + if (!regs) 655 + return irq; 656 + 657 + devfn = (regs->phys_hi >> 8) & 0xff; 658 + slot = (devfn >> 3) & 0x1f; 659 + 660 + ret = ((irq - 1 + (slot & 3)) & 3) + 1; 661 + 662 + return ret; 663 + } 664 + 665 + static unsigned int __init build_one_device_irq(struct of_device *op, 666 + struct device *parent, 667 + unsigned int irq) 668 + { 669 + struct device_node *dp = op->node; 670 + struct device_node *pp, *ip; 671 + unsigned int orig_irq = irq; 672 + 673 + if (irq == 0xffffffff) 674 + return irq; 675 + 676 + if (dp->irq_trans) { 677 + irq = dp->irq_trans->irq_build(dp, irq, 678 + dp->irq_trans->data); 679 + #if 1 680 + printk("%s: direct translate %x --> %x\n", 681 + dp->full_name, orig_irq, irq); 682 + #endif 683 + return irq; 684 + } 685 + 686 + /* Something more complicated. Walk up to the root, applying 687 + * interrupt-map or bus specific translations, until we hit 688 + * an IRQ translator. 689 + * 690 + * If we hit a bus type or situation we cannot handle, we 691 + * stop and assume that the original IRQ number was in a 692 + * format which has special meaning to it's immediate parent. 693 + */ 694 + pp = dp->parent; 695 + ip = NULL; 696 + while (pp) { 697 + void *imap, *imsk; 698 + int imlen; 699 + 700 + imap = of_get_property(pp, "interrupt-map", &imlen); 701 + imsk = of_get_property(pp, "interrupt-map-mask", NULL); 702 + if (imap && imsk) { 703 + struct device_node *iret; 704 + int this_orig_irq = irq; 705 + 706 + iret = apply_interrupt_map(dp, pp, 707 + imap, imlen, imsk, 708 + &irq); 709 + #if 1 710 + printk("%s: Apply [%s:%x] imap --> [%s:%x]\n", 711 + op->node->full_name, 712 + pp->full_name, this_orig_irq, 713 + (iret ? iret->full_name : "NULL"), irq); 714 + #endif 715 + if (!iret) 716 + break; 717 + 718 + if (iret->irq_trans) { 719 + ip = iret; 720 + break; 721 + } 722 + } else { 723 + if (!strcmp(pp->type, "pci") || 724 + !strcmp(pp->type, "pciex")) { 725 + unsigned int this_orig_irq = irq; 726 + 727 + irq = pci_irq_swizzle(dp, pp, irq); 728 + #if 1 729 + printk("%s: PCI swizzle [%s] %x --> %x\n", 730 + op->node->full_name, 731 + pp->full_name, this_orig_irq, irq); 732 + #endif 733 + } 734 + 735 + if (pp->irq_trans) { 736 + ip = pp; 737 + break; 738 + } 739 + } 740 + dp = pp; 741 + pp = pp->parent; 742 + } 743 + if (!ip) 744 + return orig_irq; 745 + 746 + irq = ip->irq_trans->irq_build(op->node, irq, 747 + ip->irq_trans->data); 748 + #if 1 749 + printk("%s: Apply IRQ trans [%s] %x --> %x\n", 750 + op->node->full_name, ip->full_name, orig_irq, irq); 751 + #endif 752 + 753 + return irq; 754 + } 755 + 616 756 static struct of_device * __init scan_one_device(struct device_node *dp, 617 757 struct device *parent) 618 758 { 619 759 struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL); 620 760 unsigned int *irq; 621 - int len; 761 + int len, i; 622 762 623 763 if (!op) 624 764 return NULL; ··· 791 613 op->portid = of_getintprop_default(dp, "portid", -1); 792 614 793 615 irq = of_get_property(dp, "interrupts", &len); 794 - if (irq) 795 - op->irq = *irq; 796 - else 797 - op->irq = 0xffffffff; 616 + if (irq) { 617 + memcpy(op->irqs, irq, len); 618 + op->num_irqs = len / 4; 619 + } else { 620 + op->num_irqs = 0; 621 + } 798 622 799 623 build_device_resources(op, parent); 624 + for (i = 0; i < op->num_irqs; i++) 625 + op->irqs[i] = build_one_device_irq(op, parent, op->irqs[i]); 800 626 801 627 op->dev.parent = parent; 802 628 op->dev.bus = &of_bus_type;
-6
arch/sparc64/kernel/pci.c
··· 404 404 } 405 405 EXPORT_SYMBOL(pcibios_bus_to_resource); 406 406 407 - extern int pci_irq_verbose; 408 - 409 407 char * __init pcibios_setup(char *str) 410 408 { 411 - if (!strcmp(str, "irq_verbose")) { 412 - pci_irq_verbose = 1; 413 - return NULL; 414 - } 415 409 return str; 416 410 } 417 411
+6 -285
arch/sparc64/kernel/pci_common.c
··· 10 10 11 11 #include <asm/pbm.h> 12 12 #include <asm/prom.h> 13 + #include <asm/of_device.h> 13 14 14 15 #include "pci_impl.h" 15 - 16 - /* Pass "pci=irq_verbose" on the kernel command line to enable this. */ 17 - int pci_irq_verbose; 18 16 19 17 /* Fix self device of BUS and hook it into BUS->self. 20 18 * The pci_scan_bus does not do this for the host bridge. ··· 167 169 } 168 170 pcp->pbm = pbm; 169 171 pcp->prom_node = dp; 172 + pcp->op = of_find_device_by_node(dp); 170 173 memcpy(pcp->prom_regs, pregs, 171 174 nregs * sizeof(struct linux_prom_pci_registers)); 172 175 pcp->num_prom_regs = nregs; ··· 548 549 pci_assign_unassigned(pbm, bus); 549 550 } 550 551 551 - static inline unsigned int pci_slot_swivel(struct pci_pbm_info *pbm, 552 - struct pci_dev *toplevel_pdev, 553 - struct pci_dev *pdev, 554 - unsigned int interrupt) 555 - { 556 - unsigned int ret; 557 - 558 - if (unlikely(interrupt < 1 || interrupt > 4)) { 559 - printk("%s: Device %s interrupt value of %u is strange.\n", 560 - pbm->name, pci_name(pdev), interrupt); 561 - return interrupt; 562 - } 563 - 564 - ret = ((interrupt - 1 + (PCI_SLOT(pdev->devfn) & 3)) & 3) + 1; 565 - 566 - if (pci_irq_verbose) 567 - printk("%s: %s IRQ Swivel %s [%x:%x] -> [%x]\n", 568 - pbm->name, pci_name(toplevel_pdev), pci_name(pdev), 569 - interrupt, PCI_SLOT(pdev->devfn), ret); 570 - 571 - return ret; 572 - } 573 - 574 - static inline unsigned int pci_apply_intmap(struct pci_pbm_info *pbm, 575 - struct pci_dev *toplevel_pdev, 576 - struct pci_dev *pbus, 577 - struct pci_dev *pdev, 578 - unsigned int interrupt, 579 - struct device_node **cnode) 580 - { 581 - struct linux_prom_pci_intmap *imap; 582 - struct linux_prom_pci_intmask *imask; 583 - struct pcidev_cookie *pbus_pcp = pbus->sysdata; 584 - struct pcidev_cookie *pdev_pcp = pdev->sysdata; 585 - struct linux_prom_pci_registers *pregs = pdev_pcp->prom_regs; 586 - struct property *prop; 587 - int plen, num_imap, i; 588 - unsigned int hi, mid, lo, irq, orig_interrupt; 589 - 590 - *cnode = pbus_pcp->prom_node; 591 - 592 - prop = of_find_property(pbus_pcp->prom_node, "interrupt-map", &plen); 593 - if (!prop || 594 - (plen % sizeof(struct linux_prom_pci_intmap)) != 0) { 595 - printk("%s: Device %s interrupt-map has bad len %d\n", 596 - pbm->name, pci_name(pbus), plen); 597 - goto no_intmap; 598 - } 599 - imap = prop->value; 600 - num_imap = plen / sizeof(struct linux_prom_pci_intmap); 601 - 602 - prop = of_find_property(pbus_pcp->prom_node, "interrupt-map-mask", &plen); 603 - if (!prop || 604 - (plen % sizeof(struct linux_prom_pci_intmask)) != 0) { 605 - printk("%s: Device %s interrupt-map-mask has bad len %d\n", 606 - pbm->name, pci_name(pbus), plen); 607 - goto no_intmap; 608 - } 609 - imask = prop->value; 610 - 611 - orig_interrupt = interrupt; 612 - 613 - hi = pregs->phys_hi & imask->phys_hi; 614 - mid = pregs->phys_mid & imask->phys_mid; 615 - lo = pregs->phys_lo & imask->phys_lo; 616 - irq = interrupt & imask->interrupt; 617 - 618 - for (i = 0; i < num_imap; i++) { 619 - if (imap[i].phys_hi == hi && 620 - imap[i].phys_mid == mid && 621 - imap[i].phys_lo == lo && 622 - imap[i].interrupt == irq) { 623 - *cnode = of_find_node_by_phandle(imap[i].cnode); 624 - interrupt = imap[i].cinterrupt; 625 - } 626 - } 627 - 628 - if (pci_irq_verbose) 629 - printk("%s: %s MAP BUS %s DEV %s [%x] -> [%x]\n", 630 - pbm->name, pci_name(toplevel_pdev), 631 - pci_name(pbus), pci_name(pdev), 632 - orig_interrupt, interrupt); 633 - 634 - no_intmap: 635 - return interrupt; 636 - } 637 - 638 - /* For each PCI bus on the way to the root: 639 - * 1) If it has an interrupt-map property, apply it. 640 - * 2) Else, swivel the interrupt number based upon the PCI device number. 641 - * 642 - * Return the "IRQ controller" node. If this is the PBM's device node, 643 - * all interrupt translations are complete, else we should use that node's 644 - * "reg" property to apply the PBM's "interrupt-{map,mask}" to the interrupt. 645 - */ 646 - static struct device_node * __init 647 - pci_intmap_match_to_root(struct pci_pbm_info *pbm, 648 - struct pci_dev *pdev, 649 - unsigned int *interrupt) 650 - { 651 - struct pci_dev *toplevel_pdev = pdev; 652 - struct pcidev_cookie *toplevel_pcp = toplevel_pdev->sysdata; 653 - struct device_node *cnode = toplevel_pcp->prom_node; 654 - 655 - while (pdev->bus->number != pbm->pci_first_busno) { 656 - struct pci_dev *pbus = pdev->bus->self; 657 - struct pcidev_cookie *pcp = pbus->sysdata; 658 - struct property *prop; 659 - 660 - prop = of_find_property(pcp->prom_node, "interrupt-map", NULL); 661 - if (!prop) { 662 - *interrupt = pci_slot_swivel(pbm, toplevel_pdev, 663 - pdev, *interrupt); 664 - cnode = pcp->prom_node; 665 - } else { 666 - *interrupt = pci_apply_intmap(pbm, toplevel_pdev, 667 - pbus, pdev, 668 - *interrupt, &cnode); 669 - 670 - while (pcp->prom_node != cnode && 671 - pbus->bus->number != pbm->pci_first_busno) { 672 - pbus = pbus->bus->self; 673 - pcp = pbus->sysdata; 674 - } 675 - } 676 - pdev = pbus; 677 - 678 - if (cnode == pbm->prom_node) 679 - break; 680 - } 681 - 682 - return cnode; 683 - } 684 - 685 - static int __init pci_intmap_match(struct pci_dev *pdev, unsigned int *interrupt) 686 - { 687 - struct pcidev_cookie *dev_pcp = pdev->sysdata; 688 - struct pci_pbm_info *pbm = dev_pcp->pbm; 689 - struct linux_prom_pci_registers *reg; 690 - struct device_node *cnode; 691 - struct property *prop; 692 - unsigned int hi, mid, lo, irq; 693 - int i, plen; 694 - 695 - cnode = pci_intmap_match_to_root(pbm, pdev, interrupt); 696 - if (cnode == pbm->prom_node) 697 - goto success; 698 - 699 - prop = of_find_property(cnode, "reg", &plen); 700 - if (!prop || 701 - (plen % sizeof(struct linux_prom_pci_registers)) != 0) { 702 - printk("%s: OBP node %s reg property has bad len %d\n", 703 - pbm->name, cnode->full_name, plen); 704 - goto fail; 705 - } 706 - reg = prop->value; 707 - 708 - hi = reg[0].phys_hi & pbm->pbm_intmask->phys_hi; 709 - mid = reg[0].phys_mid & pbm->pbm_intmask->phys_mid; 710 - lo = reg[0].phys_lo & pbm->pbm_intmask->phys_lo; 711 - irq = *interrupt & pbm->pbm_intmask->interrupt; 712 - 713 - for (i = 0; i < pbm->num_pbm_intmap; i++) { 714 - struct linux_prom_pci_intmap *intmap; 715 - 716 - intmap = &pbm->pbm_intmap[i]; 717 - 718 - if (intmap->phys_hi == hi && 719 - intmap->phys_mid == mid && 720 - intmap->phys_lo == lo && 721 - intmap->interrupt == irq) { 722 - *interrupt = intmap->cinterrupt; 723 - goto success; 724 - } 725 - } 726 - 727 - fail: 728 - return 0; 729 - 730 - success: 731 - if (pci_irq_verbose) 732 - printk("%s: Routing bus[%2x] slot[%2x] to INO[%02x]\n", 733 - pbm->name, 734 - pdev->bus->number, PCI_SLOT(pdev->devfn), 735 - *interrupt); 736 - return 1; 737 - } 738 - 739 552 static void __init pdev_fixup_irq(struct pci_dev *pdev) 740 553 { 741 554 struct pcidev_cookie *pcp = pdev->sysdata; 742 - struct pci_pbm_info *pbm = pcp->pbm; 743 - struct pci_controller_info *p = pbm->parent; 744 - unsigned int portid = pbm->portid; 745 - unsigned int prom_irq; 746 - struct device_node *dp = pcp->prom_node; 747 - struct property *prop; 555 + struct of_device *op = pcp->op; 748 556 749 - /* If this is an empty EBUS device, sometimes OBP fails to 750 - * give it a valid fully specified interrupts property. 751 - * The EBUS hooked up to SunHME on PCI I/O boards of 752 - * Ex000 systems is one such case. 753 - * 754 - * The interrupt is not important so just ignore it. 755 - */ 756 - if (pdev->vendor == PCI_VENDOR_ID_SUN && 757 - pdev->device == PCI_DEVICE_ID_SUN_EBUS && 758 - !dp->child) { 759 - pdev->irq = 0; 557 + if (op->irqs[0] == 0xffffffff) { 558 + pdev->irq = PCI_IRQ_NONE; 760 559 return; 761 560 } 762 561 763 - prop = of_find_property(dp, "interrupts", NULL); 764 - if (!prop) { 765 - pdev->irq = 0; 766 - return; 767 - } 768 - prom_irq = *(unsigned int *) prop->value; 562 + pdev->irq = op->irqs[0]; 769 563 770 - if (tlb_type != hypervisor) { 771 - /* Fully specified already? */ 772 - if (((prom_irq & PCI_IRQ_IGN) >> 6) == portid) { 773 - pdev->irq = p->irq_build(pbm, pdev, prom_irq); 774 - goto have_irq; 775 - } 776 - 777 - /* An onboard device? (bit 5 set) */ 778 - if ((prom_irq & PCI_IRQ_INO) & 0x20) { 779 - pdev->irq = p->irq_build(pbm, pdev, (portid << 6 | prom_irq)); 780 - goto have_irq; 781 - } 782 - } 783 - 784 - /* Can we find a matching entry in the interrupt-map? */ 785 - if (pci_intmap_match(pdev, &prom_irq)) { 786 - pdev->irq = p->irq_build(pbm, pdev, (portid << 6) | prom_irq); 787 - goto have_irq; 788 - } 789 - 790 - /* Ok, we have to do it the hard way. */ 791 - { 792 - unsigned int bus, slot, line; 793 - 794 - bus = (pbm == &pbm->parent->pbm_B) ? (1 << 4) : 0; 795 - 796 - /* If we have a legal interrupt property, use it as 797 - * the IRQ line. 798 - */ 799 - if (prom_irq > 0 && prom_irq < 5) { 800 - line = ((prom_irq - 1) & 3); 801 - } else { 802 - u8 pci_irq_line; 803 - 804 - /* Else just directly consult PCI config space. */ 805 - pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pci_irq_line); 806 - line = ((pci_irq_line - 1) & 3); 807 - } 808 - 809 - /* Now figure out the slot. 810 - * 811 - * Basically, device number zero on the top-level bus is 812 - * always the PCI host controller. Slot 0 is then device 1. 813 - * PBM A supports two external slots (0 and 1), and PBM B 814 - * supports 4 external slots (0, 1, 2, and 3). On-board PCI 815 - * devices are wired to device numbers outside of these 816 - * ranges. -DaveM 817 - */ 818 - if (pdev->bus->number == pbm->pci_first_busno) { 819 - slot = PCI_SLOT(pdev->devfn) - pbm->pci_first_slot; 820 - } else { 821 - struct pci_dev *bus_dev; 822 - 823 - /* Underneath a bridge, use slot number of parent 824 - * bridge which is closest to the PBM. 825 - */ 826 - bus_dev = pdev->bus->self; 827 - while (bus_dev->bus && 828 - bus_dev->bus->number != pbm->pci_first_busno) 829 - bus_dev = bus_dev->bus->self; 830 - 831 - slot = PCI_SLOT(bus_dev->devfn) - pbm->pci_first_slot; 832 - } 833 - slot = slot << 2; 834 - 835 - pdev->irq = p->irq_build(pbm, pdev, 836 - ((portid << 6) & PCI_IRQ_IGN) | 837 - (bus | slot | line)); 838 - } 839 - 840 - have_irq: 841 564 pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 842 565 pdev->irq & PCI_IRQ_INO); 843 566 }
+20 -141
arch/sparc64/kernel/pci_psycho.c
··· 18 18 #include <asm/irq.h> 19 19 #include <asm/starfire.h> 20 20 #include <asm/prom.h> 21 + #include <asm/of_device.h> 21 22 22 23 #include "pci_impl.h" 23 24 #include "iommu_common.h" ··· 208 207 .read = psycho_read_pci_cfg, 209 208 .write = psycho_write_pci_cfg, 210 209 }; 211 - 212 - /* PSYCHO interrupt mapping support. */ 213 - #define PSYCHO_IMAP_A_SLOT0 0x0c00UL 214 - #define PSYCHO_IMAP_B_SLOT0 0x0c20UL 215 - static unsigned long psycho_pcislot_imap_offset(unsigned long ino) 216 - { 217 - unsigned int bus = (ino & 0x10) >> 4; 218 - unsigned int slot = (ino & 0x0c) >> 2; 219 - 220 - if (bus == 0) 221 - return PSYCHO_IMAP_A_SLOT0 + (slot * 8); 222 - else 223 - return PSYCHO_IMAP_B_SLOT0 + (slot * 8); 224 - } 225 - 226 - #define PSYCHO_IMAP_SCSI 0x1000UL 227 - #define PSYCHO_IMAP_ETH 0x1008UL 228 - #define PSYCHO_IMAP_BPP 0x1010UL 229 - #define PSYCHO_IMAP_AU_REC 0x1018UL 230 - #define PSYCHO_IMAP_AU_PLAY 0x1020UL 231 - #define PSYCHO_IMAP_PFAIL 0x1028UL 232 - #define PSYCHO_IMAP_KMS 0x1030UL 233 - #define PSYCHO_IMAP_FLPY 0x1038UL 234 - #define PSYCHO_IMAP_SHW 0x1040UL 235 - #define PSYCHO_IMAP_KBD 0x1048UL 236 - #define PSYCHO_IMAP_MS 0x1050UL 237 - #define PSYCHO_IMAP_SER 0x1058UL 238 - #define PSYCHO_IMAP_TIM0 0x1060UL 239 - #define PSYCHO_IMAP_TIM1 0x1068UL 240 - #define PSYCHO_IMAP_UE 0x1070UL 241 - #define PSYCHO_IMAP_CE 0x1078UL 242 - #define PSYCHO_IMAP_A_ERR 0x1080UL 243 - #define PSYCHO_IMAP_B_ERR 0x1088UL 244 - #define PSYCHO_IMAP_PMGMT 0x1090UL 245 - #define PSYCHO_IMAP_GFX 0x1098UL 246 - #define PSYCHO_IMAP_EUPA 0x10a0UL 247 - 248 - static unsigned long __onboard_imap_off[] = { 249 - /*0x20*/ PSYCHO_IMAP_SCSI, 250 - /*0x21*/ PSYCHO_IMAP_ETH, 251 - /*0x22*/ PSYCHO_IMAP_BPP, 252 - /*0x23*/ PSYCHO_IMAP_AU_REC, 253 - /*0x24*/ PSYCHO_IMAP_AU_PLAY, 254 - /*0x25*/ PSYCHO_IMAP_PFAIL, 255 - /*0x26*/ PSYCHO_IMAP_KMS, 256 - /*0x27*/ PSYCHO_IMAP_FLPY, 257 - /*0x28*/ PSYCHO_IMAP_SHW, 258 - /*0x29*/ PSYCHO_IMAP_KBD, 259 - /*0x2a*/ PSYCHO_IMAP_MS, 260 - /*0x2b*/ PSYCHO_IMAP_SER, 261 - /*0x2c*/ PSYCHO_IMAP_TIM0, 262 - /*0x2d*/ PSYCHO_IMAP_TIM1, 263 - /*0x2e*/ PSYCHO_IMAP_UE, 264 - /*0x2f*/ PSYCHO_IMAP_CE, 265 - /*0x30*/ PSYCHO_IMAP_A_ERR, 266 - /*0x31*/ PSYCHO_IMAP_B_ERR, 267 - /*0x32*/ PSYCHO_IMAP_PMGMT 268 - }; 269 - #define PSYCHO_ONBOARD_IRQ_BASE 0x20 270 - #define PSYCHO_ONBOARD_IRQ_LAST 0x32 271 - #define psycho_onboard_imap_offset(__ino) \ 272 - __onboard_imap_off[(__ino) - PSYCHO_ONBOARD_IRQ_BASE] 273 - 274 - #define PSYCHO_ICLR_A_SLOT0 0x1400UL 275 - #define PSYCHO_ICLR_SCSI 0x1800UL 276 - 277 - #define psycho_iclr_offset(ino) \ 278 - ((ino & 0x20) ? (PSYCHO_ICLR_SCSI + (((ino) & 0x1f) << 3)) : \ 279 - (PSYCHO_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3))) 280 - 281 - static unsigned int psycho_irq_build(struct pci_pbm_info *pbm, 282 - struct pci_dev *pdev, 283 - unsigned int ino) 284 - { 285 - unsigned long imap, iclr; 286 - unsigned long imap_off, iclr_off; 287 - int inofixup = 0; 288 - 289 - ino &= PCI_IRQ_INO; 290 - if (ino < PSYCHO_ONBOARD_IRQ_BASE) { 291 - /* PCI slot */ 292 - imap_off = psycho_pcislot_imap_offset(ino); 293 - } else { 294 - /* Onboard device */ 295 - if (ino > PSYCHO_ONBOARD_IRQ_LAST) { 296 - prom_printf("psycho_irq_build: Wacky INO [%x]\n", ino); 297 - prom_halt(); 298 - } 299 - imap_off = psycho_onboard_imap_offset(ino); 300 - } 301 - 302 - /* Now build the IRQ bucket. */ 303 - imap = pbm->controller_regs + imap_off; 304 - imap += 4; 305 - 306 - iclr_off = psycho_iclr_offset(ino); 307 - iclr = pbm->controller_regs + iclr_off; 308 - iclr += 4; 309 - 310 - if ((ino & 0x20) == 0) 311 - inofixup = ino & 0x03; 312 - 313 - return build_irq(inofixup, iclr, imap); 314 - } 315 210 316 211 /* PSYCHO error handling support. */ 317 212 enum psycho_error_type { ··· 841 944 #define PSYCHO_ECCCTRL_EE 0x8000000000000000UL /* Enable ECC Checking */ 842 945 #define PSYCHO_ECCCTRL_UE 0x4000000000000000UL /* Enable UE Interrupts */ 843 946 #define PSYCHO_ECCCTRL_CE 0x2000000000000000UL /* Enable CE INterrupts */ 844 - #define PSYCHO_UE_INO 0x2e 845 - #define PSYCHO_CE_INO 0x2f 846 - #define PSYCHO_PCIERR_A_INO 0x30 847 - #define PSYCHO_PCIERR_B_INO 0x31 848 947 static void psycho_register_error_handlers(struct pci_controller_info *p) 849 948 { 850 949 struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ 950 + struct of_device *op = of_find_device_by_node(pbm->prom_node); 851 951 unsigned long base = p->pbm_A.controller_regs; 852 - unsigned int irq, portid = pbm->portid; 853 952 u64 tmp; 854 953 855 - /* Build IRQs and register handlers. */ 856 - irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_UE_INO); 857 - if (request_irq(irq, psycho_ue_intr, 858 - SA_SHIRQ, "PSYCHO UE", p) < 0) { 859 - prom_printf("PSYCHO%d: Cannot register UE interrupt.\n", 860 - p->index); 861 - prom_halt(); 862 - } 954 + if (!op) 955 + return; 863 956 864 - irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_CE_INO); 865 - if (request_irq(irq, psycho_ce_intr, 866 - SA_SHIRQ, "PSYCHO CE", p) < 0) { 867 - prom_printf("PSYCHO%d: Cannot register CE interrupt.\n", 868 - p->index); 869 - prom_halt(); 870 - } 957 + /* Psycho interrupt property order is: 958 + * 0: PCIERR PBM B INO 959 + * 1: UE ERR 960 + * 2: CE ERR 961 + * 3: POWER FAIL 962 + * 4: SPARE HARDWARE 963 + * 5: PCIERR PBM A INO 964 + */ 871 965 872 - pbm = &p->pbm_A; 873 - irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_PCIERR_A_INO); 874 - if (request_irq(irq, psycho_pcierr_intr, 875 - SA_SHIRQ, "PSYCHO PCIERR", &p->pbm_A) < 0) { 876 - prom_printf("PSYCHO%d(PBMA): Cannot register PciERR interrupt.\n", 877 - p->index); 878 - prom_halt(); 879 - } 966 + if (op->num_irqs < 6) 967 + return; 880 968 881 - pbm = &p->pbm_B; 882 - irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_PCIERR_B_INO); 883 - if (request_irq(irq, psycho_pcierr_intr, 884 - SA_SHIRQ, "PSYCHO PCIERR", &p->pbm_B) < 0) { 885 - prom_printf("PSYCHO%d(PBMB): Cannot register PciERR interrupt.\n", 886 - p->index); 887 - prom_halt(); 888 - } 969 + request_irq(op->irqs[1], psycho_ue_intr, SA_SHIRQ, "PSYCHO UE", p); 970 + request_irq(op->irqs[2], psycho_ce_intr, SA_SHIRQ, "PSYCHO CE", p); 971 + request_irq(op->irqs[5], psycho_pcierr_intr, SA_SHIRQ, 972 + "PSYCHO PCIERR-A", &p->pbm_A); 973 + request_irq(op->irqs[0], psycho_pcierr_intr, SA_SHIRQ, 974 + "PSYCHO PCIERR-B", &p->pbm_B); 889 975 890 976 /* Enable UE and CE interrupts for controller. */ 891 977 psycho_write(base + PSYCHO_ECC_CTRL, ··· 1286 1406 p->index = pci_num_controllers++; 1287 1407 p->pbms_same_domain = 0; 1288 1408 p->scan_bus = psycho_scan_bus; 1289 - p->irq_build = psycho_irq_build; 1290 1409 p->base_address_update = psycho_base_address_update; 1291 1410 p->resource_adjust = psycho_resource_adjust; 1292 1411 p->pci_ops = &psycho_ops;
+23 -135
arch/sparc64/kernel/pci_sabre.c
··· 485 485 .write = sabre_write_pci_cfg, 486 486 }; 487 487 488 - static unsigned long sabre_pcislot_imap_offset(unsigned long ino) 489 - { 490 - unsigned int bus = (ino & 0x10) >> 4; 491 - unsigned int slot = (ino & 0x0c) >> 2; 492 - 493 - if (bus == 0) 494 - return SABRE_IMAP_A_SLOT0 + (slot * 8); 495 - else 496 - return SABRE_IMAP_B_SLOT0 + (slot * 8); 497 - } 498 - 499 - static unsigned long __onboard_imap_off[] = { 500 - /*0x20*/ SABRE_IMAP_SCSI, 501 - /*0x21*/ SABRE_IMAP_ETH, 502 - /*0x22*/ SABRE_IMAP_BPP, 503 - /*0x23*/ SABRE_IMAP_AU_REC, 504 - /*0x24*/ SABRE_IMAP_AU_PLAY, 505 - /*0x25*/ SABRE_IMAP_PFAIL, 506 - /*0x26*/ SABRE_IMAP_KMS, 507 - /*0x27*/ SABRE_IMAP_FLPY, 508 - /*0x28*/ SABRE_IMAP_SHW, 509 - /*0x29*/ SABRE_IMAP_KBD, 510 - /*0x2a*/ SABRE_IMAP_MS, 511 - /*0x2b*/ SABRE_IMAP_SER, 512 - /*0x2c*/ 0 /* reserved */, 513 - /*0x2d*/ 0 /* reserved */, 514 - /*0x2e*/ SABRE_IMAP_UE, 515 - /*0x2f*/ SABRE_IMAP_CE, 516 - /*0x30*/ SABRE_IMAP_PCIERR, 517 - }; 518 - #define SABRE_ONBOARD_IRQ_BASE 0x20 519 - #define SABRE_ONBOARD_IRQ_LAST 0x30 520 - #define sabre_onboard_imap_offset(__ino) \ 521 - __onboard_imap_off[(__ino) - SABRE_ONBOARD_IRQ_BASE] 522 - 523 - #define sabre_iclr_offset(ino) \ 524 - ((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) : \ 525 - (SABRE_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3))) 526 - 527 - /* When a device lives behind a bridge deeper in the PCI bus topology 528 - * than APB, a special sequence must run to make sure all pending DMA 529 - * transfers at the time of IRQ delivery are visible in the coherency 530 - * domain by the cpu. This sequence is to perform a read on the far 531 - * side of the non-APB bridge, then perform a read of Sabre's DMA 532 - * write-sync register. 533 - */ 534 - static void sabre_wsync_handler(unsigned int ino, void *_arg1, void *_arg2) 535 - { 536 - struct pci_dev *pdev = _arg1; 537 - unsigned long sync_reg = (unsigned long) _arg2; 538 - u16 _unused; 539 - 540 - pci_read_config_word(pdev, PCI_VENDOR_ID, &_unused); 541 - sabre_read(sync_reg); 542 - } 543 - 544 - static unsigned int sabre_irq_build(struct pci_pbm_info *pbm, 545 - struct pci_dev *pdev, 546 - unsigned int ino) 547 - { 548 - unsigned long imap, iclr; 549 - unsigned long imap_off, iclr_off; 550 - int inofixup = 0; 551 - int virt_irq; 552 - 553 - ino &= PCI_IRQ_INO; 554 - if (ino < SABRE_ONBOARD_IRQ_BASE) { 555 - /* PCI slot */ 556 - imap_off = sabre_pcislot_imap_offset(ino); 557 - } else { 558 - /* onboard device */ 559 - if (ino > SABRE_ONBOARD_IRQ_LAST) { 560 - prom_printf("sabre_irq_build: Wacky INO [%x]\n", ino); 561 - prom_halt(); 562 - } 563 - imap_off = sabre_onboard_imap_offset(ino); 564 - } 565 - 566 - /* Now build the IRQ bucket. */ 567 - imap = pbm->controller_regs + imap_off; 568 - imap += 4; 569 - 570 - iclr_off = sabre_iclr_offset(ino); 571 - iclr = pbm->controller_regs + iclr_off; 572 - iclr += 4; 573 - 574 - if ((ino & 0x20) == 0) 575 - inofixup = ino & 0x03; 576 - 577 - virt_irq = build_irq(inofixup, iclr, imap); 578 - 579 - if (pdev) { 580 - struct pcidev_cookie *pcp = pdev->sysdata; 581 - 582 - if (pdev->bus->number != pcp->pbm->pci_first_busno) { 583 - struct pci_controller_info *p = pcp->pbm->parent; 584 - 585 - irq_install_pre_handler(virt_irq, 586 - sabre_wsync_handler, 587 - pdev, 588 - (void *) 589 - p->pbm_A.controller_regs + 590 - SABRE_WRSYNC); 591 - } 592 - } 593 - return virt_irq; 594 - } 595 - 596 488 /* SABRE error handling support. */ 597 489 static void sabre_check_iommu_error(struct pci_controller_info *p, 598 490 unsigned long afsr, ··· 821 929 return IRQ_HANDLED; 822 930 } 823 931 824 - /* XXX What about PowerFail/PowerManagement??? -DaveM */ 825 - #define SABRE_UE_INO 0x2e 826 - #define SABRE_CE_INO 0x2f 827 - #define SABRE_PCIERR_INO 0x30 828 932 static void sabre_register_error_handlers(struct pci_controller_info *p) 829 933 { 830 934 struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ 935 + struct device_node *dp = pbm->prom_node; 936 + struct of_device *op; 831 937 unsigned long base = pbm->controller_regs; 832 - unsigned long irq, portid = pbm->portid; 833 938 u64 tmp; 939 + 940 + if (pbm->chip_type == PBM_CHIP_TYPE_SABRE) 941 + dp = dp->parent; 942 + 943 + op = of_find_device_by_node(dp); 944 + if (!op) 945 + return; 946 + 947 + /* Sabre/Hummingbird IRQ property layout is: 948 + * 0: PCI ERR 949 + * 1: UE ERR 950 + * 2: CE ERR 951 + * 3: POWER FAIL 952 + */ 953 + if (op->num_irqs < 4) 954 + return; 834 955 835 956 /* We clear the error bits in the appropriate AFSR before 836 957 * registering the handler so that we don't get spurious ··· 853 948 (SABRE_UEAFSR_PDRD | SABRE_UEAFSR_PDWR | 854 949 SABRE_UEAFSR_SDRD | SABRE_UEAFSR_SDWR | 855 950 SABRE_UEAFSR_SDTE | SABRE_UEAFSR_PDTE)); 856 - irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_UE_INO); 857 - if (request_irq(irq, sabre_ue_intr, 858 - SA_SHIRQ, "SABRE UE", p) < 0) { 859 - prom_printf("SABRE%d: Cannot register UE interrupt.\n", 860 - p->index); 861 - prom_halt(); 862 - } 951 + 952 + request_irq(op->irqs[1], sabre_ue_intr, SA_SHIRQ, "SABRE UE", p); 863 953 864 954 sabre_write(base + SABRE_CE_AFSR, 865 955 (SABRE_CEAFSR_PDRD | SABRE_CEAFSR_PDWR | 866 956 SABRE_CEAFSR_SDRD | SABRE_CEAFSR_SDWR)); 867 - irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_CE_INO); 868 - if (request_irq(irq, sabre_ce_intr, 869 - SA_SHIRQ, "SABRE CE", p) < 0) { 870 - prom_printf("SABRE%d: Cannot register CE interrupt.\n", 871 - p->index); 872 - prom_halt(); 873 - } 874 957 875 - irq = sabre_irq_build(pbm, NULL, (portid << 6) | SABRE_PCIERR_INO); 876 - if (request_irq(irq, sabre_pcierr_intr, 877 - SA_SHIRQ, "SABRE PCIERR", p) < 0) { 878 - prom_printf("SABRE%d: Cannot register PciERR interrupt.\n", 879 - p->index); 880 - prom_halt(); 881 - } 958 + request_irq(op->irqs[2], sabre_ce_intr, SA_SHIRQ, "SABRE CE", p); 959 + request_irq(op->irqs[0], sabre_pcierr_intr, SA_SHIRQ, 960 + "SABRE PCIERR", p); 882 961 883 962 tmp = sabre_read(base + SABRE_PCICTRL); 884 963 tmp |= SABRE_PCICTRL_ERREN; ··· 1381 1492 p->index = pci_num_controllers++; 1382 1493 p->pbms_same_domain = 1; 1383 1494 p->scan_bus = sabre_scan_bus; 1384 - p->irq_build = sabre_irq_build; 1385 1495 p->base_address_update = sabre_base_address_update; 1386 1496 p->resource_adjust = sabre_resource_adjust; 1387 1497 p->pci_ops = &sabre_ops;
+60 -251
arch/sparc64/kernel/pci_schizo.c
··· 217 217 .write = schizo_write_pci_cfg, 218 218 }; 219 219 220 - /* SCHIZO interrupt mapping support. Unlike Psycho, for this controller the 221 - * imap/iclr registers are per-PBM. 222 - */ 223 - #define SCHIZO_IMAP_BASE 0x1000UL 224 - #define SCHIZO_ICLR_BASE 0x1400UL 225 - 226 - static unsigned long schizo_imap_offset(unsigned long ino) 227 - { 228 - return SCHIZO_IMAP_BASE + (ino * 8UL); 229 - } 230 - 231 - static unsigned long schizo_iclr_offset(unsigned long ino) 232 - { 233 - return SCHIZO_ICLR_BASE + (ino * 8UL); 234 - } 235 - 236 - static void tomatillo_wsync_handler(unsigned int ino, void *_arg1, void *_arg2) 237 - { 238 - unsigned long sync_reg = (unsigned long) _arg2; 239 - u64 mask = 1UL << (ino & IMAP_INO); 240 - u64 val; 241 - int limit; 242 - 243 - schizo_write(sync_reg, mask); 244 - 245 - limit = 100000; 246 - val = 0; 247 - while (--limit) { 248 - val = schizo_read(sync_reg); 249 - if (!(val & mask)) 250 - break; 251 - } 252 - if (limit <= 0) { 253 - printk("tomatillo_wsync_handler: DMA won't sync [%lx:%lx]\n", 254 - val, mask); 255 - } 256 - 257 - if (_arg1) { 258 - static unsigned char cacheline[64] 259 - __attribute__ ((aligned (64))); 260 - 261 - __asm__ __volatile__("rd %%fprs, %0\n\t" 262 - "or %0, %4, %1\n\t" 263 - "wr %1, 0x0, %%fprs\n\t" 264 - "stda %%f0, [%5] %6\n\t" 265 - "wr %0, 0x0, %%fprs\n\t" 266 - "membar #Sync" 267 - : "=&r" (mask), "=&r" (val) 268 - : "0" (mask), "1" (val), 269 - "i" (FPRS_FEF), "r" (&cacheline[0]), 270 - "i" (ASI_BLK_COMMIT_P)); 271 - } 272 - } 273 - 274 - static unsigned long schizo_ino_to_iclr(struct pci_pbm_info *pbm, 275 - unsigned int ino) 276 - { 277 - ino &= PCI_IRQ_INO; 278 - return pbm->pbm_regs + schizo_iclr_offset(ino) + 4; 279 - } 280 - 281 - static unsigned long schizo_ino_to_imap(struct pci_pbm_info *pbm, 282 - unsigned int ino) 283 - { 284 - ino &= PCI_IRQ_INO; 285 - return pbm->pbm_regs + schizo_imap_offset(ino) + 4; 286 - } 287 - 288 - static unsigned int schizo_irq_build(struct pci_pbm_info *pbm, 289 - struct pci_dev *pdev, 290 - unsigned int ino) 291 - { 292 - unsigned long imap, iclr; 293 - int ign_fixup; 294 - int virt_irq; 295 - 296 - ino &= PCI_IRQ_INO; 297 - 298 - /* Now build the IRQ bucket. */ 299 - imap = schizo_ino_to_imap(pbm, ino); 300 - iclr = schizo_ino_to_iclr(pbm, ino); 301 - 302 - /* On Schizo, no inofixup occurs. This is because each 303 - * INO has it's own IMAP register. On Psycho and Sabre 304 - * there is only one IMAP register for each PCI slot even 305 - * though four different INOs can be generated by each 306 - * PCI slot. 307 - * 308 - * But, for JBUS variants (essentially, Tomatillo), we have 309 - * to fixup the lowest bit of the interrupt group number. 310 - */ 311 - ign_fixup = 0; 312 - if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) { 313 - if (pbm->portid & 1) 314 - ign_fixup = (1 << 6); 315 - } 316 - 317 - virt_irq = build_irq(ign_fixup, iclr, imap); 318 - 319 - if (pdev && pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) { 320 - irq_install_pre_handler(virt_irq, 321 - tomatillo_wsync_handler, 322 - ((pbm->chip_version <= 4) ? 323 - (void *) 1 : (void *) 0), 324 - (void *) pbm->sync_reg); 325 - } 326 - 327 - return virt_irq; 328 - } 329 - 330 220 /* SCHIZO error handling support. */ 331 221 enum schizo_error_type { 332 222 UE_ERR, CE_ERR, PCI_ERR, SAFARI_ERR ··· 250 360 p->index); 251 361 252 362 return &p->pbm_A; 253 - } 254 - 255 - static void schizo_clear_other_err_intr(struct pci_controller_info *p, int irq) 256 - { 257 - struct pci_pbm_info *pbm; 258 - unsigned long iclr; 259 - 260 - /* Do not clear the interrupt for the other PCI bus. 261 - * 262 - * This "ACK both PBM IRQs" only needs to be performed 263 - * for chip-wide error interrupts. 264 - */ 265 - if ((irq & IMAP_INO) == SCHIZO_PCIERR_A_INO || 266 - (irq & IMAP_INO) == SCHIZO_PCIERR_B_INO) 267 - return; 268 - 269 - pbm = pbm_for_ino(p, irq); 270 - if (pbm == &p->pbm_A) 271 - pbm = &p->pbm_B; 272 - else 273 - pbm = &p->pbm_A; 274 - 275 - schizo_irq_build(pbm, NULL, 276 - (pbm->portid << 6) | (irq & IMAP_INO)); 277 - 278 - iclr = schizo_ino_to_iclr(pbm, 279 - (pbm->portid << 6) | (irq & IMAP_INO)); 280 - upa_writel(ICLR_IDLE, iclr); 281 363 } 282 364 283 365 #define SCHIZO_STC_ERR 0xb800UL /* --> 0xba00 */ ··· 582 720 /* Interrogate IOMMU for error status. */ 583 721 schizo_check_iommu_error(p, UE_ERR); 584 722 585 - schizo_clear_other_err_intr(p, irq); 586 - 587 723 return IRQ_HANDLED; 588 724 } 589 725 ··· 670 810 if (!reported) 671 811 printk("(none)"); 672 812 printk("]\n"); 673 - 674 - schizo_clear_other_err_intr(p, irq); 675 813 676 814 return IRQ_HANDLED; 677 815 } ··· 891 1033 if (error_bits & (SCHIZO_PCIAFSR_PPERR | SCHIZO_PCIAFSR_SPERR)) 892 1034 pci_scan_for_parity_error(p, pbm, pbm->pci_bus); 893 1035 894 - schizo_clear_other_err_intr(p, irq); 895 - 896 1036 return IRQ_HANDLED; 897 1037 } 898 1038 ··· 946 1090 printk("PCI%d: Unexpected Safari/JBUS error interrupt, errlog[%016lx]\n", 947 1091 p->index, errlog); 948 1092 949 - schizo_clear_other_err_intr(p, irq); 950 1093 return IRQ_HANDLED; 951 1094 } 952 1095 ··· 953 1098 p->index); 954 1099 schizo_check_iommu_error(p, SAFARI_ERR); 955 1100 956 - schizo_clear_other_err_intr(p, irq); 957 1101 return IRQ_HANDLED; 958 1102 } 959 1103 ··· 984 1130 static void tomatillo_register_error_handlers(struct pci_controller_info *p) 985 1131 { 986 1132 struct pci_pbm_info *pbm; 987 - unsigned int irq; 1133 + struct of_device *op; 988 1134 u64 tmp, err_mask, err_no_mask; 989 1135 990 - /* Build IRQs and register handlers. */ 1136 + /* Tomatillo IRQ property layout is: 1137 + * 0: PCIERR 1138 + * 1: UE ERR 1139 + * 2: CE ERR 1140 + * 3: SERR 1141 + * 4: POWER FAIL? 1142 + */ 1143 + 991 1144 pbm = pbm_for_ino(p, SCHIZO_UE_INO); 992 - irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_UE_INO); 993 - if (request_irq(irq, schizo_ue_intr, 994 - SA_SHIRQ, "TOMATILLO UE", p) < 0) { 995 - prom_printf("%s: Cannot register UE interrupt.\n", 996 - pbm->name); 997 - prom_halt(); 998 - } 999 - tmp = upa_readl(schizo_ino_to_imap(pbm, (pbm->portid << 6) | SCHIZO_UE_INO)); 1000 - upa_writel(tmp, (pbm->pbm_regs + 1001 - schizo_imap_offset(SCHIZO_UE_INO) + 4)); 1145 + op = of_find_device_by_node(pbm->prom_node); 1146 + if (op) 1147 + request_irq(op->irqs[1], schizo_ue_intr, SA_SHIRQ, 1148 + "TOMATILLO_UE", p); 1002 1149 1003 1150 pbm = pbm_for_ino(p, SCHIZO_CE_INO); 1004 - irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_CE_INO); 1005 - if (request_irq(irq, schizo_ce_intr, 1006 - SA_SHIRQ, "TOMATILLO CE", p) < 0) { 1007 - prom_printf("%s: Cannot register CE interrupt.\n", 1008 - pbm->name); 1009 - prom_halt(); 1010 - } 1011 - tmp = upa_readl(schizo_ino_to_imap(pbm, (pbm->portid << 6) | SCHIZO_CE_INO)); 1012 - upa_writel(tmp, (pbm->pbm_regs + 1013 - schizo_imap_offset(SCHIZO_CE_INO) + 4)); 1151 + op = of_find_device_by_node(pbm->prom_node); 1152 + if (op) 1153 + request_irq(op->irqs[2], schizo_ce_intr, SA_SHIRQ, 1154 + "TOMATILLO CE", p); 1014 1155 1015 1156 pbm = pbm_for_ino(p, SCHIZO_PCIERR_A_INO); 1016 - irq = schizo_irq_build(pbm, NULL, ((pbm->portid << 6) | 1017 - SCHIZO_PCIERR_A_INO)); 1018 - if (request_irq(irq, schizo_pcierr_intr, 1019 - SA_SHIRQ, "TOMATILLO PCIERR", pbm) < 0) { 1020 - prom_printf("%s: Cannot register PBM A PciERR interrupt.\n", 1021 - pbm->name); 1022 - prom_halt(); 1023 - } 1024 - tmp = upa_readl(schizo_ino_to_imap(pbm, ((pbm->portid << 6) | 1025 - SCHIZO_PCIERR_A_INO))); 1026 - upa_writel(tmp, (pbm->pbm_regs + 1027 - schizo_imap_offset(SCHIZO_PCIERR_A_INO) + 4)); 1157 + op = of_find_device_by_node(pbm->prom_node); 1158 + if (op) 1159 + request_irq(op->irqs[0], schizo_pcierr_intr, SA_SHIRQ, 1160 + "TOMATILLO PCIERR-A", pbm); 1161 + 1028 1162 1029 1163 pbm = pbm_for_ino(p, SCHIZO_PCIERR_B_INO); 1030 - irq = schizo_irq_build(pbm, NULL, ((pbm->portid << 6) | 1031 - SCHIZO_PCIERR_B_INO)); 1032 - if (request_irq(irq, schizo_pcierr_intr, 1033 - SA_SHIRQ, "TOMATILLO PCIERR", pbm) < 0) { 1034 - prom_printf("%s: Cannot register PBM B PciERR interrupt.\n", 1035 - pbm->name); 1036 - prom_halt(); 1037 - } 1038 - tmp = upa_readl(schizo_ino_to_imap(pbm, ((pbm->portid << 6) | 1039 - SCHIZO_PCIERR_B_INO))); 1040 - upa_writel(tmp, (pbm->pbm_regs + 1041 - schizo_imap_offset(SCHIZO_PCIERR_B_INO) + 4)); 1164 + op = of_find_device_by_node(pbm->prom_node); 1165 + if (op) 1166 + request_irq(op->irqs[0], schizo_pcierr_intr, SA_SHIRQ, 1167 + "TOMATILLO PCIERR-B", pbm); 1042 1168 1043 1169 pbm = pbm_for_ino(p, SCHIZO_SERR_INO); 1044 - irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_SERR_INO); 1045 - if (request_irq(irq, schizo_safarierr_intr, 1046 - SA_SHIRQ, "TOMATILLO SERR", p) < 0) { 1047 - prom_printf("%s: Cannot register SafariERR interrupt.\n", 1048 - pbm->name); 1049 - prom_halt(); 1050 - } 1051 - tmp = upa_readl(schizo_ino_to_imap(pbm, ((pbm->portid << 6) | 1052 - SCHIZO_SERR_INO))); 1053 - upa_writel(tmp, (pbm->pbm_regs + 1054 - schizo_imap_offset(SCHIZO_SERR_INO) + 4)); 1170 + op = of_find_device_by_node(pbm->prom_node); 1171 + if (op) 1172 + request_irq(op->irqs[3], schizo_safarierr_intr, SA_SHIRQ, 1173 + "TOMATILLO SERR", p); 1055 1174 1056 1175 /* Enable UE and CE interrupts for controller. */ 1057 1176 schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL, ··· 1092 1265 static void schizo_register_error_handlers(struct pci_controller_info *p) 1093 1266 { 1094 1267 struct pci_pbm_info *pbm; 1095 - unsigned int irq; 1268 + struct of_device *op; 1096 1269 u64 tmp, err_mask, err_no_mask; 1097 1270 1098 - /* Build IRQs and register handlers. */ 1271 + /* Schizo IRQ property layout is: 1272 + * 0: PCIERR 1273 + * 1: UE ERR 1274 + * 2: CE ERR 1275 + * 3: SERR 1276 + * 4: POWER FAIL? 1277 + */ 1278 + 1099 1279 pbm = pbm_for_ino(p, SCHIZO_UE_INO); 1100 - irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_UE_INO); 1101 - if (request_irq(irq, schizo_ue_intr, 1102 - SA_SHIRQ, "SCHIZO UE", p) < 0) { 1103 - prom_printf("%s: Cannot register UE interrupt.\n", 1104 - pbm->name); 1105 - prom_halt(); 1106 - } 1107 - tmp = upa_readl(schizo_ino_to_imap(pbm, (pbm->portid << 6) | SCHIZO_UE_INO)); 1108 - upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_UE_INO) + 4)); 1280 + op = of_find_device_by_node(pbm->prom_node); 1281 + if (op) 1282 + request_irq(op->irqs[1], schizo_ue_intr, SA_SHIRQ, 1283 + "SCHIZO_UE", p); 1109 1284 1110 1285 pbm = pbm_for_ino(p, SCHIZO_CE_INO); 1111 - irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_CE_INO); 1112 - if (request_irq(irq, schizo_ce_intr, 1113 - SA_SHIRQ, "SCHIZO CE", p) < 0) { 1114 - prom_printf("%s: Cannot register CE interrupt.\n", 1115 - pbm->name); 1116 - prom_halt(); 1117 - } 1118 - tmp = upa_readl(schizo_ino_to_imap(pbm, (pbm->portid << 6) | SCHIZO_CE_INO)); 1119 - upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_CE_INO) + 4)); 1286 + op = of_find_device_by_node(pbm->prom_node); 1287 + if (op) 1288 + request_irq(op->irqs[2], schizo_ce_intr, SA_SHIRQ, 1289 + "SCHIZO CE", p); 1120 1290 1121 1291 pbm = pbm_for_ino(p, SCHIZO_PCIERR_A_INO); 1122 - irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_PCIERR_A_INO); 1123 - if (request_irq(irq, schizo_pcierr_intr, 1124 - SA_SHIRQ, "SCHIZO PCIERR", pbm) < 0) { 1125 - prom_printf("%s: Cannot register PBM A PciERR interrupt.\n", 1126 - pbm->name); 1127 - prom_halt(); 1128 - } 1129 - tmp = upa_readl(schizo_ino_to_imap(pbm, (pbm->portid << 6) | SCHIZO_PCIERR_A_INO)); 1130 - upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_PCIERR_A_INO) + 4)); 1292 + op = of_find_device_by_node(pbm->prom_node); 1293 + if (op) 1294 + request_irq(op->irqs[0], schizo_pcierr_intr, SA_SHIRQ, 1295 + "SCHIZO PCIERR-A", pbm); 1296 + 1131 1297 1132 1298 pbm = pbm_for_ino(p, SCHIZO_PCIERR_B_INO); 1133 - irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_PCIERR_B_INO); 1134 - if (request_irq(irq, schizo_pcierr_intr, 1135 - SA_SHIRQ, "SCHIZO PCIERR", &p->pbm_B) < 0) { 1136 - prom_printf("%s: Cannot register PBM B PciERR interrupt.\n", 1137 - pbm->name); 1138 - prom_halt(); 1139 - } 1140 - tmp = upa_readl(schizo_ino_to_imap(pbm, (pbm->portid << 6) | SCHIZO_PCIERR_B_INO)); 1141 - upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_PCIERR_B_INO) + 4)); 1299 + op = of_find_device_by_node(pbm->prom_node); 1300 + if (op) 1301 + request_irq(op->irqs[0], schizo_pcierr_intr, SA_SHIRQ, 1302 + "SCHIZO PCIERR-B", pbm); 1142 1303 1143 1304 pbm = pbm_for_ino(p, SCHIZO_SERR_INO); 1144 - irq = schizo_irq_build(pbm, NULL, (pbm->portid << 6) | SCHIZO_SERR_INO); 1145 - if (request_irq(irq, schizo_safarierr_intr, 1146 - SA_SHIRQ, "SCHIZO SERR", p) < 0) { 1147 - prom_printf("%s: Cannot register SafariERR interrupt.\n", 1148 - pbm->name); 1149 - prom_halt(); 1150 - } 1151 - tmp = upa_readl(schizo_ino_to_imap(pbm, (pbm->portid << 6) | SCHIZO_SERR_INO)); 1152 - upa_writel(tmp, (pbm->pbm_regs + schizo_imap_offset(SCHIZO_SERR_INO) + 4)); 1305 + op = of_find_device_by_node(pbm->prom_node); 1306 + if (op) 1307 + request_irq(op->irqs[3], schizo_safarierr_intr, SA_SHIRQ, 1308 + "SCHIZO SERR", p); 1153 1309 1154 1310 /* Enable UE and CE interrupts for controller. */ 1155 1311 schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL, ··· 1832 2022 p->scan_bus = (chip_type == PBM_CHIP_TYPE_TOMATILLO ? 1833 2023 tomatillo_scan_bus : 1834 2024 schizo_scan_bus); 1835 - p->irq_build = schizo_irq_build; 1836 2025 p->base_address_update = schizo_base_address_update; 1837 2026 p->resource_adjust = schizo_resource_adjust; 1838 2027 p->pci_ops = &schizo_ops;
-10
arch/sparc64/kernel/pci_sun4v.c
··· 843 843 /* XXX register error interrupt handlers XXX */ 844 844 } 845 845 846 - static unsigned int pci_sun4v_irq_build(struct pci_pbm_info *pbm, 847 - struct pci_dev *pdev, 848 - unsigned int devino) 849 - { 850 - u32 devhandle = pbm->devhandle; 851 - 852 - return sun4v_build_irq(devhandle, devino); 853 - } 854 - 855 846 static void pci_sun4v_base_address_update(struct pci_dev *pdev, int resource) 856 847 { 857 848 struct pcidev_cookie *pcp = pdev->sysdata; ··· 1191 1200 p->pbms_same_domain = 0; 1192 1201 1193 1202 p->scan_bus = pci_sun4v_scan_bus; 1194 - p->irq_build = pci_sun4v_irq_build; 1195 1203 p->base_address_update = pci_sun4v_base_address_update; 1196 1204 p->resource_adjust = pci_sun4v_resource_adjust; 1197 1205 p->pci_ops = &pci_sun4v_ops;
+755 -2
arch/sparc64/kernel/prom.c
··· 15 15 * 2 of the License, or (at your option) any later version. 16 16 */ 17 17 18 + #include <linux/config.h> 18 19 #include <linux/kernel.h> 19 20 #include <linux/types.h> 20 21 #include <linux/string.h> ··· 24 23 #include <linux/module.h> 25 24 26 25 #include <asm/prom.h> 26 + #include <asm/of_device.h> 27 27 #include <asm/oplib.h> 28 + #include <asm/irq.h> 29 + #include <asm/asi.h> 30 + #include <asm/upa.h> 28 31 29 32 static struct device_node *allnodes; 30 33 ··· 286 281 prom_early_allocated += size; 287 282 288 283 return ret; 284 + } 285 + 286 + #ifdef CONFIG_PCI 287 + /* PSYCHO interrupt mapping support. */ 288 + #define PSYCHO_IMAP_A_SLOT0 0x0c00UL 289 + #define PSYCHO_IMAP_B_SLOT0 0x0c20UL 290 + static unsigned long psycho_pcislot_imap_offset(unsigned long ino) 291 + { 292 + unsigned int bus = (ino & 0x10) >> 4; 293 + unsigned int slot = (ino & 0x0c) >> 2; 294 + 295 + if (bus == 0) 296 + return PSYCHO_IMAP_A_SLOT0 + (slot * 8); 297 + else 298 + return PSYCHO_IMAP_B_SLOT0 + (slot * 8); 299 + } 300 + 301 + #define PSYCHO_IMAP_SCSI 0x1000UL 302 + #define PSYCHO_IMAP_ETH 0x1008UL 303 + #define PSYCHO_IMAP_BPP 0x1010UL 304 + #define PSYCHO_IMAP_AU_REC 0x1018UL 305 + #define PSYCHO_IMAP_AU_PLAY 0x1020UL 306 + #define PSYCHO_IMAP_PFAIL 0x1028UL 307 + #define PSYCHO_IMAP_KMS 0x1030UL 308 + #define PSYCHO_IMAP_FLPY 0x1038UL 309 + #define PSYCHO_IMAP_SHW 0x1040UL 310 + #define PSYCHO_IMAP_KBD 0x1048UL 311 + #define PSYCHO_IMAP_MS 0x1050UL 312 + #define PSYCHO_IMAP_SER 0x1058UL 313 + #define PSYCHO_IMAP_TIM0 0x1060UL 314 + #define PSYCHO_IMAP_TIM1 0x1068UL 315 + #define PSYCHO_IMAP_UE 0x1070UL 316 + #define PSYCHO_IMAP_CE 0x1078UL 317 + #define PSYCHO_IMAP_A_ERR 0x1080UL 318 + #define PSYCHO_IMAP_B_ERR 0x1088UL 319 + #define PSYCHO_IMAP_PMGMT 0x1090UL 320 + #define PSYCHO_IMAP_GFX 0x1098UL 321 + #define PSYCHO_IMAP_EUPA 0x10a0UL 322 + 323 + static unsigned long __psycho_onboard_imap_off[] = { 324 + /*0x20*/ PSYCHO_IMAP_SCSI, 325 + /*0x21*/ PSYCHO_IMAP_ETH, 326 + /*0x22*/ PSYCHO_IMAP_BPP, 327 + /*0x23*/ PSYCHO_IMAP_AU_REC, 328 + /*0x24*/ PSYCHO_IMAP_AU_PLAY, 329 + /*0x25*/ PSYCHO_IMAP_PFAIL, 330 + /*0x26*/ PSYCHO_IMAP_KMS, 331 + /*0x27*/ PSYCHO_IMAP_FLPY, 332 + /*0x28*/ PSYCHO_IMAP_SHW, 333 + /*0x29*/ PSYCHO_IMAP_KBD, 334 + /*0x2a*/ PSYCHO_IMAP_MS, 335 + /*0x2b*/ PSYCHO_IMAP_SER, 336 + /*0x2c*/ PSYCHO_IMAP_TIM0, 337 + /*0x2d*/ PSYCHO_IMAP_TIM1, 338 + /*0x2e*/ PSYCHO_IMAP_UE, 339 + /*0x2f*/ PSYCHO_IMAP_CE, 340 + /*0x30*/ PSYCHO_IMAP_A_ERR, 341 + /*0x31*/ PSYCHO_IMAP_B_ERR, 342 + /*0x32*/ PSYCHO_IMAP_PMGMT 343 + }; 344 + #define PSYCHO_ONBOARD_IRQ_BASE 0x20 345 + #define PSYCHO_ONBOARD_IRQ_LAST 0x32 346 + #define psycho_onboard_imap_offset(__ino) \ 347 + __psycho_onboard_imap_off[(__ino) - PSYCHO_ONBOARD_IRQ_BASE] 348 + 349 + #define PSYCHO_ICLR_A_SLOT0 0x1400UL 350 + #define PSYCHO_ICLR_SCSI 0x1800UL 351 + 352 + #define psycho_iclr_offset(ino) \ 353 + ((ino & 0x20) ? (PSYCHO_ICLR_SCSI + (((ino) & 0x1f) << 3)) : \ 354 + (PSYCHO_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3))) 355 + 356 + static unsigned int psycho_irq_build(struct device_node *dp, 357 + unsigned int ino, 358 + void *_data) 359 + { 360 + unsigned long controller_regs = (unsigned long) _data; 361 + unsigned long imap, iclr; 362 + unsigned long imap_off, iclr_off; 363 + int inofixup = 0; 364 + 365 + ino &= 0x3f; 366 + if (ino < PSYCHO_ONBOARD_IRQ_BASE) { 367 + /* PCI slot */ 368 + imap_off = psycho_pcislot_imap_offset(ino); 369 + } else { 370 + /* Onboard device */ 371 + if (ino > PSYCHO_ONBOARD_IRQ_LAST) { 372 + prom_printf("psycho_irq_build: Wacky INO [%x]\n", ino); 373 + prom_halt(); 374 + } 375 + imap_off = psycho_onboard_imap_offset(ino); 376 + } 377 + 378 + /* Now build the IRQ bucket. */ 379 + imap = controller_regs + imap_off; 380 + imap += 4; 381 + 382 + iclr_off = psycho_iclr_offset(ino); 383 + iclr = controller_regs + iclr_off; 384 + iclr += 4; 385 + 386 + if ((ino & 0x20) == 0) 387 + inofixup = ino & 0x03; 388 + 389 + return build_irq(inofixup, iclr, imap); 390 + } 391 + 392 + static void psycho_irq_trans_init(struct device_node *dp) 393 + { 394 + struct linux_prom64_registers *regs; 395 + 396 + dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller)); 397 + dp->irq_trans->irq_build = psycho_irq_build; 398 + 399 + regs = of_get_property(dp, "reg", NULL); 400 + dp->irq_trans->data = (void *) regs[2].phys_addr; 401 + } 402 + 403 + #define sabre_read(__reg) \ 404 + ({ u64 __ret; \ 405 + __asm__ __volatile__("ldxa [%1] %2, %0" \ 406 + : "=r" (__ret) \ 407 + : "r" (__reg), "i" (ASI_PHYS_BYPASS_EC_E) \ 408 + : "memory"); \ 409 + __ret; \ 410 + }) 411 + 412 + struct sabre_irq_data { 413 + unsigned long controller_regs; 414 + unsigned int pci_first_busno; 415 + }; 416 + #define SABRE_CONFIGSPACE 0x001000000UL 417 + #define SABRE_WRSYNC 0x1c20UL 418 + 419 + #define SABRE_CONFIG_BASE(CONFIG_SPACE) \ 420 + (CONFIG_SPACE | (1UL << 24)) 421 + #define SABRE_CONFIG_ENCODE(BUS, DEVFN, REG) \ 422 + (((unsigned long)(BUS) << 16) | \ 423 + ((unsigned long)(DEVFN) << 8) | \ 424 + ((unsigned long)(REG))) 425 + 426 + /* When a device lives behind a bridge deeper in the PCI bus topology 427 + * than APB, a special sequence must run to make sure all pending DMA 428 + * transfers at the time of IRQ delivery are visible in the coherency 429 + * domain by the cpu. This sequence is to perform a read on the far 430 + * side of the non-APB bridge, then perform a read of Sabre's DMA 431 + * write-sync register. 432 + */ 433 + static void sabre_wsync_handler(unsigned int ino, void *_arg1, void *_arg2) 434 + { 435 + unsigned int phys_hi = (unsigned int) (unsigned long) _arg1; 436 + struct sabre_irq_data *irq_data = _arg2; 437 + unsigned long controller_regs = irq_data->controller_regs; 438 + unsigned long sync_reg = controller_regs + SABRE_WRSYNC; 439 + unsigned long config_space = controller_regs + SABRE_CONFIGSPACE; 440 + unsigned int bus, devfn; 441 + u16 _unused; 442 + 443 + config_space = SABRE_CONFIG_BASE(config_space); 444 + 445 + bus = (phys_hi >> 16) & 0xff; 446 + devfn = (phys_hi >> 8) & 0xff; 447 + 448 + config_space |= SABRE_CONFIG_ENCODE(bus, devfn, 0x00); 449 + 450 + __asm__ __volatile__("membar #Sync\n\t" 451 + "lduha [%1] %2, %0\n\t" 452 + "membar #Sync" 453 + : "=r" (_unused) 454 + : "r" ((u16 *) config_space), 455 + "i" (ASI_PHYS_BYPASS_EC_E_L) 456 + : "memory"); 457 + 458 + sabre_read(sync_reg); 459 + } 460 + 461 + #define SABRE_IMAP_A_SLOT0 0x0c00UL 462 + #define SABRE_IMAP_B_SLOT0 0x0c20UL 463 + #define SABRE_IMAP_SCSI 0x1000UL 464 + #define SABRE_IMAP_ETH 0x1008UL 465 + #define SABRE_IMAP_BPP 0x1010UL 466 + #define SABRE_IMAP_AU_REC 0x1018UL 467 + #define SABRE_IMAP_AU_PLAY 0x1020UL 468 + #define SABRE_IMAP_PFAIL 0x1028UL 469 + #define SABRE_IMAP_KMS 0x1030UL 470 + #define SABRE_IMAP_FLPY 0x1038UL 471 + #define SABRE_IMAP_SHW 0x1040UL 472 + #define SABRE_IMAP_KBD 0x1048UL 473 + #define SABRE_IMAP_MS 0x1050UL 474 + #define SABRE_IMAP_SER 0x1058UL 475 + #define SABRE_IMAP_UE 0x1070UL 476 + #define SABRE_IMAP_CE 0x1078UL 477 + #define SABRE_IMAP_PCIERR 0x1080UL 478 + #define SABRE_IMAP_GFX 0x1098UL 479 + #define SABRE_IMAP_EUPA 0x10a0UL 480 + #define SABRE_ICLR_A_SLOT0 0x1400UL 481 + #define SABRE_ICLR_B_SLOT0 0x1480UL 482 + #define SABRE_ICLR_SCSI 0x1800UL 483 + #define SABRE_ICLR_ETH 0x1808UL 484 + #define SABRE_ICLR_BPP 0x1810UL 485 + #define SABRE_ICLR_AU_REC 0x1818UL 486 + #define SABRE_ICLR_AU_PLAY 0x1820UL 487 + #define SABRE_ICLR_PFAIL 0x1828UL 488 + #define SABRE_ICLR_KMS 0x1830UL 489 + #define SABRE_ICLR_FLPY 0x1838UL 490 + #define SABRE_ICLR_SHW 0x1840UL 491 + #define SABRE_ICLR_KBD 0x1848UL 492 + #define SABRE_ICLR_MS 0x1850UL 493 + #define SABRE_ICLR_SER 0x1858UL 494 + #define SABRE_ICLR_UE 0x1870UL 495 + #define SABRE_ICLR_CE 0x1878UL 496 + #define SABRE_ICLR_PCIERR 0x1880UL 497 + 498 + static unsigned long sabre_pcislot_imap_offset(unsigned long ino) 499 + { 500 + unsigned int bus = (ino & 0x10) >> 4; 501 + unsigned int slot = (ino & 0x0c) >> 2; 502 + 503 + if (bus == 0) 504 + return SABRE_IMAP_A_SLOT0 + (slot * 8); 505 + else 506 + return SABRE_IMAP_B_SLOT0 + (slot * 8); 507 + } 508 + 509 + static unsigned long __sabre_onboard_imap_off[] = { 510 + /*0x20*/ SABRE_IMAP_SCSI, 511 + /*0x21*/ SABRE_IMAP_ETH, 512 + /*0x22*/ SABRE_IMAP_BPP, 513 + /*0x23*/ SABRE_IMAP_AU_REC, 514 + /*0x24*/ SABRE_IMAP_AU_PLAY, 515 + /*0x25*/ SABRE_IMAP_PFAIL, 516 + /*0x26*/ SABRE_IMAP_KMS, 517 + /*0x27*/ SABRE_IMAP_FLPY, 518 + /*0x28*/ SABRE_IMAP_SHW, 519 + /*0x29*/ SABRE_IMAP_KBD, 520 + /*0x2a*/ SABRE_IMAP_MS, 521 + /*0x2b*/ SABRE_IMAP_SER, 522 + /*0x2c*/ 0 /* reserved */, 523 + /*0x2d*/ 0 /* reserved */, 524 + /*0x2e*/ SABRE_IMAP_UE, 525 + /*0x2f*/ SABRE_IMAP_CE, 526 + /*0x30*/ SABRE_IMAP_PCIERR, 527 + }; 528 + #define SABRE_ONBOARD_IRQ_BASE 0x20 529 + #define SABRE_ONBOARD_IRQ_LAST 0x30 530 + #define sabre_onboard_imap_offset(__ino) \ 531 + __sabre_onboard_imap_off[(__ino) - SABRE_ONBOARD_IRQ_BASE] 532 + 533 + #define sabre_iclr_offset(ino) \ 534 + ((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) : \ 535 + (SABRE_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3))) 536 + 537 + static unsigned int sabre_irq_build(struct device_node *dp, 538 + unsigned int ino, 539 + void *_data) 540 + { 541 + struct sabre_irq_data *irq_data = _data; 542 + unsigned long controller_regs = irq_data->controller_regs; 543 + struct linux_prom_pci_registers *regs; 544 + unsigned long imap, iclr; 545 + unsigned long imap_off, iclr_off; 546 + int inofixup = 0; 547 + int virt_irq; 548 + 549 + ino &= 0x3f; 550 + if (ino < SABRE_ONBOARD_IRQ_BASE) { 551 + /* PCI slot */ 552 + imap_off = sabre_pcislot_imap_offset(ino); 553 + } else { 554 + /* onboard device */ 555 + if (ino > SABRE_ONBOARD_IRQ_LAST) { 556 + prom_printf("sabre_irq_build: Wacky INO [%x]\n", ino); 557 + prom_halt(); 558 + } 559 + imap_off = sabre_onboard_imap_offset(ino); 560 + } 561 + 562 + /* Now build the IRQ bucket. */ 563 + imap = controller_regs + imap_off; 564 + imap += 4; 565 + 566 + iclr_off = sabre_iclr_offset(ino); 567 + iclr = controller_regs + iclr_off; 568 + iclr += 4; 569 + 570 + if ((ino & 0x20) == 0) 571 + inofixup = ino & 0x03; 572 + 573 + virt_irq = build_irq(inofixup, iclr, imap); 574 + 575 + regs = of_get_property(dp, "reg", NULL); 576 + if (regs && 577 + ((regs->phys_hi >> 16) & 0xff) != irq_data->pci_first_busno) { 578 + irq_install_pre_handler(virt_irq, 579 + sabre_wsync_handler, 580 + (void *) (long) regs->phys_hi, 581 + (void *) 582 + controller_regs + 583 + SABRE_WRSYNC); 584 + } 585 + 586 + return virt_irq; 587 + } 588 + 589 + static void sabre_irq_trans_init(struct device_node *dp) 590 + { 591 + struct linux_prom64_registers *regs; 592 + struct sabre_irq_data *irq_data; 593 + u32 *busrange; 594 + 595 + dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller)); 596 + dp->irq_trans->irq_build = sabre_irq_build; 597 + 598 + irq_data = prom_early_alloc(sizeof(struct sabre_irq_data)); 599 + 600 + regs = of_get_property(dp, "reg", NULL); 601 + irq_data->controller_regs = regs[0].phys_addr; 602 + 603 + busrange = of_get_property(dp, "bus-range", NULL); 604 + irq_data->pci_first_busno = busrange[0]; 605 + 606 + dp->irq_trans->data = irq_data; 607 + } 608 + 609 + /* SCHIZO interrupt mapping support. Unlike Psycho, for this controller the 610 + * imap/iclr registers are per-PBM. 611 + */ 612 + #define SCHIZO_IMAP_BASE 0x1000UL 613 + #define SCHIZO_ICLR_BASE 0x1400UL 614 + 615 + static unsigned long schizo_imap_offset(unsigned long ino) 616 + { 617 + return SCHIZO_IMAP_BASE + (ino * 8UL); 618 + } 619 + 620 + static unsigned long schizo_iclr_offset(unsigned long ino) 621 + { 622 + return SCHIZO_ICLR_BASE + (ino * 8UL); 623 + } 624 + 625 + static unsigned long schizo_ino_to_iclr(unsigned long pbm_regs, 626 + unsigned int ino) 627 + { 628 + return pbm_regs + schizo_iclr_offset(ino) + 4; 629 + } 630 + 631 + static unsigned long schizo_ino_to_imap(unsigned long pbm_regs, 632 + unsigned int ino) 633 + { 634 + return pbm_regs + schizo_imap_offset(ino) + 4; 635 + } 636 + 637 + #define schizo_read(__reg) \ 638 + ({ u64 __ret; \ 639 + __asm__ __volatile__("ldxa [%1] %2, %0" \ 640 + : "=r" (__ret) \ 641 + : "r" (__reg), "i" (ASI_PHYS_BYPASS_EC_E) \ 642 + : "memory"); \ 643 + __ret; \ 644 + }) 645 + #define schizo_write(__reg, __val) \ 646 + __asm__ __volatile__("stxa %0, [%1] %2" \ 647 + : /* no outputs */ \ 648 + : "r" (__val), "r" (__reg), \ 649 + "i" (ASI_PHYS_BYPASS_EC_E) \ 650 + : "memory") 651 + 652 + static void tomatillo_wsync_handler(unsigned int ino, void *_arg1, void *_arg2) 653 + { 654 + unsigned long sync_reg = (unsigned long) _arg2; 655 + u64 mask = 1UL << (ino & IMAP_INO); 656 + u64 val; 657 + int limit; 658 + 659 + schizo_write(sync_reg, mask); 660 + 661 + limit = 100000; 662 + val = 0; 663 + while (--limit) { 664 + val = schizo_read(sync_reg); 665 + if (!(val & mask)) 666 + break; 667 + } 668 + if (limit <= 0) { 669 + printk("tomatillo_wsync_handler: DMA won't sync [%lx:%lx]\n", 670 + val, mask); 671 + } 672 + 673 + if (_arg1) { 674 + static unsigned char cacheline[64] 675 + __attribute__ ((aligned (64))); 676 + 677 + __asm__ __volatile__("rd %%fprs, %0\n\t" 678 + "or %0, %4, %1\n\t" 679 + "wr %1, 0x0, %%fprs\n\t" 680 + "stda %%f0, [%5] %6\n\t" 681 + "wr %0, 0x0, %%fprs\n\t" 682 + "membar #Sync" 683 + : "=&r" (mask), "=&r" (val) 684 + : "0" (mask), "1" (val), 685 + "i" (FPRS_FEF), "r" (&cacheline[0]), 686 + "i" (ASI_BLK_COMMIT_P)); 687 + } 688 + } 689 + 690 + struct schizo_irq_data { 691 + unsigned long pbm_regs; 692 + unsigned long sync_reg; 693 + u32 portid; 694 + int chip_version; 695 + }; 696 + 697 + static unsigned int schizo_irq_build(struct device_node *dp, 698 + unsigned int ino, 699 + void *_data) 700 + { 701 + struct schizo_irq_data *irq_data = _data; 702 + unsigned long pbm_regs = irq_data->pbm_regs; 703 + unsigned long imap, iclr; 704 + int ign_fixup; 705 + int virt_irq; 706 + int is_tomatillo; 707 + 708 + ino &= 0x3f; 709 + 710 + /* Now build the IRQ bucket. */ 711 + imap = schizo_ino_to_imap(pbm_regs, ino); 712 + iclr = schizo_ino_to_iclr(pbm_regs, ino); 713 + 714 + /* On Schizo, no inofixup occurs. This is because each 715 + * INO has it's own IMAP register. On Psycho and Sabre 716 + * there is only one IMAP register for each PCI slot even 717 + * though four different INOs can be generated by each 718 + * PCI slot. 719 + * 720 + * But, for JBUS variants (essentially, Tomatillo), we have 721 + * to fixup the lowest bit of the interrupt group number. 722 + */ 723 + ign_fixup = 0; 724 + 725 + is_tomatillo = (irq_data->sync_reg != 0UL); 726 + 727 + if (is_tomatillo) { 728 + if (irq_data->portid & 1) 729 + ign_fixup = (1 << 6); 730 + } 731 + 732 + virt_irq = build_irq(ign_fixup, iclr, imap); 733 + 734 + if (is_tomatillo) { 735 + irq_install_pre_handler(virt_irq, 736 + tomatillo_wsync_handler, 737 + ((irq_data->chip_version <= 4) ? 738 + (void *) 1 : (void *) 0), 739 + (void *) irq_data->sync_reg); 740 + } 741 + 742 + return virt_irq; 743 + } 744 + 745 + static void schizo_irq_trans_init(struct device_node *dp) 746 + { 747 + struct linux_prom64_registers *regs; 748 + struct schizo_irq_data *irq_data; 749 + 750 + dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller)); 751 + dp->irq_trans->irq_build = schizo_irq_build; 752 + 753 + irq_data = prom_early_alloc(sizeof(struct schizo_irq_data)); 754 + 755 + regs = of_get_property(dp, "reg", NULL); 756 + dp->irq_trans->data = irq_data; 757 + 758 + irq_data->pbm_regs = regs[0].phys_addr; 759 + irq_data->sync_reg = regs[3].phys_addr + 0x1a18UL; 760 + irq_data->portid = of_getintprop_default(dp, "portid", 0); 761 + irq_data->chip_version = of_getintprop_default(dp, "version#", 0); 762 + } 763 + 764 + static unsigned int pci_sun4v_irq_build(struct device_node *dp, 765 + unsigned int devino, 766 + void *_data) 767 + { 768 + u32 devhandle = (u32) (unsigned long) _data; 769 + 770 + return sun4v_build_irq(devhandle, devino); 771 + } 772 + 773 + static void pci_sun4v_irq_trans_init(struct device_node *dp) 774 + { 775 + struct linux_prom64_registers *regs; 776 + 777 + dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller)); 778 + dp->irq_trans->irq_build = pci_sun4v_irq_build; 779 + 780 + regs = of_get_property(dp, "reg", NULL); 781 + dp->irq_trans->data = (void *) (unsigned long) 782 + ((regs->phys_addr >> 32UL) & 0x0fffffff); 783 + } 784 + #endif /* CONFIG_PCI */ 785 + 786 + #ifdef CONFIG_SBUS 787 + /* INO number to IMAP register offset for SYSIO external IRQ's. 788 + * This should conform to both Sunfire/Wildfire server and Fusion 789 + * desktop designs. 790 + */ 791 + #define SYSIO_IMAP_SLOT0 0x2c04UL 792 + #define SYSIO_IMAP_SLOT1 0x2c0cUL 793 + #define SYSIO_IMAP_SLOT2 0x2c14UL 794 + #define SYSIO_IMAP_SLOT3 0x2c1cUL 795 + #define SYSIO_IMAP_SCSI 0x3004UL 796 + #define SYSIO_IMAP_ETH 0x300cUL 797 + #define SYSIO_IMAP_BPP 0x3014UL 798 + #define SYSIO_IMAP_AUDIO 0x301cUL 799 + #define SYSIO_IMAP_PFAIL 0x3024UL 800 + #define SYSIO_IMAP_KMS 0x302cUL 801 + #define SYSIO_IMAP_FLPY 0x3034UL 802 + #define SYSIO_IMAP_SHW 0x303cUL 803 + #define SYSIO_IMAP_KBD 0x3044UL 804 + #define SYSIO_IMAP_MS 0x304cUL 805 + #define SYSIO_IMAP_SER 0x3054UL 806 + #define SYSIO_IMAP_TIM0 0x3064UL 807 + #define SYSIO_IMAP_TIM1 0x306cUL 808 + #define SYSIO_IMAP_UE 0x3074UL 809 + #define SYSIO_IMAP_CE 0x307cUL 810 + #define SYSIO_IMAP_SBERR 0x3084UL 811 + #define SYSIO_IMAP_PMGMT 0x308cUL 812 + #define SYSIO_IMAP_GFX 0x3094UL 813 + #define SYSIO_IMAP_EUPA 0x309cUL 814 + 815 + #define bogon ((unsigned long) -1) 816 + static unsigned long sysio_irq_offsets[] = { 817 + /* SBUS Slot 0 --> 3, level 1 --> 7 */ 818 + SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, 819 + SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, SYSIO_IMAP_SLOT0, 820 + SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, 821 + SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, SYSIO_IMAP_SLOT1, 822 + SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, 823 + SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, SYSIO_IMAP_SLOT2, 824 + SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, 825 + SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, SYSIO_IMAP_SLOT3, 826 + 827 + /* Onboard devices (not relevant/used on SunFire). */ 828 + SYSIO_IMAP_SCSI, 829 + SYSIO_IMAP_ETH, 830 + SYSIO_IMAP_BPP, 831 + bogon, 832 + SYSIO_IMAP_AUDIO, 833 + SYSIO_IMAP_PFAIL, 834 + bogon, 835 + bogon, 836 + SYSIO_IMAP_KMS, 837 + SYSIO_IMAP_FLPY, 838 + SYSIO_IMAP_SHW, 839 + SYSIO_IMAP_KBD, 840 + SYSIO_IMAP_MS, 841 + SYSIO_IMAP_SER, 842 + bogon, 843 + bogon, 844 + SYSIO_IMAP_TIM0, 845 + SYSIO_IMAP_TIM1, 846 + bogon, 847 + bogon, 848 + SYSIO_IMAP_UE, 849 + SYSIO_IMAP_CE, 850 + SYSIO_IMAP_SBERR, 851 + SYSIO_IMAP_PMGMT, 852 + }; 853 + 854 + #undef bogon 855 + 856 + #define NUM_SYSIO_OFFSETS ARRAY_SIZE(sysio_irq_offsets) 857 + 858 + /* Convert Interrupt Mapping register pointer to associated 859 + * Interrupt Clear register pointer, SYSIO specific version. 860 + */ 861 + #define SYSIO_ICLR_UNUSED0 0x3400UL 862 + #define SYSIO_ICLR_SLOT0 0x340cUL 863 + #define SYSIO_ICLR_SLOT1 0x344cUL 864 + #define SYSIO_ICLR_SLOT2 0x348cUL 865 + #define SYSIO_ICLR_SLOT3 0x34ccUL 866 + static unsigned long sysio_imap_to_iclr(unsigned long imap) 867 + { 868 + unsigned long diff = SYSIO_ICLR_UNUSED0 - SYSIO_IMAP_SLOT0; 869 + return imap + diff; 870 + } 871 + 872 + static unsigned int sbus_of_build_irq(struct device_node *dp, 873 + unsigned int ino, 874 + void *_data) 875 + { 876 + unsigned long reg_base = (unsigned long) _data; 877 + struct linux_prom_registers *regs; 878 + unsigned long imap, iclr; 879 + int sbus_slot = 0; 880 + int sbus_level = 0; 881 + 882 + ino &= 0x3f; 883 + 884 + regs = of_get_property(dp, "reg", NULL); 885 + if (regs) 886 + sbus_slot = regs->which_io; 887 + 888 + if (ino < 0x20) 889 + ino += (sbus_slot * 8); 890 + 891 + imap = sysio_irq_offsets[ino]; 892 + if (imap == ((unsigned long)-1)) { 893 + prom_printf("get_irq_translations: Bad SYSIO INO[%x]\n", 894 + ino); 895 + prom_halt(); 896 + } 897 + imap += reg_base; 898 + 899 + /* SYSIO inconsistency. For external SLOTS, we have to select 900 + * the right ICLR register based upon the lower SBUS irq level 901 + * bits. 902 + */ 903 + if (ino >= 0x20) { 904 + iclr = sysio_imap_to_iclr(imap); 905 + } else { 906 + sbus_level = ino & 0x7; 907 + 908 + switch(sbus_slot) { 909 + case 0: 910 + iclr = reg_base + SYSIO_ICLR_SLOT0; 911 + break; 912 + case 1: 913 + iclr = reg_base + SYSIO_ICLR_SLOT1; 914 + break; 915 + case 2: 916 + iclr = reg_base + SYSIO_ICLR_SLOT2; 917 + break; 918 + default: 919 + case 3: 920 + iclr = reg_base + SYSIO_ICLR_SLOT3; 921 + break; 922 + }; 923 + 924 + iclr += ((unsigned long)sbus_level - 1UL) * 8UL; 925 + } 926 + return build_irq(sbus_level, iclr, imap); 927 + } 928 + 929 + static void sbus_irq_trans_init(struct device_node *dp) 930 + { 931 + struct linux_prom64_registers *regs; 932 + 933 + dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller)); 934 + dp->irq_trans->irq_build = sbus_of_build_irq; 935 + 936 + regs = of_get_property(dp, "reg", NULL); 937 + dp->irq_trans->data = (void *) (unsigned long) regs->phys_addr; 938 + } 939 + #endif /* CONFIG_SBUS */ 940 + 941 + 942 + static unsigned int central_build_irq(struct device_node *dp, 943 + unsigned int ino, 944 + void *_data) 945 + { 946 + struct device_node *central_dp = _data; 947 + struct of_device *central_op = of_find_device_by_node(central_dp); 948 + struct resource *res; 949 + unsigned long imap, iclr; 950 + u32 tmp; 951 + 952 + if (!strcmp(dp->name, "eeprom")) { 953 + res = &central_op->resource[5]; 954 + } else if (!strcmp(dp->name, "zs")) { 955 + res = &central_op->resource[4]; 956 + } else if (!strcmp(dp->name, "clock-board")) { 957 + res = &central_op->resource[3]; 958 + } else { 959 + return ino; 960 + } 961 + 962 + imap = res->start + 0x00UL; 963 + iclr = res->start + 0x10UL; 964 + 965 + /* Set the INO state to idle, and disable. */ 966 + upa_writel(0, iclr); 967 + upa_readl(iclr); 968 + 969 + tmp = upa_readl(imap); 970 + tmp &= ~0x80000000; 971 + upa_writel(tmp, imap); 972 + 973 + return build_irq(0, iclr, imap); 974 + } 975 + 976 + static void central_irq_trans_init(struct device_node *dp) 977 + { 978 + dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller)); 979 + dp->irq_trans->irq_build = central_build_irq; 980 + 981 + dp->irq_trans->data = dp; 982 + } 983 + 984 + struct irq_trans { 985 + const char *name; 986 + void (*init)(struct device_node *); 987 + }; 988 + 989 + #ifdef CONFIG_PCI 990 + static struct irq_trans pci_irq_trans_table[] = { 991 + { "SUNW,sabre", sabre_irq_trans_init }, 992 + { "pci108e,a000", sabre_irq_trans_init }, 993 + { "pci108e,a001", sabre_irq_trans_init }, 994 + { "SUNW,psycho", psycho_irq_trans_init }, 995 + { "pci108e,8000", psycho_irq_trans_init }, 996 + { "SUNW,schizo", schizo_irq_trans_init }, 997 + { "pci108e,8001", schizo_irq_trans_init }, 998 + { "SUNW,schizo+", schizo_irq_trans_init }, 999 + { "pci108e,8002", schizo_irq_trans_init }, 1000 + { "SUNW,tomatillo", schizo_irq_trans_init }, 1001 + { "pci108e,a801", schizo_irq_trans_init }, 1002 + { "SUNW,sun4v-pci", pci_sun4v_irq_trans_init }, 1003 + }; 1004 + #endif 1005 + 1006 + static void irq_trans_init(struct device_node *dp) 1007 + { 1008 + const char *model; 1009 + int i; 1010 + 1011 + model = of_get_property(dp, "model", NULL); 1012 + if (!model) 1013 + model = of_get_property(dp, "compatible", NULL); 1014 + if (!model) 1015 + return; 1016 + 1017 + #ifdef CONFIG_PCI 1018 + for (i = 0; i < ARRAY_SIZE(pci_irq_trans_table); i++) { 1019 + struct irq_trans *t = &pci_irq_trans_table[i]; 1020 + 1021 + if (!strcmp(model, t->name)) 1022 + return t->init(dp); 1023 + } 1024 + #endif 1025 + #ifdef CONFIG_SBUS 1026 + if (!strcmp(dp->name, "sbus") || 1027 + !strcmp(dp->name, "sbi")) 1028 + return sbus_irq_trans_init(dp); 1029 + #endif 1030 + if (!strcmp(dp->name, "central")) 1031 + return central_irq_trans_init(dp->child); 289 1032 } 290 1033 291 1034 static int is_root_node(const struct device_node *dp) ··· 1459 706 dp->type = get_one_property(node, "device_type"); 1460 707 dp->node = node; 1461 708 1462 - /* Build interrupts later... */ 1463 - 1464 709 dp->properties = build_prop_list(node); 710 + 711 + irq_trans_init(dp); 1465 712 1466 713 return dp; 1467 714 }
+4 -1
include/asm-sparc64/of_device.h
··· 22 22 struct device_node *node; 23 23 struct device dev; 24 24 struct resource resource[PROMREG_MAX]; 25 - unsigned int irq; 25 + unsigned int irqs[PROMINTR_MAX]; 26 + int num_irqs; 26 27 27 28 void *sysdata; 28 29 ··· 35 34 36 35 extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name); 37 36 extern void of_iounmap(void __iomem *base, unsigned long size); 37 + 38 + extern struct of_device *of_find_device_by_node(struct device_node *); 38 39 39 40 extern const struct of_device_id *of_match_device( 40 41 const struct of_device_id *matches, const struct of_device *dev);
+2 -1
include/asm-sparc64/pbm.h
··· 16 16 #include <asm/page.h> 17 17 #include <asm/oplib.h> 18 18 #include <asm/prom.h> 19 + #include <asm/of_device.h> 19 20 #include <asm/iommu.h> 20 21 21 22 /* The abstraction used here is that there are PCI controllers, ··· 210 209 211 210 /* Operations which are controller specific. */ 212 211 void (*scan_bus)(struct pci_controller_info *); 213 - unsigned int (*irq_build)(struct pci_pbm_info *, struct pci_dev *, unsigned int); 214 212 void (*base_address_update)(struct pci_dev *, int); 215 213 void (*resource_adjust)(struct pci_dev *, struct resource *, struct resource *); 216 214 ··· 226 226 struct pcidev_cookie { 227 227 struct pci_pbm_info *pbm; 228 228 struct device_node *prom_node; 229 + struct of_device *op; 229 230 struct linux_prom_pci_registers prom_regs[PROMREG_MAX]; 230 231 int num_prom_regs; 231 232 struct linux_prom_pci_registers prom_assignments[PROMREG_MAX];
+8
include/asm-sparc64/prom.h
··· 34 34 unsigned int unique_id; 35 35 }; 36 36 37 + struct of_irq_controller; 37 38 struct device_node { 38 39 char *name; 39 40 char *type; ··· 54 53 unsigned long _flags; 55 54 void *data; 56 55 unsigned int unique_id; 56 + 57 + struct of_irq_controller *irq_trans; 58 + }; 59 + 60 + struct of_irq_controller { 61 + unsigned int (*irq_build)(struct device_node *, unsigned int, void *); 62 + void *data; 57 63 }; 58 64 59 65 /* flag descriptions */