Hi!

It seems there's machine where changing CPU clocks actually does
something very bad [was it keyboard freeze?].

Can the unhappy thinkpad T20 owner please step up and test this patch?

Alan, is something like this candidate for -ac series?

                                                                Pavel

--- clean//arch/i386/kernel/time.c      Mon Jan  8 22:49:35 2001
+++ linux/arch/i386/kernel/time.c       Mon Jan  8 22:43:56 2001
@@ -63,7 +63,7 @@
  */
 #include <linux/irq.h>
 
-
+extern int x86_udelay_tsc;
 unsigned long cpu_khz; /* Detected as we calibrate the TSC */
 
 /* Number of usecs that the last interrupt was delayed */
@@ -152,7 +152,7 @@
  * comp.protocols.time.ntp!
  */
 
-static unsigned long do_slow_gettimeoffset(void)
+static unsigned long do_read_hwtimer(void)
 {
        int count;
 
@@ -227,7 +227,7 @@
 
                                count -= 256;
 #else
-                               printk("do_slow_gettimeoffset(): hardware timer 
problem?\n");
+                               printk("do_read_hwtimer(): hardware timer problem?\n");
 #endif
                        }
                }
@@ -235,6 +235,12 @@
                jiffies_p = jiffies_t;
 
        count_p = count;
+       return count;
+}
+
+unsigned long do_slow_gettimeoffset(void)
+{
+       unsigned long count = do_read_hwtimer();
 
        count = ((LATCH-1) - count) * TICK_SIZE;
        count = (count + LATCH/2) / LATCH;
@@ -449,7 +455,39 @@
 #endif
 }
 
-static int use_tsc;
+int use_tsc;
+
+void big_calibrate_tsc(void)
+{
+       if (cpu_has_tsc) {
+               unsigned long tsc_quotient = calibrate_tsc();
+               if (tsc_quotient) {
+                       fast_gettimeoffset_quotient = tsc_quotient;
+                       use_tsc = 1;
+                       /*
+                        *      We could be more selective here I suspect
+                        *      and just enable this for the next intel chips ?
+                        */
+                       x86_udelay_tsc = 1;
+#ifndef do_gettimeoffset
+                       do_gettimeoffset = do_fast_gettimeoffset;
+#endif
+                       do_get_fast_time = do_gettimeofday;
+
+                       /* report CPU clock rate in Hz.
+                        * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) =
+                        * clock/second. Our precision is about 100 ppm.
+                        */
+                       {       unsigned long eax=0, edx=1000;
+                               __asm__("divl %2"
+                               :"=a" (cpu_khz), "=d" (edx)
+                               :"r" (tsc_quotient),
+                               "0" (eax), "1" (edx));
+                               printk("Detected %lu.%03lu MHz processor.\n", cpu_khz 
+/ 1000, cpu_khz % 1000);
+                       }
+               } else { printk( "Failed to detect CPU Hz.\n" ); use_tsc = 0; }
+       } else use_tsc = 0;
+}
 
 /*
  * This is the same as the above, except we _also_ save the current
@@ -469,6 +507,28 @@
         */
        write_lock(&xtime_lock);
 
+       if (use_tsc) {
+               long off = do_gettimeoffset();
+               /* Damn, kapmd plays hell with this. We'd need to busy loop in timer 
+interrupt to calibrate reliably. */ 
+               static int faster = 0, slower = 0;
+               if (off > (1100000/HZ))
+                       faster++;
+               else
+                       faster = 0;
+
+               if (off < (900000/HZ))
+                       slower++;
+               else
+                       slower = 0;
+
+               if ((faster > 10) || (slower > 10)) {
+                       printk( KERN_ERR "TSC is %s than it should be! ", (faster > 
+10) ? "faster" : "slower" );
+                       big_calibrate_tsc();
+                       faster = 0;
+                       slower = 0;
+               }
+       }
+
        if (use_tsc)
        {
                /*
@@ -558,7 +618,7 @@
 #define CALIBRATE_LATCH        (5 * LATCH)
 #define CALIBRATE_TIME (5 * 1000020/HZ)
 
-static unsigned long __init calibrate_tsc(void)
+static unsigned long calibrate_tsc(void)
 {
        /* Set the Gate high, disable speaker */
        outb((inb(0x61) & ~0x02) | 0x01, 0x61);
@@ -625,8 +685,6 @@
 
 void __init time_init(void)
 {
-       extern int x86_udelay_tsc;
-       
        xtime.tv_sec = get_cmos_time();
        xtime.tv_usec = 0;
 
@@ -657,34 +715,7 @@
  
        dodgy_tsc();
        
-       if (cpu_has_tsc) {
-               unsigned long tsc_quotient = calibrate_tsc();
-               if (tsc_quotient) {
-                       fast_gettimeoffset_quotient = tsc_quotient;
-                       use_tsc = 1;
-                       /*
-                        *      We could be more selective here I suspect
-                        *      and just enable this for the next intel chips ?
-                        */
-                       x86_udelay_tsc = 1;
-#ifndef do_gettimeoffset
-                       do_gettimeoffset = do_fast_gettimeoffset;
-#endif
-                       do_get_fast_time = do_gettimeofday;
-
-                       /* report CPU clock rate in Hz.
-                        * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) =
-                        * clock/second. Our precision is about 100 ppm.
-                        */
-                       {       unsigned long eax=0, edx=1000;
-                               __asm__("divl %2"
-                               :"=a" (cpu_khz), "=d" (edx)
-                               :"r" (tsc_quotient),
-                               "0" (eax), "1" (edx));
-                               printk("Detected %lu.%03lu MHz processor.\n", cpu_khz 
/ 1000, cpu_khz % 1000);
-                       }
-               }
-       }
+       big_calibrate_tsc();
 
 #ifdef CONFIG_VISWS
        printk("Starting Cobalt Timer system clock\n");

-- 
I'm [EMAIL PROTECTED] "In my country we have almost anarchy and I don't care."
Panos Katsaloulis describing me w.r.t. patents at [EMAIL PROTECTED]
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to