[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 #include <asm/pbm.h> 21 #include <asm/ebus.h> 22 #include <asm/oplib.h> 23 #include <asm/bpp.h> 24 #include <asm/irq.h> 25 ··· 281 return mem; 282 } 283 284 - int __init ebus_intmap_match(struct linux_ebus *ebus, 285 - struct linux_prom_registers *reg, 286 - int *interrupt) 287 { 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 - { 321 int *regs; 322 - int *irqs; 323 int i, len; 324 325 dev->prom_node = dp; ··· 323 } 324 } 325 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) { 331 dev->num_irqs = 0; 332 /* 333 * Oh, well, some PROMs don't export interrupts 334 * property to children of EBus devices... ··· 348 dev->irqs[0] = dev->parent->irqs[1]; 349 } 350 } 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 } 369 } 370 ··· 359 return 0; 360 } 361 362 - void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev) 363 { 364 - struct linux_prom_registers *regs; 365 struct linux_ebus_child *child; 366 - int *irqs; 367 - int i, n, len; 368 369 dev->prom_node = dp; 370 371 printk(" [%s", dp->name); 372 373 - regs = of_get_property(dp, "reg", &len); 374 - if (!regs) { 375 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 dev->num_irqs = 0; 411 } 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; 416 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 - } 428 } 429 430 dev->ofdev.node = dp; ··· 406 child->next = NULL; 407 child->parent = dev; 408 child->bus = dev->bus; 409 - fill_ebus_child(dp, regs, child, 410 child_regs_nonstandard(dev)); 411 412 while ((dp = dp->sibling) != NULL) { ··· 416 child->next = NULL; 417 child->parent = dev; 418 child->bus = dev->bus; 419 - fill_ebus_child(dp, regs, child, 420 child_regs_nonstandard(dev)); 421 } 422 }
··· 20 #include <asm/pbm.h> 21 #include <asm/ebus.h> 22 #include <asm/oplib.h> 23 + #include <asm/prom.h> 24 + #include <asm/of_device.h> 25 #include <asm/bpp.h> 26 #include <asm/irq.h> 27 ··· 279 return mem; 280 } 281 282 + static void __init fill_ebus_child(struct device_node *dp, 283 + struct linux_ebus_child *dev, 284 + int non_standard_regs) 285 { 286 + struct of_device *op; 287 int *regs; 288 int i, len; 289 290 dev->prom_node = dp; ··· 354 } 355 } 356 357 + op = of_find_device_by_node(dp); 358 + if (!op) { 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) { 367 /* 368 * Oh, well, some PROMs don't export interrupts 369 * property to children of EBus devices... ··· 375 dev->irqs[0] = dev->parent->irqs[1]; 376 } 377 } 378 } 379 } 380 ··· 403 return 0; 404 } 405 406 + static void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev) 407 { 408 struct linux_ebus_child *child; 409 + struct of_device *op; 410 + int i, len; 411 412 dev->prom_node = dp; 413 414 printk(" [%s", dp->name); 415 416 + op = of_find_device_by_node(dp); 417 + if (!op) { 418 dev->num_addrs = 0; 419 dev->num_irqs = 0; 420 } else { 421 + (void) of_get_property(dp, "reg", &len); 422 + dev->num_addrs = len / sizeof(struct linux_prom_registers); 423 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]; 432 } 433 434 dev->ofdev.node = dp; ··· 490 child->next = NULL; 491 child->parent = dev; 492 child->bus = dev->bus; 493 + fill_ebus_child(dp, child, 494 child_regs_nonstandard(dev)); 495 496 while ((dp = dp->sibling) != NULL) { ··· 500 child->next = NULL; 501 child->parent = dev; 502 child->bus = dev->bus; 503 + fill_ebus_child(dp, child, 504 child_regs_nonstandard(dev)); 505 } 506 }
+6 -95
arch/sparc64/kernel/isa.c
··· 3 #include <linux/pci.h> 4 #include <linux/slab.h> 5 #include <asm/oplib.h> 6 #include <asm/isa.h> 7 8 struct sparc_isa_bridge *isa_chain; ··· 48 return pregs; 49 } 50 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 static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev, 108 struct linux_prom_registers *pregs) 109 { 110 - int irq_prop; 111 112 - irq_prop = of_getintprop_default(isa_dev->prom_node, 113 - "interrupts", -1); 114 - if (irq_prop <= 0) { 115 - goto no_irq; 116 } 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; 148 } 149 - 150 - no_irq: 151 - isa_dev->irq = PCI_IRQ_NONE; 152 } 153 154 static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
··· 3 #include <linux/pci.h> 4 #include <linux/slab.h> 5 #include <asm/oplib.h> 6 + #include <asm/prom.h> 7 + #include <asm/of_device.h> 8 #include <asm/isa.h> 9 10 struct sparc_isa_bridge *isa_chain; ··· 46 return pregs; 47 } 48 49 static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev, 50 struct linux_prom_registers *pregs) 51 { 52 + struct of_device *op = of_find_device_by_node(isa_dev->prom_node); 53 54 + if (!op || !op->num_irqs) { 55 + isa_dev->irq = PCI_IRQ_NONE; 56 } else { 57 + isa_dev->irq = op->irqs[0]; 58 } 59 } 60 61 static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
+188 -6
arch/sparc64/kernel/of_device.c
··· 146 } 147 EXPORT_SYMBOL(of_iounmap); 148 149 #ifdef CONFIG_PCI 150 struct bus_type isa_bus_type = { 151 .name = "isa", ··· 280 { 281 return IORESOURCE_MEM; 282 } 283 - 284 285 /* 286 * PCI bus specific translator ··· 613 } 614 } 615 616 static struct of_device * __init scan_one_device(struct device_node *dp, 617 struct device *parent) 618 { 619 struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL); 620 unsigned int *irq; 621 - int len; 622 623 if (!op) 624 return NULL; ··· 791 op->portid = of_getintprop_default(dp, "portid", -1); 792 793 irq = of_get_property(dp, "interrupts", &len); 794 - if (irq) 795 - op->irq = *irq; 796 - else 797 - op->irq = 0xffffffff; 798 799 build_device_resources(op, parent); 800 801 op->dev.parent = parent; 802 op->dev.bus = &of_bus_type;
··· 146 } 147 EXPORT_SYMBOL(of_iounmap); 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 + 169 #ifdef CONFIG_PCI 170 struct bus_type isa_bus_type = { 171 .name = "isa", ··· 260 { 261 return IORESOURCE_MEM; 262 } 263 264 /* 265 * PCI bus specific translator ··· 594 } 595 } 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 + 756 static struct of_device * __init scan_one_device(struct device_node *dp, 757 struct device *parent) 758 { 759 struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL); 760 unsigned int *irq; 761 + int len, i; 762 763 if (!op) 764 return NULL; ··· 613 op->portid = of_getintprop_default(dp, "portid", -1); 614 615 irq = of_get_property(dp, "interrupts", &len); 616 + if (irq) { 617 + memcpy(op->irqs, irq, len); 618 + op->num_irqs = len / 4; 619 + } else { 620 + op->num_irqs = 0; 621 + } 622 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]); 626 627 op->dev.parent = parent; 628 op->dev.bus = &of_bus_type;
-6
arch/sparc64/kernel/pci.c
··· 404 } 405 EXPORT_SYMBOL(pcibios_bus_to_resource); 406 407 - extern int pci_irq_verbose; 408 - 409 char * __init pcibios_setup(char *str) 410 { 411 - if (!strcmp(str, "irq_verbose")) { 412 - pci_irq_verbose = 1; 413 - return NULL; 414 - } 415 return str; 416 } 417
··· 404 } 405 EXPORT_SYMBOL(pcibios_bus_to_resource); 406 407 char * __init pcibios_setup(char *str) 408 { 409 return str; 410 } 411
+6 -285
arch/sparc64/kernel/pci_common.c
··· 10 11 #include <asm/pbm.h> 12 #include <asm/prom.h> 13 14 #include "pci_impl.h" 15 - 16 - /* Pass "pci=irq_verbose" on the kernel command line to enable this. */ 17 - int pci_irq_verbose; 18 19 /* Fix self device of BUS and hook it into BUS->self. 20 * The pci_scan_bus does not do this for the host bridge. ··· 167 } 168 pcp->pbm = pbm; 169 pcp->prom_node = dp; 170 memcpy(pcp->prom_regs, pregs, 171 nregs * sizeof(struct linux_prom_pci_registers)); 172 pcp->num_prom_regs = nregs; ··· 548 pci_assign_unassigned(pbm, bus); 549 } 550 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 static void __init pdev_fixup_irq(struct pci_dev *pdev) 740 { 741 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; 748 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; 760 return; 761 } 762 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; 769 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 pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 842 pdev->irq & PCI_IRQ_INO); 843 }
··· 10 11 #include <asm/pbm.h> 12 #include <asm/prom.h> 13 + #include <asm/of_device.h> 14 15 #include "pci_impl.h" 16 17 /* Fix self device of BUS and hook it into BUS->self. 18 * The pci_scan_bus does not do this for the host bridge. ··· 169 } 170 pcp->pbm = pbm; 171 pcp->prom_node = dp; 172 + pcp->op = of_find_device_by_node(dp); 173 memcpy(pcp->prom_regs, pregs, 174 nregs * sizeof(struct linux_prom_pci_registers)); 175 pcp->num_prom_regs = nregs; ··· 549 pci_assign_unassigned(pbm, bus); 550 } 551 552 static void __init pdev_fixup_irq(struct pci_dev *pdev) 553 { 554 struct pcidev_cookie *pcp = pdev->sysdata; 555 + struct of_device *op = pcp->op; 556 557 + if (op->irqs[0] == 0xffffffff) { 558 + pdev->irq = PCI_IRQ_NONE; 559 return; 560 } 561 562 + pdev->irq = op->irqs[0]; 563 564 pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 565 pdev->irq & PCI_IRQ_INO); 566 }
+20 -141
arch/sparc64/kernel/pci_psycho.c
··· 18 #include <asm/irq.h> 19 #include <asm/starfire.h> 20 #include <asm/prom.h> 21 22 #include "pci_impl.h" 23 #include "iommu_common.h" ··· 208 .read = psycho_read_pci_cfg, 209 .write = psycho_write_pci_cfg, 210 }; 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 316 /* PSYCHO error handling support. */ 317 enum psycho_error_type { ··· 841 #define PSYCHO_ECCCTRL_EE 0x8000000000000000UL /* Enable ECC Checking */ 842 #define PSYCHO_ECCCTRL_UE 0x4000000000000000UL /* Enable UE Interrupts */ 843 #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 static void psycho_register_error_handlers(struct pci_controller_info *p) 849 { 850 struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ 851 unsigned long base = p->pbm_A.controller_regs; 852 - unsigned int irq, portid = pbm->portid; 853 u64 tmp; 854 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 - } 863 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 - } 871 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 - } 880 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 - } 889 890 /* Enable UE and CE interrupts for controller. */ 891 psycho_write(base + PSYCHO_ECC_CTRL, ··· 1286 p->index = pci_num_controllers++; 1287 p->pbms_same_domain = 0; 1288 p->scan_bus = psycho_scan_bus; 1289 - p->irq_build = psycho_irq_build; 1290 p->base_address_update = psycho_base_address_update; 1291 p->resource_adjust = psycho_resource_adjust; 1292 p->pci_ops = &psycho_ops;
··· 18 #include <asm/irq.h> 19 #include <asm/starfire.h> 20 #include <asm/prom.h> 21 + #include <asm/of_device.h> 22 23 #include "pci_impl.h" 24 #include "iommu_common.h" ··· 207 .read = psycho_read_pci_cfg, 208 .write = psycho_write_pci_cfg, 209 }; 210 211 /* PSYCHO error handling support. */ 212 enum psycho_error_type { ··· 944 #define PSYCHO_ECCCTRL_EE 0x8000000000000000UL /* Enable ECC Checking */ 945 #define PSYCHO_ECCCTRL_UE 0x4000000000000000UL /* Enable UE Interrupts */ 946 #define PSYCHO_ECCCTRL_CE 0x2000000000000000UL /* Enable CE INterrupts */ 947 static void psycho_register_error_handlers(struct pci_controller_info *p) 948 { 949 struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ 950 + struct of_device *op = of_find_device_by_node(pbm->prom_node); 951 unsigned long base = p->pbm_A.controller_regs; 952 u64 tmp; 953 954 + if (!op) 955 + return; 956 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 + */ 965 966 + if (op->num_irqs < 6) 967 + return; 968 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); 975 976 /* Enable UE and CE interrupts for controller. */ 977 psycho_write(base + PSYCHO_ECC_CTRL, ··· 1406 p->index = pci_num_controllers++; 1407 p->pbms_same_domain = 0; 1408 p->scan_bus = psycho_scan_bus; 1409 p->base_address_update = psycho_base_address_update; 1410 p->resource_adjust = psycho_resource_adjust; 1411 p->pci_ops = &psycho_ops;
+23 -135
arch/sparc64/kernel/pci_sabre.c
··· 485 .write = sabre_write_pci_cfg, 486 }; 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 /* SABRE error handling support. */ 597 static void sabre_check_iommu_error(struct pci_controller_info *p, 598 unsigned long afsr, ··· 821 return IRQ_HANDLED; 822 } 823 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 static void sabre_register_error_handlers(struct pci_controller_info *p) 829 { 830 struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ 831 unsigned long base = pbm->controller_regs; 832 - unsigned long irq, portid = pbm->portid; 833 u64 tmp; 834 835 /* We clear the error bits in the appropriate AFSR before 836 * registering the handler so that we don't get spurious ··· 853 (SABRE_UEAFSR_PDRD | SABRE_UEAFSR_PDWR | 854 SABRE_UEAFSR_SDRD | SABRE_UEAFSR_SDWR | 855 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 - } 863 864 sabre_write(base + SABRE_CE_AFSR, 865 (SABRE_CEAFSR_PDRD | SABRE_CEAFSR_PDWR | 866 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 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 - } 882 883 tmp = sabre_read(base + SABRE_PCICTRL); 884 tmp |= SABRE_PCICTRL_ERREN; ··· 1381 p->index = pci_num_controllers++; 1382 p->pbms_same_domain = 1; 1383 p->scan_bus = sabre_scan_bus; 1384 - p->irq_build = sabre_irq_build; 1385 p->base_address_update = sabre_base_address_update; 1386 p->resource_adjust = sabre_resource_adjust; 1387 p->pci_ops = &sabre_ops;
··· 485 .write = sabre_write_pci_cfg, 486 }; 487 488 /* SABRE error handling support. */ 489 static void sabre_check_iommu_error(struct pci_controller_info *p, 490 unsigned long afsr, ··· 929 return IRQ_HANDLED; 930 } 931 932 static void sabre_register_error_handlers(struct pci_controller_info *p) 933 { 934 struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ 935 + struct device_node *dp = pbm->prom_node; 936 + struct of_device *op; 937 unsigned long base = pbm->controller_regs; 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; 955 956 /* We clear the error bits in the appropriate AFSR before 957 * registering the handler so that we don't get spurious ··· 948 (SABRE_UEAFSR_PDRD | SABRE_UEAFSR_PDWR | 949 SABRE_UEAFSR_SDRD | SABRE_UEAFSR_SDWR | 950 SABRE_UEAFSR_SDTE | SABRE_UEAFSR_PDTE)); 951 + 952 + request_irq(op->irqs[1], sabre_ue_intr, SA_SHIRQ, "SABRE UE", p); 953 954 sabre_write(base + SABRE_CE_AFSR, 955 (SABRE_CEAFSR_PDRD | SABRE_CEAFSR_PDWR | 956 SABRE_CEAFSR_SDRD | SABRE_CEAFSR_SDWR)); 957 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); 961 962 tmp = sabre_read(base + SABRE_PCICTRL); 963 tmp |= SABRE_PCICTRL_ERREN; ··· 1492 p->index = pci_num_controllers++; 1493 p->pbms_same_domain = 1; 1494 p->scan_bus = sabre_scan_bus; 1495 p->base_address_update = sabre_base_address_update; 1496 p->resource_adjust = sabre_resource_adjust; 1497 p->pci_ops = &sabre_ops;
+60 -251
arch/sparc64/kernel/pci_schizo.c
··· 217 .write = schizo_write_pci_cfg, 218 }; 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 /* SCHIZO error handling support. */ 331 enum schizo_error_type { 332 UE_ERR, CE_ERR, PCI_ERR, SAFARI_ERR ··· 250 p->index); 251 252 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 } 282 283 #define SCHIZO_STC_ERR 0xb800UL /* --> 0xba00 */ ··· 582 /* Interrogate IOMMU for error status. */ 583 schizo_check_iommu_error(p, UE_ERR); 584 585 - schizo_clear_other_err_intr(p, irq); 586 - 587 return IRQ_HANDLED; 588 } 589 ··· 670 if (!reported) 671 printk("(none)"); 672 printk("]\n"); 673 - 674 - schizo_clear_other_err_intr(p, irq); 675 676 return IRQ_HANDLED; 677 } ··· 891 if (error_bits & (SCHIZO_PCIAFSR_PPERR | SCHIZO_PCIAFSR_SPERR)) 892 pci_scan_for_parity_error(p, pbm, pbm->pci_bus); 893 894 - schizo_clear_other_err_intr(p, irq); 895 - 896 return IRQ_HANDLED; 897 } 898 ··· 946 printk("PCI%d: Unexpected Safari/JBUS error interrupt, errlog[%016lx]\n", 947 p->index, errlog); 948 949 - schizo_clear_other_err_intr(p, irq); 950 return IRQ_HANDLED; 951 } 952 ··· 953 p->index); 954 schizo_check_iommu_error(p, SAFARI_ERR); 955 956 - schizo_clear_other_err_intr(p, irq); 957 return IRQ_HANDLED; 958 } 959 ··· 984 static void tomatillo_register_error_handlers(struct pci_controller_info *p) 985 { 986 struct pci_pbm_info *pbm; 987 - unsigned int irq; 988 u64 tmp, err_mask, err_no_mask; 989 990 - /* Build IRQs and register handlers. */ 991 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)); 1002 1003 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)); 1014 1015 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)); 1028 1029 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)); 1042 1043 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)); 1055 1056 /* Enable UE and CE interrupts for controller. */ 1057 schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL, ··· 1092 static void schizo_register_error_handlers(struct pci_controller_info *p) 1093 { 1094 struct pci_pbm_info *pbm; 1095 - unsigned int irq; 1096 u64 tmp, err_mask, err_no_mask; 1097 1098 - /* Build IRQs and register handlers. */ 1099 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)); 1109 1110 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)); 1120 1121 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)); 1131 1132 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)); 1142 1143 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)); 1153 1154 /* Enable UE and CE interrupts for controller. */ 1155 schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL, ··· 1832 p->scan_bus = (chip_type == PBM_CHIP_TYPE_TOMATILLO ? 1833 tomatillo_scan_bus : 1834 schizo_scan_bus); 1835 - p->irq_build = schizo_irq_build; 1836 p->base_address_update = schizo_base_address_update; 1837 p->resource_adjust = schizo_resource_adjust; 1838 p->pci_ops = &schizo_ops;
··· 217 .write = schizo_write_pci_cfg, 218 }; 219 220 /* SCHIZO error handling support. */ 221 enum schizo_error_type { 222 UE_ERR, CE_ERR, PCI_ERR, SAFARI_ERR ··· 360 p->index); 361 362 return &p->pbm_A; 363 } 364 365 #define SCHIZO_STC_ERR 0xb800UL /* --> 0xba00 */ ··· 720 /* Interrogate IOMMU for error status. */ 721 schizo_check_iommu_error(p, UE_ERR); 722 723 return IRQ_HANDLED; 724 } 725 ··· 810 if (!reported) 811 printk("(none)"); 812 printk("]\n"); 813 814 return IRQ_HANDLED; 815 } ··· 1033 if (error_bits & (SCHIZO_PCIAFSR_PPERR | SCHIZO_PCIAFSR_SPERR)) 1034 pci_scan_for_parity_error(p, pbm, pbm->pci_bus); 1035 1036 return IRQ_HANDLED; 1037 } 1038 ··· 1090 printk("PCI%d: Unexpected Safari/JBUS error interrupt, errlog[%016lx]\n", 1091 p->index, errlog); 1092 1093 return IRQ_HANDLED; 1094 } 1095 ··· 1098 p->index); 1099 schizo_check_iommu_error(p, SAFARI_ERR); 1100 1101 return IRQ_HANDLED; 1102 } 1103 ··· 1130 static void tomatillo_register_error_handlers(struct pci_controller_info *p) 1131 { 1132 struct pci_pbm_info *pbm; 1133 + struct of_device *op; 1134 u64 tmp, err_mask, err_no_mask; 1135 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 + 1144 pbm = pbm_for_ino(p, SCHIZO_UE_INO); 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); 1149 1150 pbm = pbm_for_ino(p, SCHIZO_CE_INO); 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); 1155 1156 pbm = pbm_for_ino(p, SCHIZO_PCIERR_A_INO); 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 + 1162 1163 pbm = pbm_for_ino(p, SCHIZO_PCIERR_B_INO); 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); 1168 1169 pbm = pbm_for_ino(p, SCHIZO_SERR_INO); 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); 1174 1175 /* Enable UE and CE interrupts for controller. */ 1176 schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL, ··· 1265 static void schizo_register_error_handlers(struct pci_controller_info *p) 1266 { 1267 struct pci_pbm_info *pbm; 1268 + struct of_device *op; 1269 u64 tmp, err_mask, err_no_mask; 1270 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 + 1279 pbm = pbm_for_ino(p, SCHIZO_UE_INO); 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); 1284 1285 pbm = pbm_for_ino(p, SCHIZO_CE_INO); 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); 1290 1291 pbm = pbm_for_ino(p, SCHIZO_PCIERR_A_INO); 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 + 1297 1298 pbm = pbm_for_ino(p, SCHIZO_PCIERR_B_INO); 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); 1303 1304 pbm = pbm_for_ino(p, SCHIZO_SERR_INO); 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); 1309 1310 /* Enable UE and CE interrupts for controller. */ 1311 schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL, ··· 2022 p->scan_bus = (chip_type == PBM_CHIP_TYPE_TOMATILLO ? 2023 tomatillo_scan_bus : 2024 schizo_scan_bus); 2025 p->base_address_update = schizo_base_address_update; 2026 p->resource_adjust = schizo_resource_adjust; 2027 p->pci_ops = &schizo_ops;
-10
arch/sparc64/kernel/pci_sun4v.c
··· 843 /* XXX register error interrupt handlers XXX */ 844 } 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 static void pci_sun4v_base_address_update(struct pci_dev *pdev, int resource) 856 { 857 struct pcidev_cookie *pcp = pdev->sysdata; ··· 1191 p->pbms_same_domain = 0; 1192 1193 p->scan_bus = pci_sun4v_scan_bus; 1194 - p->irq_build = pci_sun4v_irq_build; 1195 p->base_address_update = pci_sun4v_base_address_update; 1196 p->resource_adjust = pci_sun4v_resource_adjust; 1197 p->pci_ops = &pci_sun4v_ops;
··· 843 /* XXX register error interrupt handlers XXX */ 844 } 845 846 static void pci_sun4v_base_address_update(struct pci_dev *pdev, int resource) 847 { 848 struct pcidev_cookie *pcp = pdev->sysdata; ··· 1200 p->pbms_same_domain = 0; 1201 1202 p->scan_bus = pci_sun4v_scan_bus; 1203 p->base_address_update = pci_sun4v_base_address_update; 1204 p->resource_adjust = pci_sun4v_resource_adjust; 1205 p->pci_ops = &pci_sun4v_ops;
+755 -2
arch/sparc64/kernel/prom.c
··· 15 * 2 of the License, or (at your option) any later version. 16 */ 17 18 #include <linux/kernel.h> 19 #include <linux/types.h> 20 #include <linux/string.h> ··· 24 #include <linux/module.h> 25 26 #include <asm/prom.h> 27 #include <asm/oplib.h> 28 29 static struct device_node *allnodes; 30 ··· 286 prom_early_allocated += size; 287 288 return ret; 289 } 290 291 static int is_root_node(const struct device_node *dp) ··· 1459 dp->type = get_one_property(node, "device_type"); 1460 dp->node = node; 1461 1462 - /* Build interrupts later... */ 1463 - 1464 dp->properties = build_prop_list(node); 1465 1466 return dp; 1467 }
··· 15 * 2 of the License, or (at your option) any later version. 16 */ 17 18 + #include <linux/config.h> 19 #include <linux/kernel.h> 20 #include <linux/types.h> 21 #include <linux/string.h> ··· 23 #include <linux/module.h> 24 25 #include <asm/prom.h> 26 + #include <asm/of_device.h> 27 #include <asm/oplib.h> 28 + #include <asm/irq.h> 29 + #include <asm/asi.h> 30 + #include <asm/upa.h> 31 32 static struct device_node *allnodes; 33 ··· 281 prom_early_allocated += size; 282 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); 1032 } 1033 1034 static int is_root_node(const struct device_node *dp) ··· 706 dp->type = get_one_property(node, "device_type"); 707 dp->node = node; 708 709 dp->properties = build_prop_list(node); 710 + 711 + irq_trans_init(dp); 712 713 return dp; 714 }
+4 -1
include/asm-sparc64/of_device.h
··· 22 struct device_node *node; 23 struct device dev; 24 struct resource resource[PROMREG_MAX]; 25 - unsigned int irq; 26 27 void *sysdata; 28 ··· 35 36 extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name); 37 extern void of_iounmap(void __iomem *base, unsigned long size); 38 39 extern const struct of_device_id *of_match_device( 40 const struct of_device_id *matches, const struct of_device *dev);
··· 22 struct device_node *node; 23 struct device dev; 24 struct resource resource[PROMREG_MAX]; 25 + unsigned int irqs[PROMINTR_MAX]; 26 + int num_irqs; 27 28 void *sysdata; 29 ··· 34 35 extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name); 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 *); 39 40 extern const struct of_device_id *of_match_device( 41 const struct of_device_id *matches, const struct of_device *dev);
+2 -1
include/asm-sparc64/pbm.h
··· 16 #include <asm/page.h> 17 #include <asm/oplib.h> 18 #include <asm/prom.h> 19 #include <asm/iommu.h> 20 21 /* The abstraction used here is that there are PCI controllers, ··· 210 211 /* Operations which are controller specific. */ 212 void (*scan_bus)(struct pci_controller_info *); 213 - unsigned int (*irq_build)(struct pci_pbm_info *, struct pci_dev *, unsigned int); 214 void (*base_address_update)(struct pci_dev *, int); 215 void (*resource_adjust)(struct pci_dev *, struct resource *, struct resource *); 216 ··· 226 struct pcidev_cookie { 227 struct pci_pbm_info *pbm; 228 struct device_node *prom_node; 229 struct linux_prom_pci_registers prom_regs[PROMREG_MAX]; 230 int num_prom_regs; 231 struct linux_prom_pci_registers prom_assignments[PROMREG_MAX];
··· 16 #include <asm/page.h> 17 #include <asm/oplib.h> 18 #include <asm/prom.h> 19 + #include <asm/of_device.h> 20 #include <asm/iommu.h> 21 22 /* The abstraction used here is that there are PCI controllers, ··· 209 210 /* Operations which are controller specific. */ 211 void (*scan_bus)(struct pci_controller_info *); 212 void (*base_address_update)(struct pci_dev *, int); 213 void (*resource_adjust)(struct pci_dev *, struct resource *, struct resource *); 214 ··· 226 struct pcidev_cookie { 227 struct pci_pbm_info *pbm; 228 struct device_node *prom_node; 229 + struct of_device *op; 230 struct linux_prom_pci_registers prom_regs[PROMREG_MAX]; 231 int num_prom_regs; 232 struct linux_prom_pci_registers prom_assignments[PROMREG_MAX];
+8
include/asm-sparc64/prom.h
··· 34 unsigned int unique_id; 35 }; 36 37 struct device_node { 38 char *name; 39 char *type; ··· 54 unsigned long _flags; 55 void *data; 56 unsigned int unique_id; 57 }; 58 59 /* flag descriptions */
··· 34 unsigned int unique_id; 35 }; 36 37 + struct of_irq_controller; 38 struct device_node { 39 char *name; 40 char *type; ··· 53 unsigned long _flags; 54 void *data; 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; 63 }; 64 65 /* flag descriptions */