summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>2007-12-03 17:17:10 +0100
committerIngo Molnar <mingo@elte.hu>2007-12-03 17:17:10 +0100
commitc86c7fbc829e27e2a4093f98ded9fbd75e515adb (patch)
tree310d217b4b2e582d84798e65dac309f1d173f1ad
parent92d499d991ec4f5cbd00d6f33967eab9d3ee8d6c (diff)
x86: disable hpet on shutdown
If HPET was enabled by pci quirks, we use i8253 as initial clockevent because pci quirks doesn't run until pci is initialized. The above means the kernel (or something) is assuming HPET legacy replacement is disabled and can use i8253 at boot. If we used kexec, it isn't true. So, this patch disables HPET legacy replacement for kexec in machine_shutdown(). Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> Acked-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--arch/x86/kernel/hpet.c14
-rw-r--r--arch/x86/kernel/reboot_32.c4
-rw-r--r--arch/x86/kernel/reboot_64.c4
-rw-r--r--include/asm-x86/hpet.h1
4 files changed, 23 insertions, 0 deletions
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 53303f2e5475..4a86ffd67ec5 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -446,6 +446,20 @@ static __init int hpet_late_init(void)
}
fs_initcall(hpet_late_init);
+void hpet_disable(void)
+{
+ if (is_hpet_capable()) {
+ unsigned long cfg = hpet_readl(HPET_CFG);
+
+ if (hpet_legacy_int_enabled) {
+ cfg &= ~HPET_CFG_LEGACY;
+ hpet_legacy_int_enabled = 0;
+ }
+ cfg &= ~HPET_CFG_ENABLE;
+ hpet_writel(cfg, HPET_CFG);
+ }
+}
+
#ifdef CONFIG_HPET_EMULATE_RTC
/* HPET in LegacyReplacement Mode eats up RTC interrupt line. When, HPET
diff --git a/arch/x86/kernel/reboot_32.c b/arch/x86/kernel/reboot_32.c
index 9e2269d00918..bb1a0f889c5e 100644
--- a/arch/x86/kernel/reboot_32.c
+++ b/arch/x86/kernel/reboot_32.c
@@ -11,6 +11,7 @@
#include <linux/reboot.h>
#include <asm/uaccess.h>
#include <asm/apic.h>
+#include <asm/hpet.h>
#include <asm/desc.h>
#include "mach_reboot.h"
#include <asm/reboot_fixups.h>
@@ -326,6 +327,9 @@ static void native_machine_shutdown(void)
#ifdef CONFIG_X86_IO_APIC
disable_IO_APIC();
#endif
+#ifdef CONFIG_HPET_TIMER
+ hpet_disable();
+#endif
}
void __attribute__((weak)) mach_reboot_fixups(void)
diff --git a/arch/x86/kernel/reboot_64.c b/arch/x86/kernel/reboot_64.c
index 71b13c5f5817..53620a92a8fd 100644
--- a/arch/x86/kernel/reboot_64.c
+++ b/arch/x86/kernel/reboot_64.c
@@ -17,6 +17,7 @@
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
#include <asm/apic.h>
+#include <asm/hpet.h>
#include <asm/gart.h>
/*
@@ -113,6 +114,9 @@ void machine_shutdown(void)
disable_IO_APIC();
+#ifdef CONFIG_HPET_TIMER
+ hpet_disable();
+#endif
local_irq_restore(flags);
pci_iommu_shutdown();
diff --git a/include/asm-x86/hpet.h b/include/asm-x86/hpet.h
index b1f3c1ea55d9..ad8d6e758785 100644
--- a/include/asm-x86/hpet.h
+++ b/include/asm-x86/hpet.h
@@ -61,6 +61,7 @@ extern unsigned long force_hpet_address;
extern int hpet_force_user;
extern int is_hpet_enabled(void);
extern int hpet_enable(void);
+extern void hpet_disable(void);
extern unsigned long hpet_readl(unsigned long a);
extern void force_hpet_resume(void);