]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.arch/x86-acpi-reroute-PCI-interrupt-to-legacy-boot-interrupt.patch
Updated xen patches taken from suse.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.arch / x86-acpi-reroute-PCI-interrupt-to-legacy-boot-interrupt.patch
1 From: Stefan Assmann <sassmann@suse.de>
2 Subject: pci, acpi: reroute PCI interrupt to legacy boot interrupt equivalent
3
4 Some chipsets (e.g. intel 6700PXH) generate a legacy INTx when the
5 IRQ entry in the chipset's IO-APIC is masked (as, e.g. the RT kernel
6 does during interrupt handling). On chipsets where this INTx generation
7 cannot be disabled, we reroute the valid interrupts to their legacy
8 equivalent to get rid of spurious interrupts that might otherwise bring
9 down (vital) interrupt lines through spurious interrupt detection in
10 note_interrupt().
11
12 This patch benefited from discussions with Alexander Graf, Torsten Duwe,
13 Ihno Krumreich, Daniel Gollub, Hannes Reinecke. The conclusions we drew
14 and the patch itself are the authors' responsibility alone.
15
16 Signed-off-by: Stefan Assmann <sassmann@suse.de>
17 Signed-off-by: Olaf Dabrunz <od@suse.de>
18 Signed-off-by: Ingo Molnar <mingo@elte.hu>
19 ---
20 drivers/acpi/pci_irq.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++
21 drivers/pci/quirks.c | 26 ++++++++++++++++++++++
22 include/linux/pci.h | 6 +++++
23 3 files changed, 88 insertions(+)
24
25 --- a/drivers/acpi/pci_irq.c
26 +++ b/drivers/acpi/pci_irq.c
27 @@ -384,6 +384,27 @@ acpi_pci_free_irq(struct acpi_prt_entry
28 return irq;
29 }
30
31 +#ifdef CONFIG_X86_IO_APIC
32 +extern int noioapicquirk;
33 +
34 +static int bridge_has_boot_interrupt_variant(struct pci_bus *bus)
35 +{
36 + struct pci_bus *bus_it;
37 +
38 + for (bus_it = bus ; bus_it ; bus_it = bus_it->parent) {
39 + if (!bus_it->self)
40 + return 0;
41 +
42 + printk(KERN_INFO "vendor=%04x device=%04x\n", bus_it->self->vendor,
43 + bus_it->self->device);
44 +
45 + if (bus_it->self->irq_reroute_variant)
46 + return bus_it->self->irq_reroute_variant;
47 + }
48 + return 0;
49 +}
50 +#endif /* CONFIG_X86_IO_APIC */
51 +
52 /*
53 * acpi_pci_irq_lookup
54 * success: return IRQ >= 0
55 @@ -413,6 +434,41 @@ acpi_pci_irq_lookup(struct pci_bus *bus,
56 }
57
58 ret = func(entry, triggering, polarity, link);
59 +
60 +#ifdef CONFIG_X86_IO_APIC
61 + /*
62 + * Some chipsets (e.g. intel 6700PXH) generate a legacy INTx when the
63 + * IRQ entry in the chipset's IO-APIC is masked (as, e.g. the RT kernel
64 + * does during interrupt handling). When this INTx generation cannot be
65 + * disabled, we reroute these interrupts to their legacy equivalent to
66 + * get rid of spurious interrupts.
67 + */
68 + if (!noioapicquirk) {
69 + switch (bridge_has_boot_interrupt_variant(bus)) {
70 + case 0:
71 + /* no rerouting necessary */
72 + break;
73 +
74 + case INTEL_IRQ_REROUTE_VARIANT:
75 + /*
76 + * Remap according to INTx routing table in 6700PXH
77 + * specs, intel order number 302628-002, section
78 + * 2.15.2. Other chipsets (80332, ...) have the same
79 + * mapping and are handled here as well.
80 + */
81 + printk(KERN_INFO "pci irq %d -> rerouted to legacy "
82 + "irq %d\n", ret, (ret % 4) + 16);
83 + ret = (ret % 4) + 16;
84 + break;
85 +
86 + default:
87 + printk(KERN_INFO "not rerouting irq %d to legacy irq: "
88 + "unknown mapping\n", ret);
89 + break;
90 + }
91 + }
92 +#endif /* CONFIG_X86_IO_APIC */
93 +
94 return ret;
95 }
96
97 --- a/drivers/pci/quirks.c
98 +++ b/drivers/pci/quirks.c
99 @@ -1425,6 +1425,32 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN
100
101 #ifdef CONFIG_X86_IO_APIC
102 /*
103 + * Boot interrupts on some chipsets cannot be turned off. For these chipsets,
104 + * remap the original interrupt in the linux kernel to the boot interrupt, so
105 + * that a PCI device's interrupt handler is installed on the boot interrupt
106 + * line instead.
107 + */
108 +static void quirk_reroute_to_boot_interrupts_intel(struct pci_dev *dev)
109 +{
110 + if (noioapicquirk)
111 + return;
112 +
113 + dev->irq_reroute_variant = INTEL_IRQ_REROUTE_VARIANT;
114 +
115 + printk(KERN_INFO "PCI quirk: reroute interrupts for 0x%04x:0x%04x\n",
116 + dev->vendor, dev->device);
117 + return;
118 +}
119 +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80333_0, quirk_reroute_to_boot_interrupts_intel);
120 +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80333_1, quirk_reroute_to_boot_interrupts_intel);
121 +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0, quirk_reroute_to_boot_interrupts_intel);
122 +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_0, quirk_reroute_to_boot_interrupts_intel);
123 +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_1, quirk_reroute_to_boot_interrupts_intel);
124 +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXHV, quirk_reroute_to_boot_interrupts_intel);
125 +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80332_0, quirk_reroute_to_boot_interrupts_intel);
126 +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80332_1, quirk_reroute_to_boot_interrupts_intel);
127 +
128 +/*
129 * On some chipsets we can disable the generation of legacy INTx boot
130 * interrupts.
131 */
132 --- a/include/linux/pci.h
133 +++ b/include/linux/pci.h
134 @@ -133,6 +133,11 @@ enum pci_dev_flags {
135 PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t) 2,
136 };
137
138 +enum pci_irq_reroute_variant {
139 + INTEL_IRQ_REROUTE_VARIANT = 1,
140 + MAX_IRQ_REROUTE_VARIANTS = 3
141 +};
142 +
143 typedef unsigned short __bitwise pci_bus_flags_t;
144 enum pci_bus_flags {
145 PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1,
146 @@ -217,6 +222,7 @@ struct pci_dev {
147 unsigned int no_msi:1; /* device may not use msi */
148 unsigned int block_ucfg_access:1; /* userspace config space access is blocked */
149 unsigned int broken_parity_status:1; /* Device generates false positive parity */
150 + unsigned int irq_reroute_variant:2; /* device needs IRQ rerouting variant */
151 unsigned int msi_enabled:1;
152 unsigned int msix_enabled:1;
153 unsigned int is_managed:1;