[patch 064/101] Fix interrupt probing on E450 sparc64 systems
From: David Miller <[EMAIL PROTECTED]> [SPARC64]: Fix PCI interrupts on E450 et al. When the PCI controller OBP node lacks an interrupt-map and interrupt-map-mask property, we need to form the INO by hand. The PCI swizzle logic was not doing that properly. This was a regression added by the of_device code. Signed-off-by: David S. Miller <[EMAIL PROTECTED]> Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]> --- arch/sparc64/kernel/of_device.c | 40 ++-- 1 file changed, 38 insertions(+), 2 deletions(-) --- linux-2.6.20.1.orig/arch/sparc64/kernel/of_device.c +++ linux-2.6.20.1/arch/sparc64/kernel/of_device.c @@ -708,7 +708,7 @@ static unsigned int __init pci_irq_swizz unsigned int irq) { struct linux_prom_pci_registers *regs; - unsigned int devfn, slot, ret; + unsigned int bus, devfn, slot, ret; if (irq < 1 || irq > 4) return irq; @@ -717,10 +717,46 @@ static unsigned int __init pci_irq_swizz if (!regs) return irq; + bus = (regs->phys_hi >> 16) & 0xff; devfn = (regs->phys_hi >> 8) & 0xff; slot = (devfn >> 3) & 0x1f; - ret = ((irq - 1 + (slot & 3)) & 3) + 1; + if (pp->irq_trans) { + /* Derived from Table 8-3, U2P User's Manual. This branch +* is handling a PCI controller that lacks a proper set of +* interrupt-map and interrupt-map-mask properties. The +* Ultra-E450 is one example. +* +* The bit layout is BSSLL, where: +* B: 0 on bus A, 1 on bus B +* D: 2-bit slot number, derived from PCI device number as +*(dev - 1) for bus A, or (dev - 2) for bus B +* L: 2-bit line number +* +* Actually, more "portable" way to calculate the funky +* slot number is to subtract pbm->pci_first_slot from the +* device number, and that's exactly what the pre-OF +* sparc64 code did, but we're building this stuff generically +* using the OBP tree, not in the PCI controller layer. +*/ + if (bus & 0x80) { + /* PBM-A */ + bus = 0x00; + slot = (slot - 1) << 2; + } else { + /* PBM-B */ + bus = 0x10; + slot = (slot - 2) << 2; + } + irq -= 1; + + ret = (bus | slot | irq); + } else { + /* Going through a PCI-PCI bridge that lacks a set of +* interrupt-map and interrupt-map-mask properties. +*/ + ret = ((irq - 1 + (slot & 3)) & 3) + 1; + } return ret; } -- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[patch 064/101] Fix interrupt probing on E450 sparc64 systems
From: David Miller [EMAIL PROTECTED] [SPARC64]: Fix PCI interrupts on E450 et al. When the PCI controller OBP node lacks an interrupt-map and interrupt-map-mask property, we need to form the INO by hand. The PCI swizzle logic was not doing that properly. This was a regression added by the of_device code. Signed-off-by: David S. Miller [EMAIL PROTECTED] Signed-off-by: Greg Kroah-Hartman [EMAIL PROTECTED] --- arch/sparc64/kernel/of_device.c | 40 ++-- 1 file changed, 38 insertions(+), 2 deletions(-) --- linux-2.6.20.1.orig/arch/sparc64/kernel/of_device.c +++ linux-2.6.20.1/arch/sparc64/kernel/of_device.c @@ -708,7 +708,7 @@ static unsigned int __init pci_irq_swizz unsigned int irq) { struct linux_prom_pci_registers *regs; - unsigned int devfn, slot, ret; + unsigned int bus, devfn, slot, ret; if (irq 1 || irq 4) return irq; @@ -717,10 +717,46 @@ static unsigned int __init pci_irq_swizz if (!regs) return irq; + bus = (regs-phys_hi 16) 0xff; devfn = (regs-phys_hi 8) 0xff; slot = (devfn 3) 0x1f; - ret = ((irq - 1 + (slot 3)) 3) + 1; + if (pp-irq_trans) { + /* Derived from Table 8-3, U2P User's Manual. This branch +* is handling a PCI controller that lacks a proper set of +* interrupt-map and interrupt-map-mask properties. The +* Ultra-E450 is one example. +* +* The bit layout is BSSLL, where: +* B: 0 on bus A, 1 on bus B +* D: 2-bit slot number, derived from PCI device number as +*(dev - 1) for bus A, or (dev - 2) for bus B +* L: 2-bit line number +* +* Actually, more portable way to calculate the funky +* slot number is to subtract pbm-pci_first_slot from the +* device number, and that's exactly what the pre-OF +* sparc64 code did, but we're building this stuff generically +* using the OBP tree, not in the PCI controller layer. +*/ + if (bus 0x80) { + /* PBM-A */ + bus = 0x00; + slot = (slot - 1) 2; + } else { + /* PBM-B */ + bus = 0x10; + slot = (slot - 2) 2; + } + irq -= 1; + + ret = (bus | slot | irq); + } else { + /* Going through a PCI-PCI bridge that lacks a set of +* interrupt-map and interrupt-map-mask properties. +*/ + ret = ((irq - 1 + (slot 3)) 3) + 1; + } return ret; } -- - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/