diff options
author | Herbert Pötzl <herbert@13thfloor.at> | 2005-01-11 01:45:29 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-01-11 01:45:29 -0800 |
commit | 840fed6be1038ea2b56b24dd9565e78013a7b138 (patch) | |
tree | db936407ceefc28689acd8f287c09db1d8ddaa54 /arch | |
parent | 42d29d5c7eb5b6e0f8364ce20f45b914e604a470 (diff) | |
download | history-840fed6be1038ea2b56b24dd9565e78013a7b138.tar.gz |
[PATCH] improved wait_8254_wraparound()
hopefully 'better' fix for broken Intel Mercury/Neptune in
wait_8254_wraparound() ...
Rationale:
changing HZ to higher values (like 5k,10k or 20k) will hang machines using
wait_8254_wraparound() indefinitely, because a suboptimal workaround for
buggy Intel Mercury/Neptune chipsets is in place.
this was tested on several machines, unfortunately none with a broken Intel
Mercury/Neptune chipset, and it works fine with various HZ values ...
Signed-off-by: Herbert Pötzl <herbert@13thfloor.at>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/kernel/apic.c | 15 |
1 files changed, 5 insertions, 10 deletions
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index df8900b1f1670a..406f5a93d01b8c 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -877,23 +877,18 @@ static unsigned int __init get_8254_timer_count(void) /* next tick in 8254 can be caught by catching timer wraparound */ static void __init wait_8254_wraparound(void) { - unsigned int curr_count, prev_count=~0; - int delta; + unsigned int curr_count, prev_count; curr_count = get_8254_timer_count(); - do { prev_count = curr_count; curr_count = get_8254_timer_count(); - delta = curr_count-prev_count; - /* - * This limit for delta seems arbitrary, but it isn't, it's - * slightly above the level of error a buggy Mercury/Neptune - * chipset timer can cause. - */ + /* workaround for broken Mercury/Neptune */ + if (prev_count >= curr_count + 0x100) + curr_count = get_8254_timer_count(); - } while (delta < 300); + } while (prev_count >= curr_count); } /* |