Commit d7f6169a0d32002657886fee561c641acddb9a75

Authored by Stefan Assmann
Committed by Len Brown
1 parent 1765a367a3

ACPI: fix CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS

The following was observed by Steve Rostedt on 3.0.0-rc5
Backtrace:
irq 16: nobody cared (try booting with the "irqpoll" option)
Pid: 65, comm: irq/16-uhci_hcd Not tainted 3.0.0-rc5-test+ #94
Call Trace:
 [<ffffffff810aa643>] __report_bad_irq+0x37/0xc1
 [<ffffffff810aaa2d>] note_interrupt+0x14e/0x1c9
 [<ffffffff810a9a05>] ? irq_thread_fn+0x3c/0x3c
 [<ffffffff810a990e>] irq_thread+0xf6/0x1b1
 [<ffffffff810a9818>] ? irq_finalize_oneshot+0xb3/0xb3
 [<ffffffff8106b4d6>] kthread+0x9f/0xa7
 [<ffffffff814f1f04>] kernel_thread_helper+0x4/0x10
 [<ffffffff8103ca09>] ? finish_task_switch+0x7b/0xc0
 [<ffffffff814eac78>] ? retint_restore_args+0x13/0x13
 [<ffffffff8106b437>] ? __init_kthread_worker+0x5a/0x5a
 [<ffffffff814f1f00>] ? gs_change+0x13/0x13
handlers:
[<ffffffff810a912d>] irq_default_primary_handler threaded [<ffffffff8135eaa6>] usb_hcd_irq
[<ffffffff810a912d>] irq_default_primary_handler threaded [<ffffffff8135eaa6>] usb_hcd_irq
Disabling IRQ #16

The problem being that a device triggers boot interrupts (due to threaded
interrupt handling and masking of the IO-APIC), which are forwarded
to the PIRQ line of the device. These interrupts are not handled on the PIRQ
line because the interrupt handler is not present there.
This should have already been fixed by CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS.
However some parts of the quirk got lost in the ACPI merge. This is a resent of
the patch proposed in 2009.
See http://lkml.org/lkml/2009/9/7/192

Signed-off-by: Stefan Assmann <sassmann@kpanic.de>
Tested-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Len Brown <len.brown@intel.com>

Showing 1 changed file with 58 additions and 0 deletions Inline Diff

drivers/acpi/pci_irq.c
1 /* 1 /*
2 * pci_irq.c - ACPI PCI Interrupt Routing ($Revision: 11 $) 2 * pci_irq.c - ACPI PCI Interrupt Routing ($Revision: 11 $)
3 * 3 *
4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6 * Copyright (C) 2002 Dominik Brodowski <devel@brodo.de> 6 * Copyright (C) 2002 Dominik Brodowski <devel@brodo.de>
7 * (c) Copyright 2008 Hewlett-Packard Development Company, L.P. 7 * (c) Copyright 2008 Hewlett-Packard Development Company, L.P.
8 * Bjorn Helgaas <bjorn.helgaas@hp.com> 8 * Bjorn Helgaas <bjorn.helgaas@hp.com>
9 * 9 *
10 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 10 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by 13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or (at 14 * the Free Software Foundation; either version 2 of the License, or (at
15 * your option) any later version. 15 * your option) any later version.
16 * 16 *
17 * This program is distributed in the hope that it will be useful, but 17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of 18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details. 20 * General Public License for more details.
21 * 21 *
22 * You should have received a copy of the GNU General Public License along 22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc., 23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 * 25 *
26 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 26 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 */ 27 */
28 28
29 29
30 #include <linux/dmi.h> 30 #include <linux/dmi.h>
31 #include <linux/kernel.h> 31 #include <linux/kernel.h>
32 #include <linux/module.h> 32 #include <linux/module.h>
33 #include <linux/init.h> 33 #include <linux/init.h>
34 #include <linux/types.h> 34 #include <linux/types.h>
35 #include <linux/spinlock.h> 35 #include <linux/spinlock.h>
36 #include <linux/pm.h> 36 #include <linux/pm.h>
37 #include <linux/pci.h> 37 #include <linux/pci.h>
38 #include <linux/acpi.h> 38 #include <linux/acpi.h>
39 #include <linux/slab.h> 39 #include <linux/slab.h>
40 #include <acpi/acpi_bus.h> 40 #include <acpi/acpi_bus.h>
41 #include <acpi/acpi_drivers.h> 41 #include <acpi/acpi_drivers.h>
42 42
43 #define PREFIX "ACPI: " 43 #define PREFIX "ACPI: "
44 44
45 #define _COMPONENT ACPI_PCI_COMPONENT 45 #define _COMPONENT ACPI_PCI_COMPONENT
46 ACPI_MODULE_NAME("pci_irq"); 46 ACPI_MODULE_NAME("pci_irq");
47 47
48 struct acpi_prt_entry { 48 struct acpi_prt_entry {
49 struct list_head list; 49 struct list_head list;
50 struct acpi_pci_id id; 50 struct acpi_pci_id id;
51 u8 pin; 51 u8 pin;
52 acpi_handle link; 52 acpi_handle link;
53 u32 index; /* GSI, or link _CRS index */ 53 u32 index; /* GSI, or link _CRS index */
54 }; 54 };
55 55
56 static LIST_HEAD(acpi_prt_list); 56 static LIST_HEAD(acpi_prt_list);
57 static DEFINE_SPINLOCK(acpi_prt_lock); 57 static DEFINE_SPINLOCK(acpi_prt_lock);
58 58
59 static inline char pin_name(int pin) 59 static inline char pin_name(int pin)
60 { 60 {
61 return 'A' + pin - 1; 61 return 'A' + pin - 1;
62 } 62 }
63 63
64 /* -------------------------------------------------------------------------- 64 /* --------------------------------------------------------------------------
65 PCI IRQ Routing Table (PRT) Support 65 PCI IRQ Routing Table (PRT) Support
66 -------------------------------------------------------------------------- */ 66 -------------------------------------------------------------------------- */
67 67
68 static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(struct pci_dev *dev, 68 static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(struct pci_dev *dev,
69 int pin) 69 int pin)
70 { 70 {
71 struct acpi_prt_entry *entry; 71 struct acpi_prt_entry *entry;
72 int segment = pci_domain_nr(dev->bus); 72 int segment = pci_domain_nr(dev->bus);
73 int bus = dev->bus->number; 73 int bus = dev->bus->number;
74 int device = PCI_SLOT(dev->devfn); 74 int device = PCI_SLOT(dev->devfn);
75 75
76 spin_lock(&acpi_prt_lock); 76 spin_lock(&acpi_prt_lock);
77 list_for_each_entry(entry, &acpi_prt_list, list) { 77 list_for_each_entry(entry, &acpi_prt_list, list) {
78 if ((segment == entry->id.segment) 78 if ((segment == entry->id.segment)
79 && (bus == entry->id.bus) 79 && (bus == entry->id.bus)
80 && (device == entry->id.device) 80 && (device == entry->id.device)
81 && (pin == entry->pin)) { 81 && (pin == entry->pin)) {
82 spin_unlock(&acpi_prt_lock); 82 spin_unlock(&acpi_prt_lock);
83 return entry; 83 return entry;
84 } 84 }
85 } 85 }
86 spin_unlock(&acpi_prt_lock); 86 spin_unlock(&acpi_prt_lock);
87 return NULL; 87 return NULL;
88 } 88 }
89 89
90 /* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */ 90 /* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */
91 static const struct dmi_system_id medion_md9580[] = { 91 static const struct dmi_system_id medion_md9580[] = {
92 { 92 {
93 .ident = "Medion MD9580-F laptop", 93 .ident = "Medion MD9580-F laptop",
94 .matches = { 94 .matches = {
95 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), 95 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
96 DMI_MATCH(DMI_PRODUCT_NAME, "A555"), 96 DMI_MATCH(DMI_PRODUCT_NAME, "A555"),
97 }, 97 },
98 }, 98 },
99 { } 99 { }
100 }; 100 };
101 101
102 /* http://bugzilla.kernel.org/show_bug.cgi?id=5044 */ 102 /* http://bugzilla.kernel.org/show_bug.cgi?id=5044 */
103 static const struct dmi_system_id dell_optiplex[] = { 103 static const struct dmi_system_id dell_optiplex[] = {
104 { 104 {
105 .ident = "Dell Optiplex GX1", 105 .ident = "Dell Optiplex GX1",
106 .matches = { 106 .matches = {
107 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), 107 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
108 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex GX1 600S+"), 108 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex GX1 600S+"),
109 }, 109 },
110 }, 110 },
111 { } 111 { }
112 }; 112 };
113 113
114 /* http://bugzilla.kernel.org/show_bug.cgi?id=10138 */ 114 /* http://bugzilla.kernel.org/show_bug.cgi?id=10138 */
115 static const struct dmi_system_id hp_t5710[] = { 115 static const struct dmi_system_id hp_t5710[] = {
116 { 116 {
117 .ident = "HP t5710", 117 .ident = "HP t5710",
118 .matches = { 118 .matches = {
119 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 119 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
120 DMI_MATCH(DMI_PRODUCT_NAME, "hp t5000 series"), 120 DMI_MATCH(DMI_PRODUCT_NAME, "hp t5000 series"),
121 DMI_MATCH(DMI_BOARD_NAME, "098Ch"), 121 DMI_MATCH(DMI_BOARD_NAME, "098Ch"),
122 }, 122 },
123 }, 123 },
124 { } 124 { }
125 }; 125 };
126 126
127 struct prt_quirk { 127 struct prt_quirk {
128 const struct dmi_system_id *system; 128 const struct dmi_system_id *system;
129 unsigned int segment; 129 unsigned int segment;
130 unsigned int bus; 130 unsigned int bus;
131 unsigned int device; 131 unsigned int device;
132 unsigned char pin; 132 unsigned char pin;
133 const char *source; /* according to BIOS */ 133 const char *source; /* according to BIOS */
134 const char *actual_source; 134 const char *actual_source;
135 }; 135 };
136 136
137 #define PCI_INTX_PIN(c) (c - 'A' + 1) 137 #define PCI_INTX_PIN(c) (c - 'A' + 1)
138 138
139 /* 139 /*
140 * These systems have incorrect _PRT entries. The BIOS claims the PCI 140 * These systems have incorrect _PRT entries. The BIOS claims the PCI
141 * interrupt at the listed segment/bus/device/pin is connected to the first 141 * interrupt at the listed segment/bus/device/pin is connected to the first
142 * link device, but it is actually connected to the second. 142 * link device, but it is actually connected to the second.
143 */ 143 */
144 static const struct prt_quirk prt_quirks[] = { 144 static const struct prt_quirk prt_quirks[] = {
145 { medion_md9580, 0, 0, 9, PCI_INTX_PIN('A'), 145 { medion_md9580, 0, 0, 9, PCI_INTX_PIN('A'),
146 "\\_SB_.PCI0.ISA_.LNKA", 146 "\\_SB_.PCI0.ISA_.LNKA",
147 "\\_SB_.PCI0.ISA_.LNKB"}, 147 "\\_SB_.PCI0.ISA_.LNKB"},
148 { dell_optiplex, 0, 0, 0xd, PCI_INTX_PIN('A'), 148 { dell_optiplex, 0, 0, 0xd, PCI_INTX_PIN('A'),
149 "\\_SB_.LNKB", 149 "\\_SB_.LNKB",
150 "\\_SB_.LNKA"}, 150 "\\_SB_.LNKA"},
151 { hp_t5710, 0, 0, 1, PCI_INTX_PIN('A'), 151 { hp_t5710, 0, 0, 1, PCI_INTX_PIN('A'),
152 "\\_SB_.PCI0.LNK1", 152 "\\_SB_.PCI0.LNK1",
153 "\\_SB_.PCI0.LNK3"}, 153 "\\_SB_.PCI0.LNK3"},
154 }; 154 };
155 155
156 static void do_prt_fixups(struct acpi_prt_entry *entry, 156 static void do_prt_fixups(struct acpi_prt_entry *entry,
157 struct acpi_pci_routing_table *prt) 157 struct acpi_pci_routing_table *prt)
158 { 158 {
159 int i; 159 int i;
160 const struct prt_quirk *quirk; 160 const struct prt_quirk *quirk;
161 161
162 for (i = 0; i < ARRAY_SIZE(prt_quirks); i++) { 162 for (i = 0; i < ARRAY_SIZE(prt_quirks); i++) {
163 quirk = &prt_quirks[i]; 163 quirk = &prt_quirks[i];
164 164
165 /* All current quirks involve link devices, not GSIs */ 165 /* All current quirks involve link devices, not GSIs */
166 if (!prt->source) 166 if (!prt->source)
167 continue; 167 continue;
168 168
169 if (dmi_check_system(quirk->system) && 169 if (dmi_check_system(quirk->system) &&
170 entry->id.segment == quirk->segment && 170 entry->id.segment == quirk->segment &&
171 entry->id.bus == quirk->bus && 171 entry->id.bus == quirk->bus &&
172 entry->id.device == quirk->device && 172 entry->id.device == quirk->device &&
173 entry->pin == quirk->pin && 173 entry->pin == quirk->pin &&
174 !strcmp(prt->source, quirk->source) && 174 !strcmp(prt->source, quirk->source) &&
175 strlen(prt->source) >= strlen(quirk->actual_source)) { 175 strlen(prt->source) >= strlen(quirk->actual_source)) {
176 printk(KERN_WARNING PREFIX "firmware reports " 176 printk(KERN_WARNING PREFIX "firmware reports "
177 "%04x:%02x:%02x PCI INT %c connected to %s; " 177 "%04x:%02x:%02x PCI INT %c connected to %s; "
178 "changing to %s\n", 178 "changing to %s\n",
179 entry->id.segment, entry->id.bus, 179 entry->id.segment, entry->id.bus,
180 entry->id.device, pin_name(entry->pin), 180 entry->id.device, pin_name(entry->pin),
181 prt->source, quirk->actual_source); 181 prt->source, quirk->actual_source);
182 strcpy(prt->source, quirk->actual_source); 182 strcpy(prt->source, quirk->actual_source);
183 } 183 }
184 } 184 }
185 } 185 }
186 186
187 static int acpi_pci_irq_add_entry(acpi_handle handle, struct pci_bus *bus, 187 static int acpi_pci_irq_add_entry(acpi_handle handle, struct pci_bus *bus,
188 struct acpi_pci_routing_table *prt) 188 struct acpi_pci_routing_table *prt)
189 { 189 {
190 struct acpi_prt_entry *entry; 190 struct acpi_prt_entry *entry;
191 191
192 entry = kzalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL); 192 entry = kzalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL);
193 if (!entry) 193 if (!entry)
194 return -ENOMEM; 194 return -ENOMEM;
195 195
196 /* 196 /*
197 * Note that the _PRT uses 0=INTA, 1=INTB, etc, while PCI uses 197 * Note that the _PRT uses 0=INTA, 1=INTB, etc, while PCI uses
198 * 1=INTA, 2=INTB. We use the PCI encoding throughout, so convert 198 * 1=INTA, 2=INTB. We use the PCI encoding throughout, so convert
199 * it here. 199 * it here.
200 */ 200 */
201 entry->id.segment = pci_domain_nr(bus); 201 entry->id.segment = pci_domain_nr(bus);
202 entry->id.bus = bus->number; 202 entry->id.bus = bus->number;
203 entry->id.device = (prt->address >> 16) & 0xFFFF; 203 entry->id.device = (prt->address >> 16) & 0xFFFF;
204 entry->pin = prt->pin + 1; 204 entry->pin = prt->pin + 1;
205 205
206 do_prt_fixups(entry, prt); 206 do_prt_fixups(entry, prt);
207 207
208 entry->index = prt->source_index; 208 entry->index = prt->source_index;
209 209
210 /* 210 /*
211 * Type 1: Dynamic 211 * Type 1: Dynamic
212 * --------------- 212 * ---------------
213 * The 'source' field specifies the PCI interrupt link device used to 213 * The 'source' field specifies the PCI interrupt link device used to
214 * configure the IRQ assigned to this slot|dev|pin. The 'source_index' 214 * configure the IRQ assigned to this slot|dev|pin. The 'source_index'
215 * indicates which resource descriptor in the resource template (of 215 * indicates which resource descriptor in the resource template (of
216 * the link device) this interrupt is allocated from. 216 * the link device) this interrupt is allocated from.
217 * 217 *
218 * NOTE: Don't query the Link Device for IRQ information at this time 218 * NOTE: Don't query the Link Device for IRQ information at this time
219 * because Link Device enumeration may not have occurred yet 219 * because Link Device enumeration may not have occurred yet
220 * (e.g. exists somewhere 'below' this _PRT entry in the ACPI 220 * (e.g. exists somewhere 'below' this _PRT entry in the ACPI
221 * namespace). 221 * namespace).
222 */ 222 */
223 if (prt->source[0]) 223 if (prt->source[0])
224 acpi_get_handle(handle, prt->source, &entry->link); 224 acpi_get_handle(handle, prt->source, &entry->link);
225 225
226 /* 226 /*
227 * Type 2: Static 227 * Type 2: Static
228 * -------------- 228 * --------------
229 * The 'source' field is NULL, and the 'source_index' field specifies 229 * The 'source' field is NULL, and the 'source_index' field specifies
230 * the IRQ value, which is hardwired to specific interrupt inputs on 230 * the IRQ value, which is hardwired to specific interrupt inputs on
231 * the interrupt controller. 231 * the interrupt controller.
232 */ 232 */
233 233
234 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, 234 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO,
235 " %04x:%02x:%02x[%c] -> %s[%d]\n", 235 " %04x:%02x:%02x[%c] -> %s[%d]\n",
236 entry->id.segment, entry->id.bus, 236 entry->id.segment, entry->id.bus,
237 entry->id.device, pin_name(entry->pin), 237 entry->id.device, pin_name(entry->pin),
238 prt->source, entry->index)); 238 prt->source, entry->index));
239 239
240 spin_lock(&acpi_prt_lock); 240 spin_lock(&acpi_prt_lock);
241 list_add_tail(&entry->list, &acpi_prt_list); 241 list_add_tail(&entry->list, &acpi_prt_list);
242 spin_unlock(&acpi_prt_lock); 242 spin_unlock(&acpi_prt_lock);
243 243
244 return 0; 244 return 0;
245 } 245 }
246 246
247 int acpi_pci_irq_add_prt(acpi_handle handle, struct pci_bus *bus) 247 int acpi_pci_irq_add_prt(acpi_handle handle, struct pci_bus *bus)
248 { 248 {
249 acpi_status status; 249 acpi_status status;
250 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 250 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
251 struct acpi_pci_routing_table *entry; 251 struct acpi_pci_routing_table *entry;
252 252
253 /* 'handle' is the _PRT's parent (root bridge or PCI-PCI bridge) */ 253 /* 'handle' is the _PRT's parent (root bridge or PCI-PCI bridge) */
254 status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); 254 status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
255 if (ACPI_FAILURE(status)) 255 if (ACPI_FAILURE(status))
256 return -ENODEV; 256 return -ENODEV;
257 257
258 printk(KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n", 258 printk(KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n",
259 (char *) buffer.pointer); 259 (char *) buffer.pointer);
260 260
261 kfree(buffer.pointer); 261 kfree(buffer.pointer);
262 262
263 buffer.length = ACPI_ALLOCATE_BUFFER; 263 buffer.length = ACPI_ALLOCATE_BUFFER;
264 buffer.pointer = NULL; 264 buffer.pointer = NULL;
265 265
266 status = acpi_get_irq_routing_table(handle, &buffer); 266 status = acpi_get_irq_routing_table(handle, &buffer);
267 if (ACPI_FAILURE(status)) { 267 if (ACPI_FAILURE(status)) {
268 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRT [%s]", 268 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRT [%s]",
269 acpi_format_exception(status))); 269 acpi_format_exception(status)));
270 kfree(buffer.pointer); 270 kfree(buffer.pointer);
271 return -ENODEV; 271 return -ENODEV;
272 } 272 }
273 273
274 entry = buffer.pointer; 274 entry = buffer.pointer;
275 while (entry && (entry->length > 0)) { 275 while (entry && (entry->length > 0)) {
276 acpi_pci_irq_add_entry(handle, bus, entry); 276 acpi_pci_irq_add_entry(handle, bus, entry);
277 entry = (struct acpi_pci_routing_table *) 277 entry = (struct acpi_pci_routing_table *)
278 ((unsigned long)entry + entry->length); 278 ((unsigned long)entry + entry->length);
279 } 279 }
280 280
281 kfree(buffer.pointer); 281 kfree(buffer.pointer);
282 return 0; 282 return 0;
283 } 283 }
284 284
285 void acpi_pci_irq_del_prt(struct pci_bus *bus) 285 void acpi_pci_irq_del_prt(struct pci_bus *bus)
286 { 286 {
287 struct acpi_prt_entry *entry, *tmp; 287 struct acpi_prt_entry *entry, *tmp;
288 288
289 printk(KERN_DEBUG 289 printk(KERN_DEBUG
290 "ACPI: Delete PCI Interrupt Routing Table for %04x:%02x\n", 290 "ACPI: Delete PCI Interrupt Routing Table for %04x:%02x\n",
291 pci_domain_nr(bus), bus->number); 291 pci_domain_nr(bus), bus->number);
292 spin_lock(&acpi_prt_lock); 292 spin_lock(&acpi_prt_lock);
293 list_for_each_entry_safe(entry, tmp, &acpi_prt_list, list) { 293 list_for_each_entry_safe(entry, tmp, &acpi_prt_list, list) {
294 if (pci_domain_nr(bus) == entry->id.segment 294 if (pci_domain_nr(bus) == entry->id.segment
295 && bus->number == entry->id.bus) { 295 && bus->number == entry->id.bus) {
296 list_del(&entry->list); 296 list_del(&entry->list);
297 kfree(entry); 297 kfree(entry);
298 } 298 }
299 } 299 }
300 spin_unlock(&acpi_prt_lock); 300 spin_unlock(&acpi_prt_lock);
301 } 301 }
302 302
303 /* -------------------------------------------------------------------------- 303 /* --------------------------------------------------------------------------
304 PCI Interrupt Routing Support 304 PCI Interrupt Routing Support
305 -------------------------------------------------------------------------- */ 305 -------------------------------------------------------------------------- */
306 #ifdef CONFIG_X86_IO_APIC
307 extern int noioapicquirk;
308 extern int noioapicreroute;
309
310 static int bridge_has_boot_interrupt_variant(struct pci_bus *bus)
311 {
312 struct pci_bus *bus_it;
313
314 for (bus_it = bus ; bus_it ; bus_it = bus_it->parent) {
315 if (!bus_it->self)
316 return 0;
317 if (bus_it->self->irq_reroute_variant)
318 return bus_it->self->irq_reroute_variant;
319 }
320 return 0;
321 }
322
323 /*
324 * Some chipsets (e.g. Intel 6700PXH) generate a legacy INTx when the IRQ
325 * entry in the chipset's IO-APIC is masked (as, e.g. the RT kernel does
326 * during interrupt handling). When this INTx generation cannot be disabled,
327 * we reroute these interrupts to their legacy equivalent to get rid of
328 * spurious interrupts.
329 */
330 static int acpi_reroute_boot_interrupt(struct pci_dev *dev,
331 struct acpi_prt_entry *entry)
332 {
333 if (noioapicquirk || noioapicreroute) {
334 return 0;
335 } else {
336 switch (bridge_has_boot_interrupt_variant(dev->bus)) {
337 case 0:
338 /* no rerouting necessary */
339 return 0;
340 case INTEL_IRQ_REROUTE_VARIANT:
341 /*
342 * Remap according to INTx routing table in 6700PXH
343 * specs, intel order number 302628-002, section
344 * 2.15.2. Other chipsets (80332, ...) have the same
345 * mapping and are handled here as well.
346 */
347 dev_info(&dev->dev, "PCI IRQ %d -> rerouted to legacy "
348 "IRQ %d\n", entry->index,
349 (entry->index % 4) + 16);
350 entry->index = (entry->index % 4) + 16;
351 return 1;
352 default:
353 dev_warn(&dev->dev, "Cannot reroute IRQ %d to legacy "
354 "IRQ: unknown mapping\n", entry->index);
355 return -1;
356 }
357 }
358 }
359 #endif /* CONFIG_X86_IO_APIC */
360
306 static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin) 361 static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin)
307 { 362 {
308 struct acpi_prt_entry *entry; 363 struct acpi_prt_entry *entry;
309 struct pci_dev *bridge; 364 struct pci_dev *bridge;
310 u8 bridge_pin, orig_pin = pin; 365 u8 bridge_pin, orig_pin = pin;
311 366
312 entry = acpi_pci_irq_find_prt_entry(dev, pin); 367 entry = acpi_pci_irq_find_prt_entry(dev, pin);
313 if (entry) { 368 if (entry) {
369 #ifdef CONFIG_X86_IO_APIC
370 acpi_reroute_boot_interrupt(dev, entry);
371 #endif /* CONFIG_X86_IO_APIC */
314 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %s[%c] _PRT entry\n", 372 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %s[%c] _PRT entry\n",
315 pci_name(dev), pin_name(pin))); 373 pci_name(dev), pin_name(pin)));
316 return entry; 374 return entry;
317 } 375 }
318 376
319 /* 377 /*
320 * Attempt to derive an IRQ for this device from a parent bridge's 378 * Attempt to derive an IRQ for this device from a parent bridge's
321 * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge). 379 * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge).
322 */ 380 */
323 bridge = dev->bus->self; 381 bridge = dev->bus->self;
324 while (bridge) { 382 while (bridge) {
325 pin = pci_swizzle_interrupt_pin(dev, pin); 383 pin = pci_swizzle_interrupt_pin(dev, pin);
326 384
327 if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) { 385 if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) {
328 /* PC card has the same IRQ as its cardbridge */ 386 /* PC card has the same IRQ as its cardbridge */
329 bridge_pin = bridge->pin; 387 bridge_pin = bridge->pin;
330 if (!bridge_pin) { 388 if (!bridge_pin) {
331 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 389 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
332 "No interrupt pin configured for device %s\n", 390 "No interrupt pin configured for device %s\n",
333 pci_name(bridge))); 391 pci_name(bridge)));
334 return NULL; 392 return NULL;
335 } 393 }
336 pin = bridge_pin; 394 pin = bridge_pin;
337 } 395 }
338 396
339 entry = acpi_pci_irq_find_prt_entry(bridge, pin); 397 entry = acpi_pci_irq_find_prt_entry(bridge, pin);
340 if (entry) { 398 if (entry) {
341 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 399 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
342 "Derived GSI for %s INT %c from %s\n", 400 "Derived GSI for %s INT %c from %s\n",
343 pci_name(dev), pin_name(orig_pin), 401 pci_name(dev), pin_name(orig_pin),
344 pci_name(bridge))); 402 pci_name(bridge)));
345 return entry; 403 return entry;
346 } 404 }
347 405
348 dev = bridge; 406 dev = bridge;
349 bridge = dev->bus->self; 407 bridge = dev->bus->self;
350 } 408 }
351 409
352 dev_warn(&dev->dev, "can't derive routing for PCI INT %c\n", 410 dev_warn(&dev->dev, "can't derive routing for PCI INT %c\n",
353 pin_name(orig_pin)); 411 pin_name(orig_pin));
354 return NULL; 412 return NULL;
355 } 413 }
356 414
357 int acpi_pci_irq_enable(struct pci_dev *dev) 415 int acpi_pci_irq_enable(struct pci_dev *dev)
358 { 416 {
359 struct acpi_prt_entry *entry; 417 struct acpi_prt_entry *entry;
360 int gsi; 418 int gsi;
361 u8 pin; 419 u8 pin;
362 int triggering = ACPI_LEVEL_SENSITIVE; 420 int triggering = ACPI_LEVEL_SENSITIVE;
363 int polarity = ACPI_ACTIVE_LOW; 421 int polarity = ACPI_ACTIVE_LOW;
364 char *link = NULL; 422 char *link = NULL;
365 char link_desc[16]; 423 char link_desc[16];
366 int rc; 424 int rc;
367 425
368 pin = dev->pin; 426 pin = dev->pin;
369 if (!pin) { 427 if (!pin) {
370 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 428 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
371 "No interrupt pin configured for device %s\n", 429 "No interrupt pin configured for device %s\n",
372 pci_name(dev))); 430 pci_name(dev)));
373 return 0; 431 return 0;
374 } 432 }
375 433
376 entry = acpi_pci_irq_lookup(dev, pin); 434 entry = acpi_pci_irq_lookup(dev, pin);
377 if (!entry) { 435 if (!entry) {
378 /* 436 /*
379 * IDE legacy mode controller IRQs are magic. Why do compat 437 * IDE legacy mode controller IRQs are magic. Why do compat
380 * extensions always make such a nasty mess. 438 * extensions always make such a nasty mess.
381 */ 439 */
382 if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE && 440 if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE &&
383 (dev->class & 0x05) == 0) 441 (dev->class & 0x05) == 0)
384 return 0; 442 return 0;
385 } 443 }
386 444
387 if (entry) { 445 if (entry) {
388 if (entry->link) 446 if (entry->link)
389 gsi = acpi_pci_link_allocate_irq(entry->link, 447 gsi = acpi_pci_link_allocate_irq(entry->link,
390 entry->index, 448 entry->index,
391 &triggering, &polarity, 449 &triggering, &polarity,
392 &link); 450 &link);
393 else 451 else
394 gsi = entry->index; 452 gsi = entry->index;
395 } else 453 } else
396 gsi = -1; 454 gsi = -1;
397 455
398 /* 456 /*
399 * No IRQ known to the ACPI subsystem - maybe the BIOS / 457 * No IRQ known to the ACPI subsystem - maybe the BIOS /
400 * driver reported one, then use it. Exit in any case. 458 * driver reported one, then use it. Exit in any case.
401 */ 459 */
402 if (gsi < 0) { 460 if (gsi < 0) {
403 u32 dev_gsi; 461 u32 dev_gsi;
404 dev_warn(&dev->dev, "PCI INT %c: no GSI", pin_name(pin)); 462 dev_warn(&dev->dev, "PCI INT %c: no GSI", pin_name(pin));
405 /* Interrupt Line values above 0xF are forbidden */ 463 /* Interrupt Line values above 0xF are forbidden */
406 if (dev->irq > 0 && (dev->irq <= 0xF) && 464 if (dev->irq > 0 && (dev->irq <= 0xF) &&
407 (acpi_isa_irq_to_gsi(dev->irq, &dev_gsi) == 0)) { 465 (acpi_isa_irq_to_gsi(dev->irq, &dev_gsi) == 0)) {
408 printk(" - using ISA IRQ %d\n", dev->irq); 466 printk(" - using ISA IRQ %d\n", dev->irq);
409 acpi_register_gsi(&dev->dev, dev_gsi, 467 acpi_register_gsi(&dev->dev, dev_gsi,
410 ACPI_LEVEL_SENSITIVE, 468 ACPI_LEVEL_SENSITIVE,
411 ACPI_ACTIVE_LOW); 469 ACPI_ACTIVE_LOW);
412 return 0; 470 return 0;
413 } else { 471 } else {
414 printk("\n"); 472 printk("\n");
415 return 0; 473 return 0;
416 } 474 }
417 } 475 }
418 476
419 rc = acpi_register_gsi(&dev->dev, gsi, triggering, polarity); 477 rc = acpi_register_gsi(&dev->dev, gsi, triggering, polarity);
420 if (rc < 0) { 478 if (rc < 0) {
421 dev_warn(&dev->dev, "PCI INT %c: failed to register GSI\n", 479 dev_warn(&dev->dev, "PCI INT %c: failed to register GSI\n",
422 pin_name(pin)); 480 pin_name(pin));
423 return rc; 481 return rc;
424 } 482 }
425 dev->irq = rc; 483 dev->irq = rc;
426 484
427 if (link) 485 if (link)
428 snprintf(link_desc, sizeof(link_desc), " -> Link[%s]", link); 486 snprintf(link_desc, sizeof(link_desc), " -> Link[%s]", link);
429 else 487 else
430 link_desc[0] = '\0'; 488 link_desc[0] = '\0';
431 489
432 dev_info(&dev->dev, "PCI INT %c%s -> GSI %u (%s, %s) -> IRQ %d\n", 490 dev_info(&dev->dev, "PCI INT %c%s -> GSI %u (%s, %s) -> IRQ %d\n",
433 pin_name(pin), link_desc, gsi, 491 pin_name(pin), link_desc, gsi,
434 (triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge", 492 (triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
435 (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq); 493 (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq);
436 494
437 return 0; 495 return 0;
438 } 496 }
439 497
440 /* FIXME: implement x86/x86_64 version */ 498 /* FIXME: implement x86/x86_64 version */
441 void __attribute__ ((weak)) acpi_unregister_gsi(u32 i) 499 void __attribute__ ((weak)) acpi_unregister_gsi(u32 i)
442 { 500 {
443 } 501 }
444 502
445 void acpi_pci_irq_disable(struct pci_dev *dev) 503 void acpi_pci_irq_disable(struct pci_dev *dev)
446 { 504 {
447 struct acpi_prt_entry *entry; 505 struct acpi_prt_entry *entry;
448 int gsi; 506 int gsi;
449 u8 pin; 507 u8 pin;
450 508
451 pin = dev->pin; 509 pin = dev->pin;
452 if (!pin) 510 if (!pin)
453 return; 511 return;
454 512
455 entry = acpi_pci_irq_lookup(dev, pin); 513 entry = acpi_pci_irq_lookup(dev, pin);
456 if (!entry) 514 if (!entry)
457 return; 515 return;
458 516
459 if (entry->link) 517 if (entry->link)
460 gsi = acpi_pci_link_free_irq(entry->link); 518 gsi = acpi_pci_link_free_irq(entry->link);
461 else 519 else
462 gsi = entry->index; 520 gsi = entry->index;
463 521
464 /* 522 /*
465 * TBD: It might be worth clearing dev->irq by magic constant 523 * TBD: It might be worth clearing dev->irq by magic constant
466 * (e.g. PCI_UNDEFINED_IRQ). 524 * (e.g. PCI_UNDEFINED_IRQ).
467 */ 525 */
468 526
469 dev_info(&dev->dev, "PCI INT %c disabled\n", pin_name(pin)); 527 dev_info(&dev->dev, "PCI INT %c disabled\n", pin_name(pin));
470 acpi_unregister_gsi(gsi); 528 acpi_unregister_gsi(gsi);
471 } 529 }
472 530