]>
Commit | Line | Data |
---|---|---|
1bbce966 GKH |
1 | From stable-bounces@linux.kernel.org Tue Feb 27 11:03:05 2007 |
2 | From: David Miller <davem@davemloft.net> | |
3 | Date: Tue, 27 Feb 2007 11:01:38 -0800 (PST) | |
4 | Subject: Fix interrupt probing on E450 sparc64 systems | |
5 | To: stable@kernel.org | |
6 | Cc: fabbione@ubuntu.com, bunk@stusta.de | |
7 | Message-ID: <20070227.110138.23013918.davem@davemloft.net> | |
8 | ||
9 | From: David Miller <davem@davemloft.net> | |
10 | ||
11 | [SPARC64]: Fix PCI interrupts on E450 et al. | |
12 | ||
13 | When the PCI controller OBP node lacks an interrupt-map | |
14 | and interrupt-map-mask property, we need to form the | |
15 | INO by hand. The PCI swizzle logic was not doing that | |
16 | properly. | |
17 | ||
18 | This was a regression added by the of_device code. | |
19 | ||
20 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
21 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
22 | ||
23 | --- | |
24 | arch/sparc64/kernel/of_device.c | 40 ++++++++++++++++++++++++++++++++++++++-- | |
25 | 1 file changed, 38 insertions(+), 2 deletions(-) | |
26 | ||
27 | --- linux-2.6.20.1.orig/arch/sparc64/kernel/of_device.c | |
28 | +++ linux-2.6.20.1/arch/sparc64/kernel/of_device.c | |
29 | @@ -708,7 +708,7 @@ static unsigned int __init pci_irq_swizz | |
30 | unsigned int irq) | |
31 | { | |
32 | struct linux_prom_pci_registers *regs; | |
33 | - unsigned int devfn, slot, ret; | |
34 | + unsigned int bus, devfn, slot, ret; | |
35 | ||
36 | if (irq < 1 || irq > 4) | |
37 | return irq; | |
38 | @@ -717,10 +717,46 @@ static unsigned int __init pci_irq_swizz | |
39 | if (!regs) | |
40 | return irq; | |
41 | ||
42 | + bus = (regs->phys_hi >> 16) & 0xff; | |
43 | devfn = (regs->phys_hi >> 8) & 0xff; | |
44 | slot = (devfn >> 3) & 0x1f; | |
45 | ||
46 | - ret = ((irq - 1 + (slot & 3)) & 3) + 1; | |
47 | + if (pp->irq_trans) { | |
48 | + /* Derived from Table 8-3, U2P User's Manual. This branch | |
49 | + * is handling a PCI controller that lacks a proper set of | |
50 | + * interrupt-map and interrupt-map-mask properties. The | |
51 | + * Ultra-E450 is one example. | |
52 | + * | |
53 | + * The bit layout is BSSLL, where: | |
54 | + * B: 0 on bus A, 1 on bus B | |
55 | + * D: 2-bit slot number, derived from PCI device number as | |
56 | + * (dev - 1) for bus A, or (dev - 2) for bus B | |
57 | + * L: 2-bit line number | |
58 | + * | |
59 | + * Actually, more "portable" way to calculate the funky | |
60 | + * slot number is to subtract pbm->pci_first_slot from the | |
61 | + * device number, and that's exactly what the pre-OF | |
62 | + * sparc64 code did, but we're building this stuff generically | |
63 | + * using the OBP tree, not in the PCI controller layer. | |
64 | + */ | |
65 | + if (bus & 0x80) { | |
66 | + /* PBM-A */ | |
67 | + bus = 0x00; | |
68 | + slot = (slot - 1) << 2; | |
69 | + } else { | |
70 | + /* PBM-B */ | |
71 | + bus = 0x10; | |
72 | + slot = (slot - 2) << 2; | |
73 | + } | |
74 | + irq -= 1; | |
75 | + | |
76 | + ret = (bus | slot | irq); | |
77 | + } else { | |
78 | + /* Going through a PCI-PCI bridge that lacks a set of | |
79 | + * interrupt-map and interrupt-map-mask properties. | |
80 | + */ | |
81 | + ret = ((irq - 1 + (slot & 3)) & 3) + 1; | |
82 | + } | |
83 | ||
84 | return ret; | |
85 | } |