aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/pci_irq.c
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-08-09 11:51:35 -0400
committerDavid Woodhouse <dwmw2@shinybook.infradead.org>2005-08-09 11:51:35 -0400
commitc973b112c76c9d8fd042991128f218a738cc8d0a (patch)
treee813b0da5d0a0e19e06de6462d145a29ad683026 /drivers/acpi/pci_irq.c
parentc5fbc3966f48279dbebfde10248c977014aa9988 (diff)
parent00dd1e433967872f3997a45d5adf35056fdf2f56 (diff)
Merge with /shiny/git/linux-2.6/.git
Diffstat (limited to 'drivers/acpi/pci_irq.c')
-rw-r--r--drivers/acpi/pci_irq.c85
1 files changed, 59 insertions, 26 deletions
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index d1f42b972821..bb973d2109a1 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -269,7 +269,51 @@ acpi_pci_irq_del_prt (int segment, int bus)
269/* -------------------------------------------------------------------------- 269/* --------------------------------------------------------------------------
270 PCI Interrupt Routing Support 270 PCI Interrupt Routing Support
271 -------------------------------------------------------------------------- */ 271 -------------------------------------------------------------------------- */
272typedef int (*irq_lookup_func)(struct acpi_prt_entry *, int *, int *, char **);
272 273
274static int
275acpi_pci_allocate_irq(struct acpi_prt_entry *entry,
276 int *edge_level,
277 int *active_high_low,
278 char **link)
279{
280 int irq;
281
282 ACPI_FUNCTION_TRACE("acpi_pci_allocate_irq");
283
284 if (entry->link.handle) {
285 irq = acpi_pci_link_allocate_irq(entry->link.handle,
286 entry->link.index, edge_level, active_high_low, link);
287 if (irq < 0) {
288 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n"));
289 return_VALUE(-1);
290 }
291 } else {
292 irq = entry->link.index;
293 *edge_level = ACPI_LEVEL_SENSITIVE;
294 *active_high_low = ACPI_ACTIVE_LOW;
295 }
296
297 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq));
298 return_VALUE(irq);
299}
300
301static int
302acpi_pci_free_irq(struct acpi_prt_entry *entry,
303 int *edge_level,
304 int *active_high_low,
305 char **link)
306{
307 int irq;
308
309 ACPI_FUNCTION_TRACE("acpi_pci_free_irq");
310 if (entry->link.handle) {
311 irq = acpi_pci_link_free_irq(entry->link.handle);
312 } else {
313 irq = entry->link.index;
314 }
315 return_VALUE(irq);
316}
273/* 317/*
274 * acpi_pci_irq_lookup 318 * acpi_pci_irq_lookup
275 * success: return IRQ >= 0 319 * success: return IRQ >= 0
@@ -282,12 +326,13 @@ acpi_pci_irq_lookup (
282 int pin, 326 int pin,
283 int *edge_level, 327 int *edge_level,
284 int *active_high_low, 328 int *active_high_low,
285 char **link) 329 char **link,
330 irq_lookup_func func)
286{ 331{
287 struct acpi_prt_entry *entry = NULL; 332 struct acpi_prt_entry *entry = NULL;
288 int segment = pci_domain_nr(bus); 333 int segment = pci_domain_nr(bus);
289 int bus_nr = bus->number; 334 int bus_nr = bus->number;
290 int irq; 335 int ret;
291 336
292 ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup"); 337 ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup");
293 338
@@ -301,22 +346,8 @@ acpi_pci_irq_lookup (
301 return_VALUE(-1); 346 return_VALUE(-1);
302 } 347 }
303 348
304 if (entry->link.handle) { 349 ret = func(entry, edge_level, active_high_low, link);
305 irq = acpi_pci_link_get_irq(entry->link.handle, 350 return_VALUE(ret);
306 entry->link.index, edge_level, active_high_low, link);
307 if (irq < 0) {
308 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n"));
309 return_VALUE(-1);
310 }
311 } else {
312 irq = entry->link.index;
313 *edge_level = ACPI_LEVEL_SENSITIVE;
314 *active_high_low = ACPI_ACTIVE_LOW;
315 }
316
317 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq));
318
319 return_VALUE(irq);
320} 351}
321 352
322/* 353/*
@@ -330,7 +361,8 @@ acpi_pci_irq_derive (
330 int pin, 361 int pin,
331 int *edge_level, 362 int *edge_level,
332 int *active_high_low, 363 int *active_high_low,
333 char **link) 364 char **link,
365 irq_lookup_func func)
334{ 366{
335 struct pci_dev *bridge = dev; 367 struct pci_dev *bridge = dev;
336 int irq = -1; 368 int irq = -1;
@@ -363,7 +395,7 @@ acpi_pci_irq_derive (
363 } 395 }
364 396
365 irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn), 397 irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn),
366 pin, edge_level, active_high_low, link); 398 pin, edge_level, active_high_low, link, func);
367 } 399 }
368 400
369 if (irq < 0) { 401 if (irq < 0) {
@@ -415,7 +447,7 @@ acpi_pci_irq_enable (
415 * values override any BIOS-assigned IRQs set during boot. 447 * values override any BIOS-assigned IRQs set during boot.
416 */ 448 */
417 irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, 449 irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
418 &edge_level, &active_high_low, &link); 450 &edge_level, &active_high_low, &link, acpi_pci_allocate_irq);
419 451
420 /* 452 /*
421 * If no PRT entry was found, we'll try to derive an IRQ from the 453 * If no PRT entry was found, we'll try to derive an IRQ from the
@@ -423,7 +455,7 @@ acpi_pci_irq_enable (
423 */ 455 */
424 if (irq < 0) 456 if (irq < 0)
425 irq = acpi_pci_irq_derive(dev, pin, &edge_level, 457 irq = acpi_pci_irq_derive(dev, pin, &edge_level,
426 &active_high_low, &link); 458 &active_high_low, &link, acpi_pci_allocate_irq);
427 459
428 /* 460 /*
429 * No IRQ known to the ACPI subsystem - maybe the BIOS / 461 * No IRQ known to the ACPI subsystem - maybe the BIOS /
@@ -462,7 +494,9 @@ acpi_pci_irq_enable (
462EXPORT_SYMBOL(acpi_pci_irq_enable); 494EXPORT_SYMBOL(acpi_pci_irq_enable);
463 495
464 496
465#ifdef CONFIG_ACPI_DEALLOCATE_IRQ 497/* FIXME: implement x86/x86_64 version */
498void __attribute__((weak)) acpi_unregister_gsi(u32 i) {}
499
466void 500void
467acpi_pci_irq_disable ( 501acpi_pci_irq_disable (
468 struct pci_dev *dev) 502 struct pci_dev *dev)
@@ -489,14 +523,14 @@ acpi_pci_irq_disable (
489 * First we check the PCI IRQ routing table (PRT) for an IRQ. 523 * First we check the PCI IRQ routing table (PRT) for an IRQ.
490 */ 524 */
491 gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, 525 gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
492 &edge_level, &active_high_low, NULL); 526 &edge_level, &active_high_low, NULL, acpi_pci_free_irq);
493 /* 527 /*
494 * If no PRT entry was found, we'll try to derive an IRQ from the 528 * If no PRT entry was found, we'll try to derive an IRQ from the
495 * device's parent bridge. 529 * device's parent bridge.
496 */ 530 */
497 if (gsi < 0) 531 if (gsi < 0)
498 gsi = acpi_pci_irq_derive(dev, pin, 532 gsi = acpi_pci_irq_derive(dev, pin,
499 &edge_level, &active_high_low, NULL); 533 &edge_level, &active_high_low, NULL, acpi_pci_free_irq);
500 if (gsi < 0) 534 if (gsi < 0)
501 return_VOID; 535 return_VOID;
502 536
@@ -512,4 +546,3 @@ acpi_pci_irq_disable (
512 546
513 return_VOID; 547 return_VOID;
514} 548}
515#endif /* CONFIG_ACPI_DEALLOCATE_IRQ */