diff options
| author | David Woodhouse <dwmw2@shinybook.infradead.org> | 2005-08-09 11:51:35 -0400 |
|---|---|---|
| committer | David Woodhouse <dwmw2@shinybook.infradead.org> | 2005-08-09 11:51:35 -0400 |
| commit | c973b112c76c9d8fd042991128f218a738cc8d0a (patch) | |
| tree | e813b0da5d0a0e19e06de6462d145a29ad683026 /drivers/acpi/pci_irq.c | |
| parent | c5fbc3966f48279dbebfde10248c977014aa9988 (diff) | |
| parent | 00dd1e433967872f3997a45d5adf35056fdf2f56 (diff) | |
Merge with /shiny/git/linux-2.6/.git
Diffstat (limited to 'drivers/acpi/pci_irq.c')
| -rw-r--r-- | drivers/acpi/pci_irq.c | 85 |
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 | -------------------------------------------------------------------------- */ |
| 272 | typedef int (*irq_lookup_func)(struct acpi_prt_entry *, int *, int *, char **); | ||
| 272 | 273 | ||
| 274 | static int | ||
| 275 | acpi_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 | |||
| 301 | static int | ||
| 302 | acpi_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 ( | |||
| 462 | EXPORT_SYMBOL(acpi_pci_irq_enable); | 494 | EXPORT_SYMBOL(acpi_pci_irq_enable); |
| 463 | 495 | ||
| 464 | 496 | ||
| 465 | #ifdef CONFIG_ACPI_DEALLOCATE_IRQ | 497 | /* FIXME: implement x86/x86_64 version */ |
| 498 | void __attribute__((weak)) acpi_unregister_gsi(u32 i) {} | ||
| 499 | |||
| 466 | void | 500 | void |
| 467 | acpi_pci_irq_disable ( | 501 | acpi_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 */ | ||
