diff options
| -rw-r--r-- | drivers/acpi/pci_irq.c | 93 |
1 files changed, 36 insertions, 57 deletions
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 7978c97afb0a..28338227dd5e 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
| @@ -339,8 +339,6 @@ void acpi_pci_irq_del_prt(int segment, int bus) | |||
| 339 | /* -------------------------------------------------------------------------- | 339 | /* -------------------------------------------------------------------------- |
| 340 | PCI Interrupt Routing Support | 340 | PCI Interrupt Routing Support |
| 341 | -------------------------------------------------------------------------- */ | 341 | -------------------------------------------------------------------------- */ |
| 342 | typedef int (*irq_lookup_func) (struct acpi_prt_entry *, int *, int *, char **); | ||
| 343 | |||
| 344 | static int | 342 | static int |
| 345 | acpi_pci_allocate_irq(struct acpi_prt_entry *entry, | 343 | acpi_pci_allocate_irq(struct acpi_prt_entry *entry, |
| 346 | int *triggering, int *polarity, char **link) | 344 | int *triggering, int *polarity, char **link) |
| @@ -368,8 +366,7 @@ acpi_pci_allocate_irq(struct acpi_prt_entry *entry, | |||
| 368 | } | 366 | } |
| 369 | 367 | ||
| 370 | static int | 368 | static int |
| 371 | acpi_pci_free_irq(struct acpi_prt_entry *entry, | 369 | acpi_pci_free_irq(struct acpi_prt_entry *entry) |
| 372 | int *triggering, int *polarity, char **link) | ||
| 373 | { | 370 | { |
| 374 | int irq; | 371 | int irq; |
| 375 | 372 | ||
| @@ -381,47 +378,29 @@ acpi_pci_free_irq(struct acpi_prt_entry *entry, | |||
| 381 | return irq; | 378 | return irq; |
| 382 | } | 379 | } |
| 383 | 380 | ||
| 384 | /* | 381 | static struct acpi_prt_entry * |
| 385 | * acpi_pci_irq_lookup | 382 | acpi_pci_irq_lookup(struct pci_dev *dev, int pin) |
| 386 | * success: return IRQ >= 0 | ||
| 387 | * failure: return -1 | ||
| 388 | */ | ||
| 389 | static int | ||
| 390 | acpi_pci_irq_lookup(struct pci_dev *dev, int pin, | ||
| 391 | int *triggering, | ||
| 392 | int *polarity, char **link, irq_lookup_func func) | ||
| 393 | { | 383 | { |
| 394 | struct acpi_prt_entry *entry = NULL; | 384 | struct acpi_prt_entry *entry; |
| 395 | int ret; | ||
| 396 | |||
| 397 | 385 | ||
| 398 | entry = acpi_pci_irq_find_prt_entry(dev, pin); | 386 | entry = acpi_pci_irq_find_prt_entry(dev, pin); |
| 399 | if (!entry) { | 387 | if (!entry) { |
| 400 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No %s[%c] _PRT entry\n", | 388 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No %s[%c] _PRT entry\n", |
| 401 | pci_name(dev), pin_name(pin))); | 389 | pci_name(dev), pin_name(pin))); |
| 402 | return -1; | 390 | return NULL; |
| 403 | } | 391 | } |
| 404 | 392 | ||
| 405 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %s[%c] _PRT entry\n", | 393 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %s[%c] _PRT entry\n", |
| 406 | pci_name(dev), pin_name(pin))); | 394 | pci_name(dev), pin_name(pin))); |
| 407 | 395 | ||
| 408 | ret = func(entry, triggering, polarity, link); | 396 | return entry; |
| 409 | return ret; | ||
| 410 | } | 397 | } |
| 411 | 398 | ||
| 412 | /* | 399 | static struct acpi_prt_entry * |
| 413 | * acpi_pci_irq_derive | 400 | acpi_pci_irq_derive(struct pci_dev *dev, int pin) |
| 414 | * success: return IRQ >= 0 | ||
| 415 | * failure: return < 0 | ||
| 416 | */ | ||
| 417 | static int | ||
| 418 | acpi_pci_irq_derive(struct pci_dev *dev, | ||
| 419 | int pin, | ||
| 420 | int *triggering, | ||
| 421 | int *polarity, char **link, irq_lookup_func func) | ||
| 422 | { | 401 | { |
| 402 | struct acpi_prt_entry *entry = NULL; | ||
| 423 | struct pci_dev *bridge = dev; | 403 | struct pci_dev *bridge = dev; |
| 424 | int irq = -1; | ||
| 425 | u8 bridge_pin = 0, orig_pin = pin; | 404 | u8 bridge_pin = 0, orig_pin = pin; |
| 426 | 405 | ||
| 427 | 406 | ||
| @@ -429,7 +408,7 @@ acpi_pci_irq_derive(struct pci_dev *dev, | |||
| 429 | * Attempt to derive an IRQ for this device from a parent bridge's | 408 | * Attempt to derive an IRQ for this device from a parent bridge's |
| 430 | * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge). | 409 | * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge). |
| 431 | */ | 410 | */ |
| 432 | while (irq < 0 && bridge->bus->self) { | 411 | while (!entry && bridge->bus->self) { |
| 433 | pin = (((pin - 1) + PCI_SLOT(bridge->devfn)) % 4) + 1; | 412 | pin = (((pin - 1) + PCI_SLOT(bridge->devfn)) % 4) + 1; |
| 434 | bridge = bridge->bus->self; | 413 | bridge = bridge->bus->self; |
| 435 | 414 | ||
| @@ -440,26 +419,24 @@ acpi_pci_irq_derive(struct pci_dev *dev, | |||
| 440 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 419 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
| 441 | "No interrupt pin configured for device %s\n", | 420 | "No interrupt pin configured for device %s\n", |
| 442 | pci_name(bridge))); | 421 | pci_name(bridge))); |
| 443 | return -1; | 422 | return NULL; |
| 444 | } | 423 | } |
| 445 | pin = bridge_pin; | 424 | pin = bridge_pin; |
| 446 | } | 425 | } |
| 447 | 426 | ||
| 448 | irq = acpi_pci_irq_lookup(bridge, | 427 | entry = acpi_pci_irq_lookup(bridge, pin); |
| 449 | pin, triggering, polarity, | ||
| 450 | link, func); | ||
| 451 | } | 428 | } |
| 452 | 429 | ||
| 453 | if (irq < 0) { | 430 | if (!entry) { |
| 454 | dev_warn(&dev->dev, "can't derive routing for PCI INT %c\n", | 431 | dev_warn(&dev->dev, "can't derive routing for PCI INT %c\n", |
| 455 | pin_name(orig_pin)); | 432 | pin_name(orig_pin)); |
| 456 | return -1; | 433 | return NULL; |
| 457 | } | 434 | } |
| 458 | 435 | ||
| 459 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derived GSI %d for %s INT %c from %s\n", | 436 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Derived GSI for %s INT %c from %s\n", |
| 460 | irq, pci_name(dev), pin_name(orig_pin), pci_name(bridge))); | 437 | pci_name(dev), pin_name(orig_pin), pci_name(bridge))); |
| 461 | 438 | ||
| 462 | return irq; | 439 | return entry; |
| 463 | } | 440 | } |
| 464 | 441 | ||
| 465 | /* | 442 | /* |
| @@ -470,6 +447,7 @@ acpi_pci_irq_derive(struct pci_dev *dev, | |||
| 470 | 447 | ||
| 471 | int acpi_pci_irq_enable(struct pci_dev *dev) | 448 | int acpi_pci_irq_enable(struct pci_dev *dev) |
| 472 | { | 449 | { |
| 450 | struct acpi_prt_entry *entry; | ||
| 473 | int gsi = 0; | 451 | int gsi = 0; |
| 474 | u8 pin = 0; | 452 | u8 pin = 0; |
| 475 | int triggering = ACPI_LEVEL_SENSITIVE; | 453 | int triggering = ACPI_LEVEL_SENSITIVE; |
| @@ -491,18 +469,20 @@ int acpi_pci_irq_enable(struct pci_dev *dev) | |||
| 491 | * First we check the PCI IRQ routing table (PRT) for an IRQ. PRT | 469 | * First we check the PCI IRQ routing table (PRT) for an IRQ. PRT |
| 492 | * values override any BIOS-assigned IRQs set during boot. | 470 | * values override any BIOS-assigned IRQs set during boot. |
| 493 | */ | 471 | */ |
| 494 | gsi = acpi_pci_irq_lookup(dev, pin, | 472 | entry = acpi_pci_irq_lookup(dev, pin); |
| 495 | &triggering, &polarity, &link, | ||
| 496 | acpi_pci_allocate_irq); | ||
| 497 | 473 | ||
| 498 | /* | 474 | /* |
| 499 | * If no PRT entry was found, we'll try to derive an IRQ from the | 475 | * If no PRT entry was found, we'll try to derive an IRQ from the |
| 500 | * device's parent bridge. | 476 | * device's parent bridge. |
| 501 | */ | 477 | */ |
| 502 | if (gsi < 0) | 478 | if (!entry) |
| 503 | gsi = acpi_pci_irq_derive(dev, pin, &triggering, | 479 | entry = acpi_pci_irq_derive(dev, pin); |
| 504 | &polarity, &link, | 480 | |
| 505 | acpi_pci_allocate_irq); | 481 | if (entry) |
| 482 | gsi = acpi_pci_allocate_irq(entry, &triggering, &polarity, | ||
| 483 | &link); | ||
| 484 | else | ||
| 485 | gsi = -1; | ||
| 506 | 486 | ||
| 507 | if (gsi < 0) { | 487 | if (gsi < 0) { |
| 508 | /* | 488 | /* |
| @@ -559,10 +539,9 @@ void __attribute__ ((weak)) acpi_unregister_gsi(u32 i) | |||
| 559 | 539 | ||
| 560 | void acpi_pci_irq_disable(struct pci_dev *dev) | 540 | void acpi_pci_irq_disable(struct pci_dev *dev) |
| 561 | { | 541 | { |
| 542 | struct acpi_prt_entry *entry; | ||
| 562 | int gsi = 0; | 543 | int gsi = 0; |
| 563 | u8 pin = 0; | 544 | u8 pin = 0; |
| 564 | int triggering = ACPI_LEVEL_SENSITIVE; | ||
| 565 | int polarity = ACPI_ACTIVE_LOW; | ||
| 566 | 545 | ||
| 567 | 546 | ||
| 568 | pin = dev->pin; | 547 | pin = dev->pin; |
| @@ -572,20 +551,20 @@ void acpi_pci_irq_disable(struct pci_dev *dev) | |||
| 572 | /* | 551 | /* |
| 573 | * First we check the PCI IRQ routing table (PRT) for an IRQ. | 552 | * First we check the PCI IRQ routing table (PRT) for an IRQ. |
| 574 | */ | 553 | */ |
| 575 | gsi = acpi_pci_irq_lookup(dev, pin, | 554 | entry = acpi_pci_irq_lookup(dev, pin); |
| 576 | &triggering, &polarity, NULL, | 555 | |
| 577 | acpi_pci_free_irq); | ||
| 578 | /* | 556 | /* |
| 579 | * If no PRT entry was found, we'll try to derive an IRQ from the | 557 | * If no PRT entry was found, we'll try to derive an IRQ from the |
| 580 | * device's parent bridge. | 558 | * device's parent bridge. |
| 581 | */ | 559 | */ |
| 582 | if (gsi < 0) | 560 | if (!entry) |
| 583 | gsi = acpi_pci_irq_derive(dev, pin, | 561 | entry = acpi_pci_irq_derive(dev, pin); |
| 584 | &triggering, &polarity, NULL, | 562 | |
| 585 | acpi_pci_free_irq); | 563 | if (!entry) |
| 586 | if (gsi < 0) | ||
| 587 | return; | 564 | return; |
| 588 | 565 | ||
| 566 | gsi = acpi_pci_free_irq(entry); | ||
| 567 | |||
| 589 | /* | 568 | /* |
| 590 | * TBD: It might be worth clearing dev->irq by magic constant | 569 | * TBD: It might be worth clearing dev->irq by magic constant |
| 591 | * (e.g. PCI_UNDEFINED_IRQ). | 570 | * (e.g. PCI_UNDEFINED_IRQ). |
