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).

The new changes in this release are basically better whitespace and __init
usage.

I'm still tracking an issue between this and the cpu_freq code, so let me
know if it doesn't work or if you see anything terminally stupid.


 Documentation/kernel-parameters.txt     |    6 ++++++
 arch/i386/kernel/smpboot.c              |    4 ++--
 arch/i386/kernel/timers/timer.c         |   15 ++++++++++++++-
 arch/i386/kernel/timers/timer_cyclone.c |    8 ++++++--
 arch/i386/kernel/timers/timer_none.c    |    3 ++-
 arch/i386/kernel/timers/timer_pit.c     |    6 +++++-
 arch/i386/kernel/timers/timer_tsc.c     |    8 +++++++-
 include/asm-i386/timer.h                |    6 +++---
 8 files changed, 45 insertions(+), 11 deletions(-)

diff -puN arch/i386/kernel/smpboot.c~x86-clock-override-option arch/i386/kernel/smpboot.c
--- 25/arch/i386/kernel/smpboot.c~x86-clock-override-option	2003-03-22 22:14:50.000000000 -0800
+++ 25-akpm/arch/i386/kernel/smpboot.c	2003-03-22 22:14:50.000000000 -0800
@@ -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(unsigne
 	/*
 	 * Synchronize the TSC with the AP
 	 */
-	if (cpu_has_tsc && cpucount)
+	if (cpu_has_tsc && cpucount && cpu_khz)
 		synchronize_tsc_bp();
 }
 
diff -puN arch/i386/kernel/timers/timer.c~x86-clock-override-option arch/i386/kernel/timers/timer.c
--- 25/arch/i386/kernel/timers/timer.c~x86-clock-override-option	2003-03-22 22:14:50.000000000 -0800
+++ 25-akpm/arch/i386/kernel/timers/timer.c	2003-03-22 22:14:50.000000000 -0800
@@ -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;
 	}
diff -puN arch/i386/kernel/timers/timer_cyclone.c~x86-clock-override-option arch/i386/kernel/timers/timer_cyclone.c
--- 25/arch/i386/kernel/timers/timer_cyclone.c~x86-clock-override-option	2003-03-22 22:14:50.000000000 -0800
+++ 25-akpm/arch/i386/kernel/timers/timer_cyclone.c	2003-03-22 22:14:50.000000000 -0800
@@ -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(
 	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");
diff -puN arch/i386/kernel/timers/timer_none.c~x86-clock-override-option arch/i386/kernel/timers/timer_none.c
--- 25/arch/i386/kernel/timers/timer_none.c~x86-clock-override-option	2003-03-22 22:14:50.000000000 -0800
+++ 25-akpm/arch/i386/kernel/timers/timer_none.c	2003-03-22 22:14:50.000000000 -0800
@@ -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;
 }
diff -puN arch/i386/kernel/timers/timer_pit.c~x86-clock-override-option arch/i386/kernel/timers/timer_pit.c
--- 25/arch/i386/kernel/timers/timer_pit.c~x86-clock-override-option	2003-03-22 22:14:50.000000000 -0800
+++ 25-akpm/arch/i386/kernel/timers/timer_pit.c	2003-03-22 22:14:50.000000000 -0800
@@ -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;
 }
 
diff -puN arch/i386/kernel/timers/timer_tsc.c~x86-clock-override-option arch/i386/kernel/timers/timer_tsc.c
--- 25/arch/i386/kernel/timers/timer_tsc.c~x86-clock-override-option	2003-03-22 22:14:50.000000000 -0800
+++ 25-akpm/arch/i386/kernel/timers/timer_tsc.c	2003-03-22 22:14:50.000000000 -0800
@@ -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_cpufre
 #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)
diff -puN Documentation/kernel-parameters.txt~x86-clock-override-option Documentation/kernel-parameters.txt
--- 25/Documentation/kernel-parameters.txt~x86-clock-override-option	2003-03-22 22:14:50.000000000 -0800
+++ 25-akpm/Documentation/kernel-parameters.txt	2003-03-22 22:14:50.000000000 -0800
@@ -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>] }
 
diff -puN include/asm-i386/timer.h~x86-clock-override-option include/asm-i386/timer.h
--- 25/include/asm-i386/timer.h~x86-clock-override-option	2003-03-22 22:14:50.000000000 -0800
+++ 25-akpm/include/asm-i386/timer.h	2003-03-22 22:14:50.000000000 -0800
@@ -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);

_