Commit 5958cbab authored by Andrew Morton's avatar Andrew Morton Committed by Dave Jones

[PATCH] x86 clock override boot option

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).
parent 3a2631da
......@@ -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>] }
......
......@@ -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();
}
......
#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;
}
......
......@@ -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");
......
#include <linux/init.h>
#include <asm/timer.h>
static int init_none(void)
static int __init init_none(char* override)
{
return 0;
}
......
......@@ -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;
}
......
......@@ -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)
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment