diff options
author | Bjorn Helgaas <bjorn.helgaas@hp.com> | 2005-06-07 16:22:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-07 16:39:26 -0400 |
commit | 93cffffa19960464a52f9c78d9a6150270d23785 (patch) | |
tree | 67341f2e824b1812fde8c68bcd1bf42f3672e612 | |
parent | a86d1f4301fad4ff44c1f614c897000bc574ab2f (diff) |
[PATCH] PCI: do VIA IRQ fixup always, not just in PIC mode
At least some VIA chipsets require the fixup even in IO-APIC mode.
This was found and debugged with the patient assistance of Stian
Jordet <liste@jordet.nu> on an Asus CUV266-DLS motherboard.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | drivers/pci/quirks.c | 35 |
1 files changed, 13 insertions, 22 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 637e9493034b..2194669300bf 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -460,17 +460,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_APIC, | |||
460 | 460 | ||
461 | 461 | ||
462 | /* | 462 | /* |
463 | * Via 686A/B: The PCI_INTERRUPT_LINE register for the on-chip | ||
464 | * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature: | ||
465 | * when written, it makes an internal connection to the PIC. | ||
466 | * For these devices, this register is defined to be 4 bits wide. | ||
467 | * Normally this is fine. However for IO-APIC motherboards, or | ||
468 | * non-x86 architectures (yes Via exists on PPC among other places), | ||
469 | * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get | ||
470 | * interrupts delivered properly. | ||
471 | */ | ||
472 | |||
473 | /* | ||
474 | * FIXME: it is questionable that quirk_via_acpi | 463 | * FIXME: it is questionable that quirk_via_acpi |
475 | * is needed. It shows up as an ISA bridge, and does not | 464 | * is needed. It shows up as an ISA bridge, and does not |
476 | * support the PCI_INTERRUPT_LINE register at all. Therefore | 465 | * support the PCI_INTERRUPT_LINE register at all. Therefore |
@@ -492,28 +481,30 @@ static void __devinit quirk_via_acpi(struct pci_dev *d) | |||
492 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi ); | 481 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi ); |
493 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi ); | 482 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi ); |
494 | 483 | ||
495 | static void quirk_via_irqpic(struct pci_dev *dev) | 484 | /* |
485 | * Via 686A/B: The PCI_INTERRUPT_LINE register for the on-chip | ||
486 | * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature: | ||
487 | * when written, it makes an internal connection to the PIC. | ||
488 | * For these devices, this register is defined to be 4 bits wide. | ||
489 | * Normally this is fine. However for IO-APIC motherboards, or | ||
490 | * non-x86 architectures (yes Via exists on PPC among other places), | ||
491 | * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get | ||
492 | * interrupts delivered properly. | ||
493 | */ | ||
494 | static void quirk_via_irq(struct pci_dev *dev) | ||
496 | { | 495 | { |
497 | u8 irq, new_irq; | 496 | u8 irq, new_irq; |
498 | 497 | ||
499 | #ifdef CONFIG_X86_IO_APIC | ||
500 | if (nr_ioapics && !skip_ioapic_setup) | ||
501 | return; | ||
502 | #endif | ||
503 | #ifdef CONFIG_ACPI | ||
504 | if (acpi_irq_model != ACPI_IRQ_MODEL_PIC) | ||
505 | return; | ||
506 | #endif | ||
507 | new_irq = dev->irq & 0xf; | 498 | new_irq = dev->irq & 0xf; |
508 | pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); | 499 | pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); |
509 | if (new_irq != irq) { | 500 | if (new_irq != irq) { |
510 | printk(KERN_INFO "PCI: Via PIC IRQ fixup for %s, from %d to %d\n", | 501 | printk(KERN_INFO "PCI: Via IRQ fixup for %s, from %d to %d\n", |
511 | pci_name(dev), irq, new_irq); | 502 | pci_name(dev), irq, new_irq); |
512 | udelay(15); /* unknown if delay really needed */ | 503 | udelay(15); /* unknown if delay really needed */ |
513 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); | 504 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); |
514 | } | 505 | } |
515 | } | 506 | } |
516 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irqpic); | 507 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq); |
517 | 508 | ||
518 | /* | 509 | /* |
519 | * PIIX3 USB: We have to disable USB interrupts that are | 510 | * PIIX3 USB: We have to disable USB interrupts that are |