| From stable-bounces@linux.kernel.org Sat Jul 21 08:11:18 2007 |
| From: Thomas Gleixner <tglx@linutronix.de> |
| Date: Sat, 21 Jul 2007 17:11:12 +0200 (CEST) |
| Subject: i386: HPET, check if the counter works |
| To: tglx@linutronix.de, ak@suse.de, johnstul@us.ibm.com, stable@kernel.org, torvalds@osdl.org |
| Message-ID: <20070721151112.29090147AA@wotan.suse.de> |
| |
| From: Thomas Gleixner <tglx@linutronix.de> |
| |
| Some systems have a HPET which is not incrementing, which leads to a |
| complete hang. Detect it during HPET setup. |
| |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Signed-off-by: Andi Kleen <ak@suse.de> |
| Cc: john stultz <johnstul@us.ibm.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| arch/i386/kernel/hpet.c | 24 +++++++++++++++++++++++- |
| 1 file changed, 23 insertions(+), 1 deletion(-) |
| |
| --- a/arch/i386/kernel/hpet.c |
| +++ b/arch/i386/kernel/hpet.c |
| @@ -226,7 +226,8 @@ int __init hpet_enable(void) |
| { |
| unsigned long id; |
| uint64_t hpet_freq; |
| - u64 tmp; |
| + u64 tmp, start, now; |
| + cycle_t t1; |
| |
| if (!is_hpet_capable()) |
| return 0; |
| @@ -273,6 +274,27 @@ int __init hpet_enable(void) |
| /* Start the counter */ |
| hpet_start_counter(); |
| |
| + /* Verify whether hpet counter works */ |
| + t1 = read_hpet(); |
| + rdtscll(start); |
| + |
| + /* |
| + * We don't know the TSC frequency yet, but waiting for |
| + * 200000 TSC cycles is safe: |
| + * 4 GHz == 50us |
| + * 1 GHz == 200us |
| + */ |
| + do { |
| + rep_nop(); |
| + rdtscll(now); |
| + } while ((now - start) < 200000UL); |
| + |
| + if (t1 == read_hpet()) { |
| + printk(KERN_WARNING |
| + "HPET counter not counting. HPET disabled\n"); |
| + goto out_nohpet; |
| + } |
| + |
| /* Initialize and register HPET clocksource |
| * |
| * hpet period is in femto seconds per cycle |