--- arch/alpha/kernel/time.c.orig Thu Jul 5 12:18:48 2001 +++ arch/alpha/kernel/time.c Thu Jul 5 12:24:11 2001 @@ -174,13 +174,12 @@ * arch/i386/time.c. */ -#define CALIBRATE_LATCH (52 * LATCH) -#define CALIBRATE_TIME (52 * 1000020 / HZ) +#define CALIBRATE_LATCH 0xffff static unsigned long __init calibrate_cc_with_pic(void) { - int cc; + unsigned int cc; unsigned long count = 0; /* Set the Gate high, disable speaker */ @@ -191,39 +190,24 @@ * * Set the Gate high, program CTC channel 2 for mode 0, * (interrupt on terminal count mode), binary count, - * load 5 * LATCH count, (LSB and MSB) to begin countdown. + * load maximum divisor we can get for accuracy - 65535 */ outb(0xb0, 0x43); /* binary, mode 0, LSB/MSB, Ch 2 */ outb(CALIBRATE_LATCH & 0xff, 0x42); /* LSB of count */ outb(CALIBRATE_LATCH >> 8, 0x42); /* MSB of count */ - - cc = rpcc(); - do { - count++; - } while ((inb(0x61) & 0x20) == 0); + + /* we still should not hang if timer not runing or N/A */ + for (cc = rpcc(); (inb(0x61) & 0x20) == 0 && !(count >> 32); count++); + + /* cycles delta */ cc = rpcc() - cc; - - /* Error: ECTCNEVERSET */ - if (count <= 1) - goto bad_ctc; - - /* Error: ECPUTOOFAST */ - if (count >> 32) - goto bad_ctc; - - /* Error: ECPUTOOSLOW */ - if (cc <= CALIBRATE_TIME) - goto bad_ctc; - - return ((long)cc * 1000000) / CALIBRATE_TIME; - - /* - * The CTC wasn't reliable: we got a hit on the very first read, - * or the CPU was so fast/slow that the quotient wouldn't fit in - * 32 bits.. - */ - bad_ctc: - return 0; + + /* check for the reliable result */ + if ((count < 1) || (count >> 32)) + return 0; + + /* and the final result in HZ */ + return ((unsigned long)cc * CLOCK_TICK_RATE) / CALIBRATE_LATCH; } /* The Linux interpretation of the CMOS clock register contents: