]> git.hungrycats.org Git - linux/commitdiff
[PATCH] x86 clock override boot option
authorAndrew Morton <akpm@digeo.com>
Fri, 28 Mar 2003 11:19:37 +0000 (03:19 -0800)
committerDave Jones <davej@tetrachloride.(none)>
Fri, 28 Mar 2003 11:19:37 +0000 (03:19 -0800)
From: john stultz <johnstul@us.ibm.com>

This patch allows one to manually specify the i386 gettimeofday time-source
by passing clock=[pit|tsc|cyclone|...] as a boot argument.  The argument will
override the default probled selection, and in case the selected time-source
not be avalible the code defaults to using the PIT (printing a warning saying
so).

Documentation/kernel-parameters.txt
arch/i386/kernel/smpboot.c
arch/i386/kernel/timers/timer.c
arch/i386/kernel/timers/timer_cyclone.c
arch/i386/kernel/timers/timer_none.c
arch/i386/kernel/timers/timer_pit.c
arch/i386/kernel/timers/timer_tsc.c
include/asm-i386/timer.h

index 1e0b17303ed12e6fd7897037b3e8bfaf4b0ceb02..2d87a0293cb558eab3542a0f67ef50dba79ff25a 100644 (file)
@@ -207,6 +207,12 @@ running once the system is up.
 
        chandev=        [HW,NET] Generic channel device initialisation
  
+       clock=          [BUGS=IA-32, HW] gettimeofday timesource override. 
+                       Forces specified timesource (if avaliable) to be used
+                       when calculating gettimeofday(). If specicified timesource
+                       is not avalible, it defaults to PIT. 
+                       Format: { pit | tsc | cyclone | ... }
+                       
        cm206=          [HW,CD]
                        Format: { auto | [<io>,][<irq>] }
 
index 803c3fb80911ce5bf948686bff69faf3a691a30d..861c9831b5b115acc7bff247608cd60cb2e806a0 100644 (file)
@@ -422,7 +422,7 @@ void __init smp_callin(void)
        /*
         *      Synchronize the TSC with the BP
         */
-       if (cpu_has_tsc)
+       if (cpu_has_tsc && cpu_khz)
                synchronize_tsc_ap();
 }
 
@@ -1114,7 +1114,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
        /*
         * Synchronize the TSC with the AP
         */
-       if (cpu_has_tsc && cpucount)
+       if (cpu_has_tsc && cpucount && cpu_khz)
                synchronize_tsc_bp();
 }
 
index c8c2c4f72f0c475a142578c7926b26a1316dac6f..fc23421ead742e5aa71ff4d4908bdfcf86ee5c28 100644 (file)
@@ -1,4 +1,6 @@
+#include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/string.h>
 #include <asm/timer.h>
 
 /* list of externed timers */
@@ -17,6 +19,17 @@ static struct timer_opts* timers[] = {
        NULL,
 };
 
+static char clock_override[10] __initdata;
+
+static int __init clock_setup(char* str)
+{
+       if (str) {
+               strncpy(clock_override, str,10);
+               clock_override[9] = '\0';
+       }
+       return 1;
+}
+__setup("clock=", clock_setup);
 
 /* iterates through the list of timers, returning the first 
  * one that initializes successfully.
@@ -28,7 +41,7 @@ struct timer_opts* select_timer(void)
        /* find most preferred working timer */
        while (timers[i]) {
                if (timers[i]->init)
-                       if (timers[i]->init() == 0)
+                       if (timers[i]->init(clock_override) == 0)
                                return timers[i];
                ++i;
        }
index a1bac8e00e0fdfdc47a19e5dd715a9b00f3416ed..54a5026487f8c00b4ac98de49194035c5fee06c1 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/init.h>
 #include <linux/timex.h>
 #include <linux/errno.h>
+#include <linux/string.h>
 
 #include <asm/timer.h>
 #include <asm/io.h>
@@ -73,7 +74,7 @@ static unsigned long get_offset_cyclone(void)
        return delay_at_last_interrupt + offset;
 }
 
-static int init_cyclone(void)
+static int __init init_cyclone(char* override)
 {
        u32* reg;       
        u32 base;               /* saved cyclone base address */
@@ -81,8 +82,11 @@ static int init_cyclone(void)
        u32 offset;             /* offset from pageaddr to cyclone_timer register */
        int i;
        
+       /* check clock override */
+       if (override[0] && strncmp(override,"cyclone",7))
+                       return -ENODEV;
+
        /*make sure we're on a summit box*/
-       /*XXX need to use proper summit hooks! such as xapic -john*/
        if(!use_cyclone) return -ENODEV; 
        
        printk(KERN_INFO "Summit chipset: Starting Cyclone Counter.\n");
index 786ac5bc560cd80a1c0a2f3ffc87acb7bb097af6..5367a601e1e3c0d2b50ac2a76b601ead482515c1 100644 (file)
@@ -1,6 +1,7 @@
+#include <linux/init.h>
 #include <asm/timer.h>
 
-static int init_none(void)
+static int __init init_none(char* override)
 {
        return 0;
 }
index 8b9507e70e05440ae26f1130372d6c49fd9cc7e8..d9c97e5a97444f91c6e93ad1c27400c8e8ab9015 100644 (file)
@@ -17,8 +17,12 @@ extern spinlock_t i8259A_lock;
 extern spinlock_t i8253_lock;
 #include "do_timer.h"
 
-static int init_pit(void)
+static int __init init_pit(char* override)
 {
+       /* check clock override */
+       if (override[0] && strncmp(override,"pit",3))
+               printk(KERN_ERR "Warning: clock= override failed. Defaulting to PIT\n");
+
        return 0;
 }
 
index 264a20f9b96b363a26ae9f3a5054fc727bd9b156..8292e481527f1cb6a90ec20a59099af2f169896a 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/timex.h>
 #include <linux/errno.h>
 #include <linux/cpufreq.h>
+#include <linux/string.h>
 
 #include <asm/timer.h>
 #include <asm/io.h>
@@ -244,8 +245,13 @@ static struct notifier_block time_cpufreq_notifier_block = {
 #endif
 
 
-static int init_tsc(void)
+static int __init init_tsc(char* override)
 {
+
+       /* check clock override */
+       if (override[0] && strncmp(override,"tsc",3))
+                       return -ENODEV;
+
        /*
         * If we have APM enabled or the CPU clock speed is variable
         * (CPU stops clock on HLT or slows clock to save power)
index 749ee25b89999ab15bfa5623aecebf04a7364584..2384ec395c9ad22f276ae1b5e42350308d831201 100644 (file)
@@ -4,14 +4,14 @@
 /**
  * struct timer_ops - used to define a timer source
  *
- * @init: Probes and initializes the timer.  Returns 0 on success, anything
- *     else on failure.
+ * @init: Probes and initializes the timer. Takes clock= override 
+ *  string as an argument. Returns 0 on success, anything else on failure.
  * @mark_offset: called by the timer interrupt
  * @get_offset: called by gettimeofday().  Returns the number of ms since the
  *     last timer intruupt.
  */
 struct timer_opts{
-       int (*init)(void);
+       int (*init)(char *override);
        void (*mark_offset)(void);
        unsigned long (*get_offset)(void);
        void (*delay)(unsigned long);