aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRavikiran G Thirumalai <kiran@scalex86.org>2007-04-13 19:28:20 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-04-15 00:44:03 -0400
commitc9c57929d23e44f258d1b6e7f089e72c85f0bd1c (patch)
tree423990aed32fc6f8e1add83ec2d8976c8e9a81e9
parentff99e40230d5cdf5e48bcdb4938d0626624bc4cb (diff)
failsafe mechanism to HPET clock calibration
Provide a failsafe mechanism to avoid kernel spinning forever at read_hpet_tsc during early kernel bootup. This failsafe mechanism was originally introduced in commit 2f7a2a79c3ebb44f8b1b7d9b4fd3a650eb69e544, but looks like the hpet split from time.c lost it again. This reintroduces the failsafe mechanism Signed-off-by: Ravikiran Thirumalai <kiran@scalex86.org> Signed-off-by: Shai Fultheim <shai@scalex86.org> Cc: Jack Steiner <steiner@sgi.com> Cc: john stultz <johnstul@us.ibm.com> Cc: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/x86_64/kernel/hpet.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/arch/x86_64/kernel/hpet.c b/arch/x86_64/kernel/hpet.c
index 8cf0b8a13778..b8286968662d 100644
--- a/arch/x86_64/kernel/hpet.c
+++ b/arch/x86_64/kernel/hpet.c
@@ -191,6 +191,7 @@ int hpet_reenable(void)
191 191
192#define TICK_COUNT 100000000 192#define TICK_COUNT 100000000
193#define TICK_MIN 5000 193#define TICK_MIN 5000
194#define MAX_TRIES 5
194 195
195/* 196/*
196 * Some platforms take periodic SMI interrupts with 5ms duration. Make sure none 197 * Some platforms take periodic SMI interrupts with 5ms duration. Make sure none
@@ -198,13 +199,15 @@ int hpet_reenable(void)
198 */ 199 */
199static void __init read_hpet_tsc(int *hpet, int *tsc) 200static void __init read_hpet_tsc(int *hpet, int *tsc)
200{ 201{
201 int tsc1, tsc2, hpet1; 202 int tsc1, tsc2, hpet1, i;
202 203
203 do { 204 for (i = 0; i < MAX_TRIES; i++) {
204 tsc1 = get_cycles_sync(); 205 tsc1 = get_cycles_sync();
205 hpet1 = hpet_readl(HPET_COUNTER); 206 hpet1 = hpet_readl(HPET_COUNTER);
206 tsc2 = get_cycles_sync(); 207 tsc2 = get_cycles_sync();
207 } while (tsc2 - tsc1 > TICK_MIN); 208 if (tsc2 - tsc1 > TICK_MIN)
209 break;
210 }
208 *hpet = hpet1; 211 *hpet = hpet1;
209 *tsc = tsc2; 212 *tsc = tsc2;
210} 213}