[PATCH] Move early chipset quirks out to new file
authorAndi Kleen <ak@suse.de>
Tue, 26 Sep 2006 08:52:30 +0000 (10:52 +0200)
committerAndi Kleen <andi@basil.nowhere.org>
Tue, 26 Sep 2006 08:52:30 +0000 (10:52 +0200)
They did not really belong into io_apic.c. Move them into a new file
and clean it up a bit.

Also remove outdated ATI quirk that was obsolete,

Signed-off-by: Andi Kleen <ak@suse.de>
arch/x86_64/kernel/Makefile
arch/x86_64/kernel/early-quirks.c [new file with mode: 0644]
arch/x86_64/kernel/io_apic.c
arch/x86_64/kernel/setup.c
include/asm-x86_64/proto.h

index 0ef3955..000e67e 100644 (file)
@@ -8,7 +8,7 @@ obj-y   := process.o signal.o entry.o traps.o irq.o \
                ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \
                x8664_ksyms.o i387.o syscall.o vsyscall.o \
                setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \
-               pci-dma.o pci-nommu.o alternative.o
+               pci-dma.o pci-nommu.o alternative.o early-quirks.o
 
 obj-$(CONFIG_STACKTRACE)       += stacktrace.o
 obj-$(CONFIG_X86_MCE)         += mce.o
diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c
new file mode 100644 (file)
index 0000000..d637cff
--- /dev/null
@@ -0,0 +1,118 @@
+/* Various workarounds for chipset bugs.
+   This code runs very early and can't use the regular PCI subsystem
+   The entries are keyed to PCI bridges which usually identify chipsets
+   uniquely.
+   This is only for whole classes of chipsets with specific problems which
+   need early invasive action (e.g. before the timers are initialized).
+   Most PCI device specific workarounds can be done later and should be
+   in standard PCI quirks
+   Mainboard specific bugs should be handled by DMI entries.
+   CPU specific bugs in setup.c */
+
+#include <linux/pci.h>
+#include <linux/acpi.h>
+#include <linux/pci_ids.h>
+#include <asm/pci-direct.h>
+#include <asm/proto.h>
+#include <asm/dma.h>
+
+static void via_bugs(void)
+{
+#ifdef CONFIG_IOMMU
+       if ((end_pfn > MAX_DMA32_PFN ||  force_iommu) &&
+           !iommu_aperture_allowed) {
+               printk(KERN_INFO
+  "Looks like a VIA chipset. Disabling IOMMU. Override with iommu=allowed\n");
+               iommu_aperture_disabled = 1;
+       }
+#endif
+}
+
+#ifdef CONFIG_ACPI
+
+static int nvidia_hpet_detected __initdata;
+
+static int __init nvidia_hpet_check(unsigned long phys, unsigned long size)
+{
+       nvidia_hpet_detected = 1;
+       return 0;
+}
+#endif
+
+static void nvidia_bugs(void)
+{
+#ifdef CONFIG_ACPI
+       /*
+        * All timer overrides on Nvidia are
+        * wrong unless HPET is enabled.
+        */
+       nvidia_hpet_detected = 0;
+       acpi_table_parse(ACPI_HPET, nvidia_hpet_check);
+       if (nvidia_hpet_detected == 0) {
+               acpi_skip_timer_override = 1;
+               printk(KERN_INFO "Nvidia board "
+                      "detected. Ignoring ACPI "
+                      "timer override.\n");
+       }
+#endif
+       /* RED-PEN skip them on mptables too? */
+
+}
+
+static void ati_bugs(void)
+{
+#if 1 /* for testing */
+       printk("ATI board detected\n");
+#endif
+       /* No bugs right now */
+}
+
+struct chipset {
+       u16 vendor;
+       void (*f)(void);
+};
+
+static struct chipset early_qrk[] = {
+       { PCI_VENDOR_ID_NVIDIA, nvidia_bugs },
+       { PCI_VENDOR_ID_VIA, via_bugs },
+       { PCI_VENDOR_ID_ATI, ati_bugs },
+       {}
+};
+
+void __init early_quirks(void)
+{
+       int num, slot, func;
+       /* Poor man's PCI discovery */
+       for (num = 0; num < 32; num++) {
+               for (slot = 0; slot < 32; slot++) {
+                       for (func = 0; func < 8; func++) {
+                               u32 class;
+                               u32 vendor;
+                               u8 type;
+                               int i;
+                               class = read_pci_config(num,slot,func,
+                                                       PCI_CLASS_REVISION);
+                               if (class == 0xffffffff)
+                                       break;
+
+                               if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
+                                       continue;
+
+                               vendor = read_pci_config(num, slot, func,
+                                                        PCI_VENDOR_ID);
+                               vendor &= 0xffff;
+
+                               for (i = 0; early_qrk[i].f; i++)
+                                       if (early_qrk[i].vendor == vendor) {
+                                               early_qrk[i].f();
+                                               return;
+                                       }
+
+                               type = read_pci_config_byte(num, slot, func,
+                                                           PCI_HEADER_TYPE);
+                               if (!(type & 0x80))
+                                       break;
+                       }
+               }
+       }
+}
index a02ed17..8bbff64 100644 (file)
@@ -280,107 +280,6 @@ static int __init setup_enable_8254_timer(char *s)
 __setup("disable_8254_timer", setup_disable_8254_timer);
 __setup("enable_8254_timer", setup_enable_8254_timer);
 
-#include <asm/pci-direct.h>
-#include <linux/pci_ids.h>
-#include <linux/pci.h>
-
-
-#ifdef CONFIG_ACPI
-
-static int nvidia_hpet_detected __initdata;
-
-static int __init nvidia_hpet_check(unsigned long phys, unsigned long size)
-{
-       nvidia_hpet_detected = 1;
-       return 0;
-}
-#endif
-
-/* Temporary Hack. Nvidia and VIA boards currently only work with IO-APIC
-   off. Check for an Nvidia or VIA PCI bridge and turn it off.
-   Use pci direct infrastructure because this runs before the PCI subsystem. 
-
-   Can be overwritten with "apic"
-
-   And another hack to disable the IOMMU on VIA chipsets.
-
-   ... and others. Really should move this somewhere else.
-
-   Kludge-O-Rama. */
-void __init check_ioapic(void) 
-{ 
-       int num,slot,func; 
-       /* Poor man's PCI discovery */
-       for (num = 0; num < 32; num++) { 
-               for (slot = 0; slot < 32; slot++) { 
-                       for (func = 0; func < 8; func++) { 
-                               u32 class;
-                               u32 vendor;
-                               u8 type;
-                               class = read_pci_config(num,slot,func,
-                                                       PCI_CLASS_REVISION);
-                               if (class == 0xffffffff)
-                                       break; 
-
-                               if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
-                                       continue; 
-
-                               vendor = read_pci_config(num, slot, func, 
-                                                        PCI_VENDOR_ID);
-                               vendor &= 0xffff;
-                               switch (vendor) { 
-                               case PCI_VENDOR_ID_VIA:
-#ifdef CONFIG_IOMMU
-                                       if ((end_pfn > MAX_DMA32_PFN ||
-                                            force_iommu) &&
-                                           !iommu_aperture_allowed) {
-                                               printk(KERN_INFO
-    "Looks like a VIA chipset. Disabling IOMMU. Override with \"iommu=allowed\"\n");
-                                               iommu_aperture_disabled = 1;
-                                       }
-#endif
-                                       return;
-                               case PCI_VENDOR_ID_NVIDIA:
-#ifdef CONFIG_ACPI
-                                       /*
-                                        * All timer overrides on Nvidia are
-                                        * wrong unless HPET is enabled.
-                                        */
-                                       nvidia_hpet_detected = 0;
-                                       acpi_table_parse(ACPI_HPET,
-                                                       nvidia_hpet_check);
-                                       if (nvidia_hpet_detected == 0) {
-                                               acpi_skip_timer_override = 1;
-                                               printk(KERN_INFO "Nvidia board "
-                                                   "detected. Ignoring ACPI "
-                                                   "timer override.\n");
-                                       }
-#endif
-                                       /* RED-PEN skip them on mptables too? */
-                                       return;
-
-                               /* This should be actually default, but
-                                  for 2.6.16 let's do it for ATI only where
-                                  it's really needed. */
-                               case PCI_VENDOR_ID_ATI:
-                                       if (timer_over_8254 == 1) {     
-                                               timer_over_8254 = 0;    
-                                       printk(KERN_INFO
-               "ATI board detected. Disabling timer routing over 8254.\n");
-                                       }       
-                                       return;
-                               } 
-
-
-                               /* No multi-function device? */
-                               type = read_pci_config_byte(num,slot,func,
-                                                           PCI_HEADER_TYPE);
-                               if (!(type & 0x80))
-                                       break;
-                       } 
-               }
-       }
-} 
 
 /*
  * Find the IRQ entry number of a certain pin.
index fbe9f7f..aab4bd6 100644 (file)
@@ -653,7 +653,7 @@ void __init setup_arch(char **cmdline_p)
 
        paging_init();
 
-       check_ioapic();
+       early_quirks();
 
        /*
         * set this early, so we dont allocate cpu0
index 3b1c602..58fec91 100644 (file)
@@ -92,7 +92,7 @@ extern void syscall32_cpu_init(void);
 
 extern void setup_node_bootmem(int nodeid, unsigned long start, unsigned long end);
 
-extern void check_ioapic(void);
+extern void early_quirks(void);
 extern void check_efer(void);
 
 extern int unhandled_signal(struct task_struct *tsk, int sig);