aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>2007-12-03 11:17:10 -0500
committerIngo Molnar <mingo@elte.hu>2007-12-03 11:17:10 -0500
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 53303f2e547..4a86ffd67ec 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -446,6 +446,20 @@ static __init int hpet_late_init(void)
446} 446}
447fs_initcall(hpet_late_init); 447fs_initcall(hpet_late_init);
448 448
449void hpet_disable(void)
450{
451 if (is_hpet_capable()) {
452 unsigned long cfg = hpet_readl(HPET_CFG);
453
454 if (hpet_legacy_int_enabled) {
455 cfg &= ~HPET_CFG_LEGACY;
456 hpet_legacy_int_enabled = 0;
457 }
458 cfg &= ~HPET_CFG_ENABLE;
459 hpet_writel(cfg, HPET_CFG);
460 }
461}
462
449#ifdef CONFIG_HPET_EMULATE_RTC 463#ifdef CONFIG_HPET_EMULATE_RTC
450 464
451/* HPET in LegacyReplacement Mode eats up RTC interrupt line. When, HPET 465/* 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 9e2269d0091..bb1a0f889c5 100644
--- a/arch/x86/kernel/reboot_32.c
+++ b/arch/x86/kernel/reboot_32.c
@@ -11,6 +11,7 @@
11#include <linux/reboot.h> 11#include <linux/reboot.h>
12#include <asm/uaccess.h> 12#include <asm/uaccess.h>
13#include <asm/apic.h> 13#include <asm/apic.h>
14#include <asm/hpet.h>
14#include <asm/desc.h> 15#include <asm/desc.h>
15#include "mach_reboot.h" 16#include "mach_reboot.h"
16#include <asm/reboot_fixups.h> 17#include <asm/reboot_fixups.h>
@@ -326,6 +327,9 @@ static void native_machine_shutdown(void)
326#ifdef CONFIG_X86_IO_APIC 327#ifdef CONFIG_X86_IO_APIC
327 disable_IO_APIC(); 328 disable_IO_APIC();
328#endif 329#endif
330#ifdef CONFIG_HPET_TIMER
331 hpet_disable();
332#endif
329} 333}
330 334
331void __attribute__((weak)) mach_reboot_fixups(void) 335void __attribute__((weak)) mach_reboot_fixups(void)
diff --git a/arch/x86/kernel/reboot_64.c b/arch/x86/kernel/reboot_64.c
index 71b13c5f581..53620a92a8f 100644
--- a/arch/x86/kernel/reboot_64.c
+++ b/arch/x86/kernel/reboot_64.c
@@ -17,6 +17,7 @@
17#include <asm/pgtable.h> 17#include <asm/pgtable.h>
18#include <asm/tlbflush.h> 18#include <asm/tlbflush.h>
19#include <asm/apic.h> 19#include <asm/apic.h>
20#include <asm/hpet.h>
20#include <asm/gart.h> 21#include <asm/gart.h>
21 22
22/* 23/*
@@ -113,6 +114,9 @@ void machine_shutdown(void)
113 114
114 disable_IO_APIC(); 115 disable_IO_APIC();
115 116
117#ifdef CONFIG_HPET_TIMER
118 hpet_disable();
119#endif
116 local_irq_restore(flags); 120 local_irq_restore(flags);
117 121
118 pci_iommu_shutdown(); 122 pci_iommu_shutdown();
diff --git a/include/asm-x86/hpet.h b/include/asm-x86/hpet.h
index b1f3c1ea55d..ad8d6e75878 100644
--- a/include/asm-x86/hpet.h
+++ b/include/asm-x86/hpet.h
@@ -61,6 +61,7 @@ extern unsigned long force_hpet_address;
61extern int hpet_force_user; 61extern int hpet_force_user;
62extern int is_hpet_enabled(void); 62extern int is_hpet_enabled(void);
63extern int hpet_enable(void); 63extern int hpet_enable(void);
64extern void hpet_disable(void);
64extern unsigned long hpet_readl(unsigned long a); 65extern unsigned long hpet_readl(unsigned long a);
65extern void force_hpet_resume(void); 66extern void force_hpet_resume(void);
66 67