diff options
Diffstat (limited to 'drivers/acpi/pci_irq.c')
-rw-r--r-- | drivers/acpi/pci_irq.c | 275 |
1 files changed, 133 insertions, 142 deletions
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index bb973d2109a1..09567c2edcfb 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
@@ -38,26 +38,22 @@ | |||
38 | #include <acpi/acpi_bus.h> | 38 | #include <acpi/acpi_bus.h> |
39 | #include <acpi/acpi_drivers.h> | 39 | #include <acpi/acpi_drivers.h> |
40 | 40 | ||
41 | |||
42 | #define _COMPONENT ACPI_PCI_COMPONENT | 41 | #define _COMPONENT ACPI_PCI_COMPONENT |
43 | ACPI_MODULE_NAME ("pci_irq") | 42 | ACPI_MODULE_NAME("pci_irq") |
44 | 43 | ||
45 | static struct acpi_prt_list acpi_prt; | 44 | static struct acpi_prt_list acpi_prt; |
46 | static DEFINE_SPINLOCK(acpi_prt_lock); | 45 | static DEFINE_SPINLOCK(acpi_prt_lock); |
47 | 46 | ||
48 | /* -------------------------------------------------------------------------- | 47 | /* -------------------------------------------------------------------------- |
49 | PCI IRQ Routing Table (PRT) Support | 48 | PCI IRQ Routing Table (PRT) Support |
50 | -------------------------------------------------------------------------- */ | 49 | -------------------------------------------------------------------------- */ |
51 | 50 | ||
52 | static struct acpi_prt_entry * | 51 | static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(int segment, |
53 | acpi_pci_irq_find_prt_entry ( | 52 | int bus, |
54 | int segment, | 53 | int device, int pin) |
55 | int bus, | ||
56 | int device, | ||
57 | int pin) | ||
58 | { | 54 | { |
59 | struct list_head *node = NULL; | 55 | struct list_head *node = NULL; |
60 | struct acpi_prt_entry *entry = NULL; | 56 | struct acpi_prt_entry *entry = NULL; |
61 | 57 | ||
62 | ACPI_FUNCTION_TRACE("acpi_pci_irq_find_prt_entry"); | 58 | ACPI_FUNCTION_TRACE("acpi_pci_irq_find_prt_entry"); |
63 | 59 | ||
@@ -72,10 +68,10 @@ acpi_pci_irq_find_prt_entry ( | |||
72 | spin_lock(&acpi_prt_lock); | 68 | spin_lock(&acpi_prt_lock); |
73 | list_for_each(node, &acpi_prt.entries) { | 69 | list_for_each(node, &acpi_prt.entries) { |
74 | entry = list_entry(node, struct acpi_prt_entry, node); | 70 | entry = list_entry(node, struct acpi_prt_entry, node); |
75 | if ((segment == entry->id.segment) | 71 | if ((segment == entry->id.segment) |
76 | && (bus == entry->id.bus) | 72 | && (bus == entry->id.bus) |
77 | && (device == entry->id.device) | 73 | && (device == entry->id.device) |
78 | && (pin == entry->pin)) { | 74 | && (pin == entry->pin)) { |
79 | spin_unlock(&acpi_prt_lock); | 75 | spin_unlock(&acpi_prt_lock); |
80 | return_PTR(entry); | 76 | return_PTR(entry); |
81 | } | 77 | } |
@@ -85,15 +81,11 @@ acpi_pci_irq_find_prt_entry ( | |||
85 | return_PTR(NULL); | 81 | return_PTR(NULL); |
86 | } | 82 | } |
87 | 83 | ||
88 | |||
89 | static int | 84 | static int |
90 | acpi_pci_irq_add_entry ( | 85 | acpi_pci_irq_add_entry(acpi_handle handle, |
91 | acpi_handle handle, | 86 | int segment, int bus, struct acpi_pci_routing_table *prt) |
92 | int segment, | ||
93 | int bus, | ||
94 | struct acpi_pci_routing_table *prt) | ||
95 | { | 87 | { |
96 | struct acpi_prt_entry *entry = NULL; | 88 | struct acpi_prt_entry *entry = NULL; |
97 | 89 | ||
98 | ACPI_FUNCTION_TRACE("acpi_pci_irq_add_entry"); | 90 | ACPI_FUNCTION_TRACE("acpi_pci_irq_add_entry"); |
99 | 91 | ||
@@ -139,9 +131,10 @@ acpi_pci_irq_add_entry ( | |||
139 | entry->link.index = prt->source_index; | 131 | entry->link.index = prt->source_index; |
140 | 132 | ||
141 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, | 133 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, |
142 | " %02X:%02X:%02X[%c] -> %s[%d]\n", | 134 | " %02X:%02X:%02X[%c] -> %s[%d]\n", |
143 | entry->id.segment, entry->id.bus, entry->id.device, | 135 | entry->id.segment, entry->id.bus, |
144 | ('A' + entry->pin), prt->source, entry->link.index)); | 136 | entry->id.device, ('A' + entry->pin), prt->source, |
137 | entry->link.index)); | ||
145 | 138 | ||
146 | spin_lock(&acpi_prt_lock); | 139 | spin_lock(&acpi_prt_lock); |
147 | list_add_tail(&entry->node, &acpi_prt.entries); | 140 | list_add_tail(&entry->node, &acpi_prt.entries); |
@@ -151,38 +144,29 @@ acpi_pci_irq_add_entry ( | |||
151 | return_VALUE(0); | 144 | return_VALUE(0); |
152 | } | 145 | } |
153 | 146 | ||
154 | |||
155 | static void | 147 | static void |
156 | acpi_pci_irq_del_entry ( | 148 | acpi_pci_irq_del_entry(int segment, int bus, struct acpi_prt_entry *entry) |
157 | int segment, | ||
158 | int bus, | ||
159 | struct acpi_prt_entry *entry) | ||
160 | { | 149 | { |
161 | if (segment == entry->id.segment && bus == entry->id.bus){ | 150 | if (segment == entry->id.segment && bus == entry->id.bus) { |
162 | acpi_prt.count--; | 151 | acpi_prt.count--; |
163 | list_del(&entry->node); | 152 | list_del(&entry->node); |
164 | kfree(entry); | 153 | kfree(entry); |
165 | } | 154 | } |
166 | } | 155 | } |
167 | 156 | ||
168 | 157 | int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus) | |
169 | int | ||
170 | acpi_pci_irq_add_prt ( | ||
171 | acpi_handle handle, | ||
172 | int segment, | ||
173 | int bus) | ||
174 | { | 158 | { |
175 | acpi_status status = AE_OK; | 159 | acpi_status status = AE_OK; |
176 | char *pathname = NULL; | 160 | char *pathname = NULL; |
177 | struct acpi_buffer buffer = {0, NULL}; | 161 | struct acpi_buffer buffer = { 0, NULL }; |
178 | struct acpi_pci_routing_table *prt = NULL; | 162 | struct acpi_pci_routing_table *prt = NULL; |
179 | struct acpi_pci_routing_table *entry = NULL; | 163 | struct acpi_pci_routing_table *entry = NULL; |
180 | static int first_time = 1; | 164 | static int first_time = 1; |
181 | 165 | ||
182 | ACPI_FUNCTION_TRACE("acpi_pci_irq_add_prt"); | 166 | ACPI_FUNCTION_TRACE("acpi_pci_irq_add_prt"); |
183 | 167 | ||
184 | pathname = (char *) kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); | 168 | pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); |
185 | if(!pathname) | 169 | if (!pathname) |
186 | return_VALUE(-ENOMEM); | 170 | return_VALUE(-ENOMEM); |
187 | memset(pathname, 0, ACPI_PATHNAME_MAX); | 171 | memset(pathname, 0, ACPI_PATHNAME_MAX); |
188 | 172 | ||
@@ -202,7 +186,7 @@ acpi_pci_irq_add_prt ( | |||
202 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | 186 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); |
203 | 187 | ||
204 | printk(KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n", | 188 | printk(KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n", |
205 | pathname); | 189 | pathname); |
206 | 190 | ||
207 | /* | 191 | /* |
208 | * Evaluate this _PRT and add its entries to our global list (acpi_prt). | 192 | * Evaluate this _PRT and add its entries to our global list (acpi_prt). |
@@ -214,12 +198,12 @@ acpi_pci_irq_add_prt ( | |||
214 | status = acpi_get_irq_routing_table(handle, &buffer); | 198 | status = acpi_get_irq_routing_table(handle, &buffer); |
215 | if (status != AE_BUFFER_OVERFLOW) { | 199 | if (status != AE_BUFFER_OVERFLOW) { |
216 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRT [%s]\n", | 200 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRT [%s]\n", |
217 | acpi_format_exception(status))); | 201 | acpi_format_exception(status))); |
218 | return_VALUE(-ENODEV); | 202 | return_VALUE(-ENODEV); |
219 | } | 203 | } |
220 | 204 | ||
221 | prt = kmalloc(buffer.length, GFP_KERNEL); | 205 | prt = kmalloc(buffer.length, GFP_KERNEL); |
222 | if (!prt){ | 206 | if (!prt) { |
223 | return_VALUE(-ENOMEM); | 207 | return_VALUE(-ENOMEM); |
224 | } | 208 | } |
225 | memset(prt, 0, buffer.length); | 209 | memset(prt, 0, buffer.length); |
@@ -228,7 +212,7 @@ acpi_pci_irq_add_prt ( | |||
228 | status = acpi_get_irq_routing_table(handle, &buffer); | 212 | status = acpi_get_irq_routing_table(handle, &buffer); |
229 | if (ACPI_FAILURE(status)) { | 213 | if (ACPI_FAILURE(status)) { |
230 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRT [%s]\n", | 214 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRT [%s]\n", |
231 | acpi_format_exception(status))); | 215 | acpi_format_exception(status))); |
232 | kfree(buffer.pointer); | 216 | kfree(buffer.pointer); |
233 | return_VALUE(-ENODEV); | 217 | return_VALUE(-ENODEV); |
234 | } | 218 | } |
@@ -238,7 +222,7 @@ acpi_pci_irq_add_prt ( | |||
238 | while (entry && (entry->length > 0)) { | 222 | while (entry && (entry->length > 0)) { |
239 | acpi_pci_irq_add_entry(handle, segment, bus, entry); | 223 | acpi_pci_irq_add_entry(handle, segment, bus, entry); |
240 | entry = (struct acpi_pci_routing_table *) | 224 | entry = (struct acpi_pci_routing_table *) |
241 | ((unsigned long) entry + entry->length); | 225 | ((unsigned long)entry + entry->length); |
242 | } | 226 | } |
243 | 227 | ||
244 | kfree(prt); | 228 | kfree(prt); |
@@ -246,18 +230,18 @@ acpi_pci_irq_add_prt ( | |||
246 | return_VALUE(0); | 230 | return_VALUE(0); |
247 | } | 231 | } |
248 | 232 | ||
249 | void | 233 | void acpi_pci_irq_del_prt(int segment, int bus) |
250 | acpi_pci_irq_del_prt (int segment, int bus) | ||
251 | { | 234 | { |
252 | struct list_head *node = NULL, *n = NULL; | 235 | struct list_head *node = NULL, *n = NULL; |
253 | struct acpi_prt_entry *entry = NULL; | 236 | struct acpi_prt_entry *entry = NULL; |
254 | 237 | ||
255 | if (!acpi_prt.count) { | 238 | if (!acpi_prt.count) { |
256 | return; | 239 | return; |
257 | } | 240 | } |
258 | 241 | ||
259 | printk(KERN_DEBUG "ACPI: Delete PCI Interrupt Routing Table for %x:%x\n", | 242 | printk(KERN_DEBUG |
260 | segment, bus); | 243 | "ACPI: Delete PCI Interrupt Routing Table for %x:%x\n", segment, |
244 | bus); | ||
261 | spin_lock(&acpi_prt_lock); | 245 | spin_lock(&acpi_prt_lock); |
262 | list_for_each_safe(node, n, &acpi_prt.entries) { | 246 | list_for_each_safe(node, n, &acpi_prt.entries) { |
263 | entry = list_entry(node, struct acpi_prt_entry, node); | 247 | entry = list_entry(node, struct acpi_prt_entry, node); |
@@ -266,26 +250,27 @@ acpi_pci_irq_del_prt (int segment, int bus) | |||
266 | } | 250 | } |
267 | spin_unlock(&acpi_prt_lock); | 251 | spin_unlock(&acpi_prt_lock); |
268 | } | 252 | } |
253 | |||
269 | /* -------------------------------------------------------------------------- | 254 | /* -------------------------------------------------------------------------- |
270 | PCI Interrupt Routing Support | 255 | PCI Interrupt Routing Support |
271 | -------------------------------------------------------------------------- */ | 256 | -------------------------------------------------------------------------- */ |
272 | typedef int (*irq_lookup_func)(struct acpi_prt_entry *, int *, int *, char **); | 257 | typedef int (*irq_lookup_func) (struct acpi_prt_entry *, int *, int *, char **); |
273 | 258 | ||
274 | static int | 259 | static int |
275 | acpi_pci_allocate_irq(struct acpi_prt_entry *entry, | 260 | acpi_pci_allocate_irq(struct acpi_prt_entry *entry, |
276 | int *edge_level, | 261 | int *edge_level, int *active_high_low, char **link) |
277 | int *active_high_low, | ||
278 | char **link) | ||
279 | { | 262 | { |
280 | int irq; | 263 | int irq; |
281 | 264 | ||
282 | ACPI_FUNCTION_TRACE("acpi_pci_allocate_irq"); | 265 | ACPI_FUNCTION_TRACE("acpi_pci_allocate_irq"); |
283 | 266 | ||
284 | if (entry->link.handle) { | 267 | if (entry->link.handle) { |
285 | irq = acpi_pci_link_allocate_irq(entry->link.handle, | 268 | irq = acpi_pci_link_allocate_irq(entry->link.handle, |
286 | entry->link.index, edge_level, active_high_low, link); | 269 | entry->link.index, edge_level, |
270 | active_high_low, link); | ||
287 | if (irq < 0) { | 271 | if (irq < 0) { |
288 | ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n")); | 272 | ACPI_DEBUG_PRINT((ACPI_DB_WARN, |
273 | "Invalid IRQ link routing entry\n")); | ||
289 | return_VALUE(-1); | 274 | return_VALUE(-1); |
290 | } | 275 | } |
291 | } else { | 276 | } else { |
@@ -300,11 +285,9 @@ acpi_pci_allocate_irq(struct acpi_prt_entry *entry, | |||
300 | 285 | ||
301 | static int | 286 | static int |
302 | acpi_pci_free_irq(struct acpi_prt_entry *entry, | 287 | acpi_pci_free_irq(struct acpi_prt_entry *entry, |
303 | int *edge_level, | 288 | int *edge_level, int *active_high_low, char **link) |
304 | int *active_high_low, | ||
305 | char **link) | ||
306 | { | 289 | { |
307 | int irq; | 290 | int irq; |
308 | 291 | ||
309 | ACPI_FUNCTION_TRACE("acpi_pci_free_irq"); | 292 | ACPI_FUNCTION_TRACE("acpi_pci_free_irq"); |
310 | if (entry->link.handle) { | 293 | if (entry->link.handle) { |
@@ -314,38 +297,36 @@ acpi_pci_free_irq(struct acpi_prt_entry *entry, | |||
314 | } | 297 | } |
315 | return_VALUE(irq); | 298 | return_VALUE(irq); |
316 | } | 299 | } |
300 | |||
317 | /* | 301 | /* |
318 | * acpi_pci_irq_lookup | 302 | * acpi_pci_irq_lookup |
319 | * success: return IRQ >= 0 | 303 | * success: return IRQ >= 0 |
320 | * failure: return -1 | 304 | * failure: return -1 |
321 | */ | 305 | */ |
322 | static int | 306 | static int |
323 | acpi_pci_irq_lookup ( | 307 | acpi_pci_irq_lookup(struct pci_bus *bus, |
324 | struct pci_bus *bus, | 308 | int device, |
325 | int device, | 309 | int pin, |
326 | int pin, | 310 | int *edge_level, |
327 | int *edge_level, | 311 | int *active_high_low, char **link, irq_lookup_func func) |
328 | int *active_high_low, | ||
329 | char **link, | ||
330 | irq_lookup_func func) | ||
331 | { | 312 | { |
332 | struct acpi_prt_entry *entry = NULL; | 313 | struct acpi_prt_entry *entry = NULL; |
333 | int segment = pci_domain_nr(bus); | 314 | int segment = pci_domain_nr(bus); |
334 | int bus_nr = bus->number; | 315 | int bus_nr = bus->number; |
335 | int ret; | 316 | int ret; |
336 | 317 | ||
337 | ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup"); | 318 | ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup"); |
338 | 319 | ||
339 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 320 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
340 | "Searching for PRT entry for %02x:%02x:%02x[%c]\n", | 321 | "Searching for PRT entry for %02x:%02x:%02x[%c]\n", |
341 | segment, bus_nr, device, ('A' + pin))); | 322 | segment, bus_nr, device, ('A' + pin))); |
342 | 323 | ||
343 | entry = acpi_pci_irq_find_prt_entry(segment, bus_nr, device, pin); | 324 | entry = acpi_pci_irq_find_prt_entry(segment, bus_nr, device, pin); |
344 | if (!entry) { | 325 | if (!entry) { |
345 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "PRT entry not found\n")); | 326 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "PRT entry not found\n")); |
346 | return_VALUE(-1); | 327 | return_VALUE(-1); |
347 | } | 328 | } |
348 | 329 | ||
349 | ret = func(entry, edge_level, active_high_low, link); | 330 | ret = func(entry, edge_level, active_high_low, link); |
350 | return_VALUE(ret); | 331 | return_VALUE(ret); |
351 | } | 332 | } |
@@ -356,17 +337,14 @@ acpi_pci_irq_lookup ( | |||
356 | * failure: return < 0 | 337 | * failure: return < 0 |
357 | */ | 338 | */ |
358 | static int | 339 | static int |
359 | acpi_pci_irq_derive ( | 340 | acpi_pci_irq_derive(struct pci_dev *dev, |
360 | struct pci_dev *dev, | 341 | int pin, |
361 | int pin, | 342 | int *edge_level, |
362 | int *edge_level, | 343 | int *active_high_low, char **link, irq_lookup_func func) |
363 | int *active_high_low, | ||
364 | char **link, | ||
365 | irq_lookup_func func) | ||
366 | { | 344 | { |
367 | struct pci_dev *bridge = dev; | 345 | struct pci_dev *bridge = dev; |
368 | int irq = -1; | 346 | int irq = -1; |
369 | u8 bridge_pin = 0; | 347 | u8 bridge_pin = 0; |
370 | 348 | ||
371 | ACPI_FUNCTION_TRACE("acpi_pci_irq_derive"); | 349 | ACPI_FUNCTION_TRACE("acpi_pci_irq_derive"); |
372 | 350 | ||
@@ -383,28 +361,33 @@ acpi_pci_irq_derive ( | |||
383 | 361 | ||
384 | if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) { | 362 | if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) { |
385 | /* PC card has the same IRQ as its cardbridge */ | 363 | /* PC card has the same IRQ as its cardbridge */ |
386 | pci_read_config_byte(bridge, PCI_INTERRUPT_PIN, &bridge_pin); | 364 | pci_read_config_byte(bridge, PCI_INTERRUPT_PIN, |
365 | &bridge_pin); | ||
387 | if (!bridge_pin) { | 366 | if (!bridge_pin) { |
388 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 367 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
389 | "No interrupt pin configured for device %s\n", pci_name(bridge))); | 368 | "No interrupt pin configured for device %s\n", |
369 | pci_name(bridge))); | ||
390 | return_VALUE(-1); | 370 | return_VALUE(-1); |
391 | } | 371 | } |
392 | /* Pin is from 0 to 3 */ | 372 | /* Pin is from 0 to 3 */ |
393 | bridge_pin --; | 373 | bridge_pin--; |
394 | pin = bridge_pin; | 374 | pin = bridge_pin; |
395 | } | 375 | } |
396 | 376 | ||
397 | irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn), | 377 | irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn), |
398 | pin, edge_level, active_high_low, link, func); | 378 | pin, edge_level, active_high_low, |
379 | link, func); | ||
399 | } | 380 | } |
400 | 381 | ||
401 | if (irq < 0) { | 382 | if (irq < 0) { |
402 | ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to derive IRQ for device %s\n", pci_name(dev))); | 383 | ACPI_DEBUG_PRINT((ACPI_DB_WARN, |
384 | "Unable to derive IRQ for device %s\n", | ||
385 | pci_name(dev))); | ||
403 | return_VALUE(-1); | 386 | return_VALUE(-1); |
404 | } | 387 | } |
405 | 388 | ||
406 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derive IRQ %d for device %s from %s\n", | 389 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derive IRQ %d for device %s from %s\n", |
407 | irq, pci_name(dev), pci_name(bridge))); | 390 | irq, pci_name(dev), pci_name(bridge))); |
408 | 391 | ||
409 | return_VALUE(irq); | 392 | return_VALUE(irq); |
410 | } | 393 | } |
@@ -415,30 +398,32 @@ acpi_pci_irq_derive ( | |||
415 | * failure: return < 0 | 398 | * failure: return < 0 |
416 | */ | 399 | */ |
417 | 400 | ||
418 | int | 401 | int acpi_pci_irq_enable(struct pci_dev *dev) |
419 | acpi_pci_irq_enable ( | ||
420 | struct pci_dev *dev) | ||
421 | { | 402 | { |
422 | int irq = 0; | 403 | int irq = 0; |
423 | u8 pin = 0; | 404 | u8 pin = 0; |
424 | int edge_level = ACPI_LEVEL_SENSITIVE; | 405 | int edge_level = ACPI_LEVEL_SENSITIVE; |
425 | int active_high_low = ACPI_ACTIVE_LOW; | 406 | int active_high_low = ACPI_ACTIVE_LOW; |
426 | char *link = NULL; | 407 | char *link = NULL; |
408 | int rc; | ||
427 | 409 | ||
428 | ACPI_FUNCTION_TRACE("acpi_pci_irq_enable"); | 410 | ACPI_FUNCTION_TRACE("acpi_pci_irq_enable"); |
429 | 411 | ||
430 | if (!dev) | 412 | if (!dev) |
431 | return_VALUE(-EINVAL); | 413 | return_VALUE(-EINVAL); |
432 | 414 | ||
433 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); | 415 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); |
434 | if (!pin) { | 416 | if (!pin) { |
435 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No interrupt pin configured for device %s\n", pci_name(dev))); | 417 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
418 | "No interrupt pin configured for device %s\n", | ||
419 | pci_name(dev))); | ||
436 | return_VALUE(0); | 420 | return_VALUE(0); |
437 | } | 421 | } |
438 | pin--; | 422 | pin--; |
439 | 423 | ||
440 | if (!dev->bus) { | 424 | if (!dev->bus) { |
441 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid (NULL) 'bus' field\n")); | 425 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
426 | "Invalid (NULL) 'bus' field\n")); | ||
442 | return_VALUE(-ENODEV); | 427 | return_VALUE(-ENODEV); |
443 | } | 428 | } |
444 | 429 | ||
@@ -446,69 +431,76 @@ acpi_pci_irq_enable ( | |||
446 | * First we check the PCI IRQ routing table (PRT) for an IRQ. PRT | 431 | * First we check the PCI IRQ routing table (PRT) for an IRQ. PRT |
447 | * values override any BIOS-assigned IRQs set during boot. | 432 | * values override any BIOS-assigned IRQs set during boot. |
448 | */ | 433 | */ |
449 | irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, | 434 | irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, |
450 | &edge_level, &active_high_low, &link, acpi_pci_allocate_irq); | 435 | &edge_level, &active_high_low, &link, |
436 | acpi_pci_allocate_irq); | ||
451 | 437 | ||
452 | /* | 438 | /* |
453 | * If no PRT entry was found, we'll try to derive an IRQ from the | 439 | * If no PRT entry was found, we'll try to derive an IRQ from the |
454 | * device's parent bridge. | 440 | * device's parent bridge. |
455 | */ | 441 | */ |
456 | if (irq < 0) | 442 | if (irq < 0) |
457 | irq = acpi_pci_irq_derive(dev, pin, &edge_level, | 443 | irq = acpi_pci_irq_derive(dev, pin, &edge_level, |
458 | &active_high_low, &link, acpi_pci_allocate_irq); | 444 | &active_high_low, &link, |
459 | 445 | acpi_pci_allocate_irq); | |
446 | |||
460 | /* | 447 | /* |
461 | * No IRQ known to the ACPI subsystem - maybe the BIOS / | 448 | * No IRQ known to the ACPI subsystem - maybe the BIOS / |
462 | * driver reported one, then use it. Exit in any case. | 449 | * driver reported one, then use it. Exit in any case. |
463 | */ | 450 | */ |
464 | if (irq < 0) { | 451 | if (irq < 0) { |
465 | printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: no GSI", | 452 | printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: no GSI", |
466 | pci_name(dev), ('A' + pin)); | 453 | pci_name(dev), ('A' + pin)); |
467 | /* Interrupt Line values above 0xF are forbidden */ | 454 | /* Interrupt Line values above 0xF are forbidden */ |
468 | if (dev->irq > 0 && (dev->irq <= 0xF)) { | 455 | if (dev->irq > 0 && (dev->irq <= 0xF)) { |
469 | printk(" - using IRQ %d\n", dev->irq); | 456 | printk(" - using IRQ %d\n", dev->irq); |
470 | acpi_register_gsi(dev->irq, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW); | 457 | acpi_register_gsi(dev->irq, ACPI_LEVEL_SENSITIVE, |
458 | ACPI_ACTIVE_LOW); | ||
471 | return_VALUE(0); | 459 | return_VALUE(0); |
472 | } | 460 | } else { |
473 | else { | ||
474 | printk("\n"); | 461 | printk("\n"); |
475 | return_VALUE(0); | 462 | return_VALUE(0); |
476 | } | 463 | } |
477 | } | 464 | } |
478 | 465 | ||
479 | dev->irq = acpi_register_gsi(irq, edge_level, active_high_low); | 466 | rc = acpi_register_gsi(irq, edge_level, active_high_low); |
467 | if (rc < 0) { | ||
468 | printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: failed " | ||
469 | "to register GSI\n", pci_name(dev), ('A' + pin)); | ||
470 | return_VALUE(rc); | ||
471 | } | ||
472 | dev->irq = rc; | ||
480 | 473 | ||
481 | printk(KERN_INFO PREFIX "PCI Interrupt %s[%c] -> ", | 474 | printk(KERN_INFO PREFIX "PCI Interrupt %s[%c] -> ", |
482 | pci_name(dev), 'A' + pin); | 475 | pci_name(dev), 'A' + pin); |
483 | 476 | ||
484 | if (link) | 477 | if (link) |
485 | printk("Link [%s] -> ", link); | 478 | printk("Link [%s] -> ", link); |
486 | 479 | ||
487 | printk("GSI %u (%s, %s) -> IRQ %d\n", irq, | 480 | printk("GSI %u (%s, %s) -> IRQ %d\n", irq, |
488 | (edge_level == ACPI_LEVEL_SENSITIVE) ? "level" : "edge", | 481 | (edge_level == ACPI_LEVEL_SENSITIVE) ? "level" : "edge", |
489 | (active_high_low == ACPI_ACTIVE_LOW) ? "low" : "high", | 482 | (active_high_low == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq); |
490 | dev->irq); | ||
491 | 483 | ||
492 | return_VALUE(0); | 484 | return_VALUE(0); |
493 | } | 485 | } |
494 | EXPORT_SYMBOL(acpi_pci_irq_enable); | ||
495 | 486 | ||
487 | EXPORT_SYMBOL(acpi_pci_irq_enable); | ||
496 | 488 | ||
497 | /* FIXME: implement x86/x86_64 version */ | 489 | /* FIXME: implement x86/x86_64 version */ |
498 | void __attribute__((weak)) acpi_unregister_gsi(u32 i) {} | 490 | void __attribute__ ((weak)) acpi_unregister_gsi(u32 i) |
491 | { | ||
492 | } | ||
499 | 493 | ||
500 | void | 494 | void acpi_pci_irq_disable(struct pci_dev *dev) |
501 | acpi_pci_irq_disable ( | ||
502 | struct pci_dev *dev) | ||
503 | { | 495 | { |
504 | int gsi = 0; | 496 | int gsi = 0; |
505 | u8 pin = 0; | 497 | u8 pin = 0; |
506 | int edge_level = ACPI_LEVEL_SENSITIVE; | 498 | int edge_level = ACPI_LEVEL_SENSITIVE; |
507 | int active_high_low = ACPI_ACTIVE_LOW; | 499 | int active_high_low = ACPI_ACTIVE_LOW; |
508 | 500 | ||
509 | ACPI_FUNCTION_TRACE("acpi_pci_irq_disable"); | 501 | ACPI_FUNCTION_TRACE("acpi_pci_irq_disable"); |
510 | 502 | ||
511 | if (!dev) | 503 | if (!dev || !dev->bus) |
512 | return_VOID; | 504 | return_VOID; |
513 | 505 | ||
514 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); | 506 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); |
@@ -516,21 +508,20 @@ acpi_pci_irq_disable ( | |||
516 | return_VOID; | 508 | return_VOID; |
517 | pin--; | 509 | pin--; |
518 | 510 | ||
519 | if (!dev->bus) | ||
520 | return_VOID; | ||
521 | |||
522 | /* | 511 | /* |
523 | * First we check the PCI IRQ routing table (PRT) for an IRQ. | 512 | * First we check the PCI IRQ routing table (PRT) for an IRQ. |
524 | */ | 513 | */ |
525 | gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, | 514 | gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, |
526 | &edge_level, &active_high_low, NULL, acpi_pci_free_irq); | 515 | &edge_level, &active_high_low, NULL, |
516 | acpi_pci_free_irq); | ||
527 | /* | 517 | /* |
528 | * If no PRT entry was found, we'll try to derive an IRQ from the | 518 | * If no PRT entry was found, we'll try to derive an IRQ from the |
529 | * device's parent bridge. | 519 | * device's parent bridge. |
530 | */ | 520 | */ |
531 | if (gsi < 0) | 521 | if (gsi < 0) |
532 | gsi = acpi_pci_irq_derive(dev, pin, | 522 | gsi = acpi_pci_irq_derive(dev, pin, |
533 | &edge_level, &active_high_low, NULL, acpi_pci_free_irq); | 523 | &edge_level, &active_high_low, NULL, |
524 | acpi_pci_free_irq); | ||
534 | if (gsi < 0) | 525 | if (gsi < 0) |
535 | return_VOID; | 526 | return_VOID; |
536 | 527 | ||