[PATCH] [7/45] x86_64: Replace nvidia timer override quirk with pci id list and unify quirks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux