Browse Source

[PATCH] Fix HPET operation on 64-bit NVIDIA platforms

From: "Andy Currid" <ACurrid@nvidia.com>

This patch fixes a kernel panic during boot that occurs on NVIDIA platforms
that have HPET enabled.

When HPET is enabled, the standard timer IRQ is routed to IOAPIC pin 2 and is
advertised as such in the ACPI APIC table - but an earlier workaround in the
kernel was ignoring this override.  The fix is to honor timer IRQ overrides
from ACPI when HPET is detected on an NVIDIA platform.

Signed-off-by: Andy Currid <acurrid@nvidia.com>
Cc: "Brown, Len" <len.brown@intel.com>
Cc: "Yu, Luming" <luming.yu@intel.com>
Cc: Andi Kleen <ak@muc.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Andy Currid 19 years ago
parent
commit
a2ef3a50f1
1 changed files with 25 additions and 5 deletions
  1. 25 5
      arch/x86_64/kernel/io_apic.c

+ 25 - 5
arch/x86_64/kernel/io_apic.c

@@ -271,6 +271,18 @@ __setup("enable_8254_timer", setup_enable_8254_timer);
 #include <linux/pci_ids.h>
 #include <linux/pci_ids.h>
 #include <linux/pci.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
 /* 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.
    off. Check for an Nvidia or VIA PCI bridge and turn it off.
    Use pci direct infrastructure because this runs before the PCI subsystem. 
    Use pci direct infrastructure because this runs before the PCI subsystem. 
@@ -317,11 +329,19 @@ void __init check_ioapic(void)
 					return;
 					return;
 				case PCI_VENDOR_ID_NVIDIA:
 				case PCI_VENDOR_ID_NVIDIA:
 #ifdef CONFIG_ACPI
 #ifdef CONFIG_ACPI
-					/* All timer overrides on Nvidia
-				           seem to be wrong. Skip them. */
-					acpi_skip_timer_override = 1;
-					printk(KERN_INFO 
-	     "Nvidia board detected. Ignoring ACPI timer override.\n");
+					/*
+					 * 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
 #endif
 					/* RED-PEN skip them on mptables too? */
 					/* RED-PEN skip them on mptables too? */
 					return;
 					return;