This replaces the old NF3/NF4 reference BIOS timer override quirk with a device 
ID list. We need to ignore the timer override on these systems, but not 
ignore it on NF5 based systems. Previously this was distingushed by checking
for HPET, but a lot of BIOS vendors didn't enable HPET in their pre Vista 
BIOSes.
Replace the old "for all of nvidia" quirk with a quirk containing pci device
ID. I goobled this list together from pci.ids and googling and it may be 
incomplete.

I'm still not 100% sure the list is correct, but the only way
to find out is to do testing in mainline. So let's do that.

Signed-off-by: Andi Kleen <[EMAIL PROTECTED]>

---
 arch/x86_64/kernel/early-quirks.c |   50 ++++++++++++++++++--------------------
 1 file changed, 24 insertions(+), 26 deletions(-)

Index: linux/arch/x86_64/kernel/early-quirks.c
===================================================================
--- linux.orig/arch/x86_64/kernel/early-quirks.c
+++ linux/arch/x86_64/kernel/early-quirks.c
@@ -33,36 +33,20 @@ static void __init via_bugs(void)
 #endif
 }
 
-#ifdef CONFIG_ACPI
-
-static int __init nvidia_hpet_check(struct acpi_table_header *header)
-{
-       return 0;
-}
-#endif
-
 static void __init nvidia_bugs(void)
 {
 #ifdef CONFIG_ACPI
 #ifdef CONFIG_X86_IO_APIC
        /*
-        * All timer overrides on Nvidia are
-        * wrong unless HPET is enabled.
-        * Unfortunately that's not true on many Asus boards.
-        * We don't know yet how to detect this automatically, but
-        * at least allow a command line override.
+        * All timer overrides on Nvidia NF3/NF4 are
+        * wrong.
         */
        if (acpi_use_timer_override)
                return;
 
-       if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check)) {
-               acpi_skip_timer_override = 1;
-               printk(KERN_INFO "Nvidia board "
-                      "detected. Ignoring ACPI "
-                      "timer override.\n");
-               printk(KERN_INFO "If you got timer trouble "
-                       "try acpi_use_timer_override\n");
-       }
+       acpi_skip_timer_override = 1;
+       printk(KERN_INFO "Nvidia board detected. Ignoring ACPI timer 
override.\n");
+       printk(KERN_INFO "If you got timer trouble try 
acpi_use_timer_override\n");
 #endif
 #endif
        /* RED-PEN skip them on mptables too? */
@@ -83,10 +67,19 @@ static void __init ati_bugs(void)
 struct chipset {
        u16 vendor;
        void (*f)(void);
+       int id;
 };
 
 static struct chipset early_qrk[] __initdata = {
-       { PCI_VENDOR_ID_NVIDIA, nvidia_bugs },
+       /* This list should cover at least one PCI ID from each NF3 or NF4
+          mainboard to handle a bug in their reference BIOS. May be 
incomplete. */
+       { PCI_VENDOR_ID_NVIDIA, nvidia_bugs, 0x00dd },  /* nforce 3 */
+       { PCI_VENDOR_ID_NVIDIA, nvidia_bugs, 0x00e1 },  /* nforce 3 */
+       { PCI_VENDOR_ID_NVIDIA, nvidia_bugs, 0x00ed },  /* nforce 3 */
+       { PCI_VENDOR_ID_NVIDIA, nvidia_bugs, 0x003d },  /* mcp 04 ?? */
+       { PCI_VENDOR_ID_NVIDIA, nvidia_bugs, 0x005c },  /* ck 804 */
+       { PCI_VENDOR_ID_NVIDIA, nvidia_bugs, 0x026f },  /* mcp 51 / nf4 ? */
+       { PCI_VENDOR_ID_NVIDIA, nvidia_bugs, 0x02f0 },  /* mcp 51 / nf4 ? */
        { PCI_VENDOR_ID_VIA, via_bugs },
        { PCI_VENDOR_ID_ATI, ati_bugs },
        {}
@@ -99,12 +92,13 @@ void __init early_quirks(void)
        if (!early_pci_allowed())
                return;
 
-       /* Poor man's PCI discovery */
+       /* Poor man's PCI discovery.
+          We just look for a chipset unique PCI bridge; not scan all devices */
        for (num = 0; num < 32; num++) {
                for (slot = 0; slot < 32; slot++) {
                        for (func = 0; func < 8; func++) {
                                u32 class;
-                               u32 vendor;
+                               u32 vendor, device;
                                u8 type;
                                int i;
                                class = read_pci_config(num,slot,func,
@@ -117,13 +111,17 @@ void __init early_quirks(void)
 
                                vendor = read_pci_config(num, slot, func,
                                                         PCI_VENDOR_ID);
+                               device = vendor >> 16;
+
                                vendor &= 0xffff;
 
-                               for (i = 0; early_qrk[i].f; i++)
-                                       if (early_qrk[i].vendor == vendor) {
+                               for (i = 0; early_qrk[i].f; i++) {
+                                       struct chipset *c = &early_qrk[i];
+                                       if (c->vendor == vendor && (!c->id || 
(c->id && c->id==device))) {
                                                early_qrk[i].f();
                                                return;
                                        }
+                               }
 
                                type = read_pci_config_byte(num, slot, func,
                                                            PCI_HEADER_TYPE);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to