aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64
diff options
context:
space:
mode:
authorChris McDermott <lcm@us.ibm.com>2006-02-11 20:55:50 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-02-12 00:41:11 -0500
commit33042a9ff4d126ba944b9dc3076665a2029e0a34 (patch)
treed5cf22cebc02316058ad860feecef20742a4ae5e /arch/x86_64
parente00d82d07fb112446586d225763d3572e64b7abf (diff)
[PATCH] x86-64: Fix HPET timer on x460
[description from AK] The IBM Summit 3 chipset doesn't implement the HPET timer replacement option. Since the current Linux code relies on it use a mixed mode with both PIT for the interrupt and HPET counters for the time keeping. That was already implemented, but didn't work properly because it was still using the last interrupt offset in HPET. This resulted in x460 not booting. Fix this up by using the free running HPET counter. Shouldn't affect any other machine because they either use full HPET mode or no HPET at all. TBD needs a similar 32bit fix. Signed-off-by: Andi Kleen <ak@suse.de> Cc: Pallipadi, Venkatesh" <venkatesh.pallipadi@intel.com> Cc: Bob Picco <bob.picco@hp.com> Cc: Bjorn Helgaas <bjorn.helgaas@hp.com> Cc: john stultz <johnstul@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64')
-rw-r--r--arch/x86_64/kernel/apic.c2
-rw-r--r--arch/x86_64/kernel/time.c12
2 files changed, 10 insertions, 4 deletions
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index 6147770b4347..7a0a3e8d5d72 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -708,7 +708,7 @@ static void setup_APIC_timer(unsigned int clocks)
708 local_irq_save(flags); 708 local_irq_save(flags);
709 709
710 /* wait for irq slice */ 710 /* wait for irq slice */
711 if (vxtime.hpet_address) { 711 if (vxtime.hpet_address && hpet_use_timer) {
712 int trigger = hpet_readl(HPET_T0_CMP); 712 int trigger = hpet_readl(HPET_T0_CMP);
713 while (hpet_readl(HPET_COUNTER) >= trigger) 713 while (hpet_readl(HPET_COUNTER) >= trigger)
714 /* do nothing */ ; 714 /* do nothing */ ;
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index dba7237be5c1..3c58c30506a1 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -59,7 +59,7 @@ static int notsc __initdata = 0;
59unsigned int cpu_khz; /* TSC clocks / usec, not used here */ 59unsigned int cpu_khz; /* TSC clocks / usec, not used here */
60static unsigned long hpet_period; /* fsecs / HPET clock */ 60static unsigned long hpet_period; /* fsecs / HPET clock */
61unsigned long hpet_tick; /* HPET clocks / interrupt */ 61unsigned long hpet_tick; /* HPET clocks / interrupt */
62static int hpet_use_timer; /* Use counter of hpet for time keeping, otherwise PIT */ 62int hpet_use_timer; /* Use counter of hpet for time keeping, otherwise PIT */
63unsigned long vxtime_hz = PIT_TICK_RATE; 63unsigned long vxtime_hz = PIT_TICK_RATE;
64int report_lost_ticks; /* command line option */ 64int report_lost_ticks; /* command line option */
65unsigned long long monotonic_base; 65unsigned long long monotonic_base;
@@ -326,7 +326,10 @@ static noinline void handle_lost_ticks(int lost, struct pt_regs *regs)
326 print_symbol("rip %s\n", regs->rip); 326 print_symbol("rip %s\n", regs->rip);
327 if (vxtime.mode == VXTIME_TSC && vxtime.hpet_address) { 327 if (vxtime.mode == VXTIME_TSC && vxtime.hpet_address) {
328 printk(KERN_WARNING "Falling back to HPET\n"); 328 printk(KERN_WARNING "Falling back to HPET\n");
329 vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick; 329 if (hpet_use_timer)
330 vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick;
331 else
332 vxtime.last = hpet_readl(HPET_COUNTER);
330 vxtime.mode = VXTIME_HPET; 333 vxtime.mode = VXTIME_HPET;
331 do_gettimeoffset = do_gettimeoffset_hpet; 334 do_gettimeoffset = do_gettimeoffset_hpet;
332 } 335 }
@@ -988,7 +991,10 @@ void __init time_init_gtod(void)
988 notsc = 1; 991 notsc = 1;
989 if (vxtime.hpet_address && notsc) { 992 if (vxtime.hpet_address && notsc) {
990 timetype = hpet_use_timer ? "HPET" : "PIT/HPET"; 993 timetype = hpet_use_timer ? "HPET" : "PIT/HPET";
991 vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick; 994 if (hpet_use_timer)
995 vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick;
996 else
997 vxtime.last = hpet_readl(HPET_COUNTER);
992 vxtime.mode = VXTIME_HPET; 998 vxtime.mode = VXTIME_HPET;
993 do_gettimeoffset = do_gettimeoffset_hpet; 999 do_gettimeoffset = do_gettimeoffset_hpet;
994#ifdef CONFIG_X86_PM_TIMER 1000#ifdef CONFIG_X86_PM_TIMER