[patch 064/101] Fix interrupt probing on E450 sparc64 systems

2007-03-07 Thread Greg KH
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

2007-03-07 Thread Greg KH
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/