diff options
| author | Andy Currid <ACurrid@nvidia.com> | 2006-06-08 03:43:38 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-08 18:12:21 -0400 |
| commit | d44647b0a6e48d18a1402dfa9052d85c4fe98341 (patch) | |
| tree | b71d11af7eac501ba37d7ea45caecf5eb0a3cfe9 | |
| parent | 1def630a6a49dda5bc89dfbd86656293640456f0 (diff) | |
[PATCH] Fix HPET operation on 32-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>
| -rw-r--r-- | arch/i386/kernel/acpi/earlyquirk.c | 23 | ||||
| -rw-r--r-- | arch/i386/kernel/setup.c | 11 |
2 files changed, 27 insertions, 7 deletions
diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c index 2e3b643a4dc4..1649a175a206 100644 --- a/arch/i386/kernel/acpi/earlyquirk.c +++ b/arch/i386/kernel/acpi/earlyquirk.c | |||
| @@ -5,17 +5,34 @@ | |||
| 5 | #include <linux/init.h> | 5 | #include <linux/init.h> |
| 6 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
| 7 | #include <linux/pci.h> | 7 | #include <linux/pci.h> |
| 8 | #include <linux/acpi.h> | ||
| 9 | |||
| 8 | #include <asm/pci-direct.h> | 10 | #include <asm/pci-direct.h> |
| 9 | #include <asm/acpi.h> | 11 | #include <asm/acpi.h> |
| 10 | #include <asm/apic.h> | 12 | #include <asm/apic.h> |
| 11 | 13 | ||
| 14 | #ifdef CONFIG_ACPI | ||
| 15 | |||
| 16 | static int nvidia_hpet_detected __initdata; | ||
| 17 | |||
| 18 | static int __init nvidia_hpet_check(unsigned long phys, unsigned long size) | ||
| 19 | { | ||
| 20 | nvidia_hpet_detected = 1; | ||
| 21 | return 0; | ||
| 22 | } | ||
| 23 | #endif | ||
| 24 | |||
| 12 | static int __init check_bridge(int vendor, int device) | 25 | static int __init check_bridge(int vendor, int device) |
| 13 | { | 26 | { |
| 14 | #ifdef CONFIG_ACPI | 27 | #ifdef CONFIG_ACPI |
| 15 | /* According to Nvidia all timer overrides are bogus. Just ignore | 28 | /* According to Nvidia all timer overrides are bogus unless HPET |
| 16 | them all. */ | 29 | is enabled. */ |
| 17 | if (vendor == PCI_VENDOR_ID_NVIDIA) { | 30 | if (vendor == PCI_VENDOR_ID_NVIDIA) { |
| 18 | acpi_skip_timer_override = 1; | 31 | nvidia_hpet_detected = 0; |
| 32 | acpi_table_parse(ACPI_HPET, nvidia_hpet_check); | ||
| 33 | if (nvidia_hpet_detected == 0) { | ||
| 34 | acpi_skip_timer_override = 1; | ||
| 35 | } | ||
| 19 | } | 36 | } |
| 20 | #endif | 37 | #endif |
| 21 | if (vendor == PCI_VENDOR_ID_ATI && timer_over_8254 == 1) { | 38 | if (vendor == PCI_VENDOR_ID_ATI && timer_over_8254 == 1) { |
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 846e1639ef7c..dd6b0e3386ce 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
| @@ -1547,15 +1547,18 @@ void __init setup_arch(char **cmdline_p) | |||
| 1547 | if (efi_enabled) | 1547 | if (efi_enabled) |
| 1548 | efi_map_memmap(); | 1548 | efi_map_memmap(); |
| 1549 | 1549 | ||
| 1550 | #ifdef CONFIG_X86_IO_APIC | ||
| 1551 | check_acpi_pci(); /* Checks more than just ACPI actually */ | ||
| 1552 | #endif | ||
| 1553 | |||
| 1554 | #ifdef CONFIG_ACPI | 1550 | #ifdef CONFIG_ACPI |
| 1555 | /* | 1551 | /* |
| 1556 | * Parse the ACPI tables for possible boot-time SMP configuration. | 1552 | * Parse the ACPI tables for possible boot-time SMP configuration. |
| 1557 | */ | 1553 | */ |
| 1558 | acpi_boot_table_init(); | 1554 | acpi_boot_table_init(); |
| 1555 | #endif | ||
| 1556 | |||
| 1557 | #ifdef CONFIG_X86_IO_APIC | ||
| 1558 | check_acpi_pci(); /* Checks more than just ACPI actually */ | ||
| 1559 | #endif | ||
| 1560 | |||
| 1561 | #ifdef CONFIG_ACPI | ||
| 1559 | acpi_boot_init(); | 1562 | acpi_boot_init(); |
| 1560 | 1563 | ||
| 1561 | #if defined(CONFIG_SMP) && defined(CONFIG_X86_PC) | 1564 | #if defined(CONFIG_SMP) && defined(CONFIG_X86_PC) |
