[PATCH] VIA IRQ quirk
Len Brown [Fri, 27 May 2005 08:21:50 +0000 (04:21 -0400)]
Delete quirk_via_bridge(), restore quirk_via_irqpic() -- but now
improved to be invoked upon device ENABLE, and now only for VIA devices
-- not all devices behind VIA bridges.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

arch/i386/pci/irq.c
drivers/acpi/pci_irq.c
drivers/pci/quirks.c
include/linux/acpi.h

index d6598da..da21b1d 100644 (file)
@@ -1029,7 +1029,6 @@ void pcibios_penalize_isa_irq(int irq)
 static int pirq_enable_irq(struct pci_dev *dev)
 {
        u8 pin;
-       extern int via_interrupt_line_quirk;
        struct pci_dev *temp_dev;
 
        pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
@@ -1084,10 +1083,6 @@ static int pirq_enable_irq(struct pci_dev *dev)
                printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
                       'A' + pin, pci_name(dev), msg);
        }
-       /* VIA bridges use interrupt line for apic/pci steering across
-          the V-Link */
-       else if (via_interrupt_line_quirk)
-               pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq & 15);
        return 0;
 }
 
index 12b0eea..8093f2e 100644 (file)
@@ -391,7 +391,6 @@ acpi_pci_irq_enable (
        u8                      pin = 0;
        int                     edge_level = ACPI_LEVEL_SENSITIVE;
        int                     active_high_low = ACPI_ACTIVE_LOW;
-       extern int              via_interrupt_line_quirk;
        char                    *link = NULL;
 
        ACPI_FUNCTION_TRACE("acpi_pci_irq_enable");
@@ -444,9 +443,6 @@ acpi_pci_irq_enable (
                }
        }
 
-       if (via_interrupt_line_quirk)
-               pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq & 15);
-
        dev->irq = acpi_register_gsi(irq, edge_level, active_high_low);
 
        printk(KERN_INFO PREFIX "PCI Interrupt %s[%c] -> ",
index 026aa04..afc9d29 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/acpi.h>
 #include "pci.h"
 
 /* Deal with broken BIOS'es that neglect to enable passive release,
@@ -467,9 +468,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_APIC,
  * non-x86 architectures (yes Via exists on PPC among other places),
  * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get
  * interrupts delivered properly.
- *
- * TODO: When we have device-specific interrupt routers,
- * quirk_via_irqpic will go away from quirks.
  */
 
 /*
@@ -494,6 +492,29 @@ static void __devinit quirk_via_acpi(struct pci_dev *d)
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_82C586_3,     quirk_via_acpi );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_82C686_4,     quirk_via_acpi );
 
+static void __devinit quirk_via_irqpic(struct pci_dev *dev)
+{
+       u8 irq, new_irq;
+
+#ifdef CONFIG_X86_IO_APIC
+       if (nr_ioapics && !skip_ioapic_setup)
+               return;
+#endif
+#ifdef CONFIG_ACPI
+       if (acpi_irq_model != ACPI_IRQ_MODEL_PIC)
+               return;
+#endif
+       new_irq = dev->irq & 0xf;
+       pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
+       if (new_irq != irq) {
+               printk(KERN_INFO "PCI: Via PIC IRQ fixup for %s, from %d to %d\n",
+                       pci_name(dev), irq, new_irq);
+               udelay(15);     /* unknown if delay really needed */
+               pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
+       }
+}
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irqpic);
+
 /*
  * PIIX3 USB: We have to disable USB interrupts that are
  * hardwired to PIRQD# and may be shared with an
@@ -683,19 +704,6 @@ static void __init quirk_disable_pxb(struct pci_dev *pdev)
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82454NX,    quirk_disable_pxb );
 
-/*
- *     VIA northbridges care about PCI_INTERRUPT_LINE
- */
-int via_interrupt_line_quirk;
-
-static void __devinit quirk_via_bridge(struct pci_dev *pdev)
-{
-       if(pdev->devfn == 0) {
-               printk(KERN_INFO "PCI: Via IRQ fixup\n");
-               via_interrupt_line_quirk = 1;
-       }
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,    PCI_ANY_ID,                     quirk_via_bridge );
 
 /*
  *     Serverworks CSB5 IDE does not fully support native mode
index aefe6d0..d5a55bd 100644 (file)
@@ -25,6 +25,8 @@
 #ifndef _LINUX_ACPI_H
 #define _LINUX_ACPI_H
 
+#ifdef CONFIG_ACPI
+
 #ifndef _LINUX
 #define _LINUX
 #endif
@@ -533,4 +535,5 @@ static inline int acpi_get_pxm(acpi_handle handle)
 
 extern int pnpacpi_disabled;
 
-#endif /*_LINUX_ACPI_H*/
+#endif /* CONFIG_ACPI */
+#endif /*_LINUX_ACPI_H*/