1
0
Fork 0

Merge branch 'timers-for-linus-cleanups' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'timers-for-linus-cleanups' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  avr32: Fix typo in read_persistent_clock()
  sparc: Convert sparc to use read/update_persistent_clock
  cris: Convert cris to use read/update_persistent_clock
  m68k: Convert m68k to use read/update_persistent_clock
  m32r: Convert m32r to use read/update_peristent_clock
  blackfin: Convert blackfin to use read/update_persistent_clock
  ia64: Convert ia64 to use read/update_persistent_clock
  avr32: Convert avr32 to use read/update_persistent_clock
  h8300: Convert h8300 to use read/update_persistent_clock
  frv: Convert frv to use read/update_persistent_clock
  mn10300: Convert mn10300 to use read/update_persistent_clock
  alpha: Convert alpha to use read/update_persistent_clock
  xtensa: Fix unnecessary setting of xtime
  time: Clean up direct xtime usage in xen
wifi-calibration
Linus Torvalds 2010-05-19 17:10:06 -07:00
commit 7d02093e29
21 changed files with 137 additions and 310 deletions

View File

@ -55,6 +55,9 @@ config ARCH_USES_GETTIMEOFFSET
bool bool
default y default y
config GENERIC_CMOS_UPDATE
def_bool y
config ZONE_DMA config ZONE_DMA
bool bool
default y default y

View File

@ -75,8 +75,6 @@ static struct {
__u32 last_time; __u32 last_time;
/* ticks/cycle * 2^48 */ /* ticks/cycle * 2^48 */
unsigned long scaled_ticks_per_cycle; unsigned long scaled_ticks_per_cycle;
/* last time the CMOS clock got updated */
time_t last_rtc_update;
/* partial unused tick */ /* partial unused tick */
unsigned long partial_tick; unsigned long partial_tick;
} state; } state;
@ -91,6 +89,52 @@ static inline __u32 rpcc(void)
return result; return result;
} }
int update_persistent_clock(struct timespec now)
{
return set_rtc_mmss(now.tv_sec);
}
void read_persistent_clock(struct timespec *ts)
{
unsigned int year, mon, day, hour, min, sec, epoch;
sec = CMOS_READ(RTC_SECONDS);
min = CMOS_READ(RTC_MINUTES);
hour = CMOS_READ(RTC_HOURS);
day = CMOS_READ(RTC_DAY_OF_MONTH);
mon = CMOS_READ(RTC_MONTH);
year = CMOS_READ(RTC_YEAR);
if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
sec = bcd2bin(sec);
min = bcd2bin(min);
hour = bcd2bin(hour);
day = bcd2bin(day);
mon = bcd2bin(mon);
year = bcd2bin(year);
}
/* PC-like is standard; used for year >= 70 */
epoch = 1900;
if (year < 20)
epoch = 2000;
else if (year >= 20 && year < 48)
/* NT epoch */
epoch = 1980;
else if (year >= 48 && year < 70)
/* Digital UNIX epoch */
epoch = 1952;
printk(KERN_INFO "Using epoch = %d\n", epoch);
if ((year += epoch) < 1970)
year += 100;
ts->tv_sec = mktime(year, mon, day, hour, min, sec);
}
/* /*
* timer_interrupt() needs to keep up the real-time clock, * timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick * as well as call the "do_timer()" routine every clocktick
@ -123,19 +167,6 @@ irqreturn_t timer_interrupt(int irq, void *dev)
if (nticks) if (nticks)
do_timer(nticks); do_timer(nticks);
/*
* If we have an externally synchronized Linux clock, then update
* CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
* called as close as possible to 500 ms before the new second starts.
*/
if (ntp_synced()
&& xtime.tv_sec > state.last_rtc_update + 660
&& xtime.tv_nsec >= 500000 - ((unsigned) TICK_SIZE) / 2
&& xtime.tv_nsec <= 500000 + ((unsigned) TICK_SIZE) / 2) {
int tmp = set_rtc_mmss(xtime.tv_sec);
state.last_rtc_update = xtime.tv_sec - (tmp ? 600 : 0);
}
write_sequnlock(&xtime_lock); write_sequnlock(&xtime_lock);
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
@ -304,7 +335,7 @@ rpcc_after_update_in_progress(void)
void __init void __init
time_init(void) time_init(void)
{ {
unsigned int year, mon, day, hour, min, sec, cc1, cc2, epoch; unsigned int cc1, cc2;
unsigned long cycle_freq, tolerance; unsigned long cycle_freq, tolerance;
long diff; long diff;
@ -348,43 +379,6 @@ time_init(void)
bogomips yet, but this is close on a 500Mhz box. */ bogomips yet, but this is close on a 500Mhz box. */
__delay(1000000); __delay(1000000);
sec = CMOS_READ(RTC_SECONDS);
min = CMOS_READ(RTC_MINUTES);
hour = CMOS_READ(RTC_HOURS);
day = CMOS_READ(RTC_DAY_OF_MONTH);
mon = CMOS_READ(RTC_MONTH);
year = CMOS_READ(RTC_YEAR);
if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
sec = bcd2bin(sec);
min = bcd2bin(min);
hour = bcd2bin(hour);
day = bcd2bin(day);
mon = bcd2bin(mon);
year = bcd2bin(year);
}
/* PC-like is standard; used for year >= 70 */
epoch = 1900;
if (year < 20)
epoch = 2000;
else if (year >= 20 && year < 48)
/* NT epoch */
epoch = 1980;
else if (year >= 48 && year < 70)
/* Digital UNIX epoch */
epoch = 1952;
printk(KERN_INFO "Using epoch = %d\n", epoch);
if ((year += epoch) < 1970)
year += 100;
xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
xtime.tv_nsec = 0;
wall_to_monotonic.tv_sec -= xtime.tv_sec;
wall_to_monotonic.tv_nsec = 0;
if (HZ > (1<<16)) { if (HZ > (1<<16)) {
extern void __you_loose (void); extern void __you_loose (void);
@ -394,7 +388,6 @@ time_init(void)
state.last_time = cc1; state.last_time = cc1;
state.scaled_ticks_per_cycle state.scaled_ticks_per_cycle
= ((unsigned long) HZ << FIX_SHIFT) / cycle_freq; = ((unsigned long) HZ << FIX_SHIFT) / cycle_freq;
state.last_rtc_update = 0;
state.partial_tick = 0L; state.partial_tick = 0L;
/* Startup the timer source. */ /* Startup the timer source. */

View File

@ -110,17 +110,17 @@ static struct clock_event_device comparator = {
.set_mode = comparator_mode, .set_mode = comparator_mode,
}; };
void read_persistent_clock(struct timespec *ts)
{
ts->tv_sec = mktime(2007, 1, 1, 0, 0, 0);
ts->tv_nsec = 0;
}
void __init time_init(void) void __init time_init(void)
{ {
unsigned long counter_hz; unsigned long counter_hz;
int ret; int ret;
xtime.tv_sec = mktime(2007, 1, 1, 0, 0, 0);
xtime.tv_nsec = 0;
set_normalized_timespec(&wall_to_monotonic,
-xtime.tv_sec, -xtime.tv_nsec);
/* figure rate for counter */ /* figure rate for counter */
counter_hz = clk_get_rate(boot_cpu_data.clk); counter_hz = clk_get_rate(boot_cpu_data.clk);
counter.mult = clocksource_hz2mult(counter_hz, counter.shift); counter.mult = clocksource_hz2mult(counter_hz, counter.shift);

View File

@ -353,9 +353,15 @@ void bfin_coretmr_clockevent_init(void)
#endif /* CONFIG_TICKSOURCE_CORETMR */ #endif /* CONFIG_TICKSOURCE_CORETMR */
void __init time_init(void) void read_persistent_clock(struct timespec *ts)
{ {
time_t secs_since_1970 = (365 * 37 + 9) * 24 * 60 * 60; /* 1 Jan 2007 */ time_t secs_since_1970 = (365 * 37 + 9) * 24 * 60 * 60; /* 1 Jan 2007 */
ts->tv_sec = secs_since_1970;
ts->tv_nsec = 0;
}
void __init time_init(void)
{
#ifdef CONFIG_RTC_DRV_BFIN #ifdef CONFIG_RTC_DRV_BFIN
/* [#2663] hack to filter junk RTC values that would cause /* [#2663] hack to filter junk RTC values that would cause
@ -368,11 +374,6 @@ void __init time_init(void)
} }
#endif #endif
/* Initialize xtime. From now on, xtime is updated with timer interrupts */
xtime.tv_sec = secs_since_1970;
xtime.tv_nsec = 0;
set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec);
bfin_cs_cycles_init(); bfin_cs_cycles_init();
bfin_cs_gptimer0_init(); bfin_cs_gptimer0_init();

View File

@ -112,11 +112,6 @@ u32 arch_gettimeoffset(void)
} }
#endif #endif
static inline int set_rtc_mmss(unsigned long nowtime)
{
return 0;
}
/* /*
* timer_interrupt() needs to keep up the real-time clock, * timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick * as well as call the "do_timer()" routine every clocktick
@ -126,29 +121,8 @@ __attribute__((l1_text))
#endif #endif
irqreturn_t timer_interrupt(int irq, void *dummy) irqreturn_t timer_interrupt(int irq, void *dummy)
{ {
/* last time the cmos clock got updated */
static long last_rtc_update;
write_seqlock(&xtime_lock); write_seqlock(&xtime_lock);
do_timer(1); do_timer(1);
/*
* If we have an externally synchronized Linux clock, then update
* CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
* called as close as possible to 500 ms before the new second starts.
*/
if (ntp_synced() &&
xtime.tv_sec > last_rtc_update + 660 &&
(xtime.tv_nsec / NSEC_PER_USEC) >=
500000 - ((unsigned)TICK_SIZE) / 2
&& (xtime.tv_nsec / NSEC_PER_USEC) <=
500000 + ((unsigned)TICK_SIZE) / 2) {
if (set_rtc_mmss(xtime.tv_sec) == 0)
last_rtc_update = xtime.tv_sec;
else
/* Do it again in 60s. */
last_rtc_update = xtime.tv_sec - 600;
}
write_sequnlock(&xtime_lock); write_sequnlock(&xtime_lock);
#ifdef CONFIG_IPIPE #ifdef CONFIG_IPIPE
@ -161,10 +135,15 @@ irqreturn_t timer_interrupt(int irq, void *dummy)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
void __init time_init(void) void read_persistent_clock(struct timespec *ts)
{ {
time_t secs_since_1970 = (365 * 37 + 9) * 24 * 60 * 60; /* 1 Jan 2007 */ time_t secs_since_1970 = (365 * 37 + 9) * 24 * 60 * 60; /* 1 Jan 2007 */
ts->tv_sec = secs_since_1970;
ts->tv_nsec = 0;
}
void __init time_init(void)
{
#ifdef CONFIG_RTC_DRV_BFIN #ifdef CONFIG_RTC_DRV_BFIN
/* [#2663] hack to filter junk RTC values that would cause /* [#2663] hack to filter junk RTC values that would cause
* userspace to have to deal with time values greater than * userspace to have to deal with time values greater than
@ -176,11 +155,5 @@ void __init time_init(void)
} }
#endif #endif
/* Initialize xtime. From now on, xtime is updated with timer interrupts */
xtime.tv_sec = secs_since_1970;
xtime.tv_nsec = 0;
wall_to_monotonic.tv_sec = -xtime.tv_sec;
time_sched_init(timer_interrupt); time_sched_init(timer_interrupt);
} }

View File

@ -23,6 +23,9 @@ config RWSEM_XCHGADD_ALGORITHM
config GENERIC_TIME config GENERIC_TIME
def_bool y def_bool y
config GENERIC_CMOS_UPDATE
def_bool y
config ARCH_USES_GETTIMEOFFSET config ARCH_USES_GETTIMEOFFSET
def_bool y def_bool y

View File

@ -26,7 +26,6 @@
/* it will make jiffies at 96 hz instead of 100 hz though */ /* it will make jiffies at 96 hz instead of 100 hz though */
#undef USE_CASCADE_TIMERS #undef USE_CASCADE_TIMERS
extern void update_xtime_from_cmos(void);
extern int set_rtc_mmss(unsigned long nowtime); extern int set_rtc_mmss(unsigned long nowtime);
extern int have_rtc; extern int have_rtc;
@ -188,8 +187,6 @@ stop_watchdog(void)
#endif #endif
} }
/* last time the cmos clock got updated */
static long last_rtc_update = 0;
/* /*
* timer_interrupt() needs to keep up the real-time clock, * timer_interrupt() needs to keep up the real-time clock,
@ -232,24 +229,6 @@ timer_interrupt(int irq, void *dev_id)
do_timer(1); do_timer(1);
cris_do_profile(regs); /* Save profiling information */ cris_do_profile(regs); /* Save profiling information */
/*
* If we have an externally synchronized Linux clock, then update
* CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
* called as close as possible to 500 ms before the new second starts.
*
* The division here is not time critical since it will run once in
* 11 minutes
*/
if (ntp_synced() &&
xtime.tv_sec > last_rtc_update + 660 &&
(xtime.tv_nsec / 1000) >= 500000 - (tick_nsec / 1000) / 2 &&
(xtime.tv_nsec / 1000) <= 500000 + (tick_nsec / 1000) / 2) {
if (set_rtc_mmss(xtime.tv_sec) == 0)
last_rtc_update = xtime.tv_sec;
else
last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
}
return IRQ_HANDLED; return IRQ_HANDLED;
} }
@ -274,22 +253,10 @@ time_init(void)
*/ */
loops_per_usec = 50; loops_per_usec = 50;
if(RTC_INIT() < 0) { if(RTC_INIT() < 0)
/* no RTC, start at 1980 */
xtime.tv_sec = 0;
xtime.tv_nsec = 0;
have_rtc = 0; have_rtc = 0;
} else { else
/* get the current time */
have_rtc = 1; have_rtc = 1;
update_xtime_from_cmos();
}
/*
* Initialize wall_to_monotonic such that adding it to xtime will yield zero, the
* tv_nsec field must be normalized (i.e., 0 <= nsec < NSEC_PER_SEC).
*/
set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec);
/* Setup the etrax timers /* Setup the etrax timers
* Base frequency is 25000 hz, divider 250 -> 100 HZ * Base frequency is 25000 hz, divider 250 -> 100 HZ

View File

@ -44,7 +44,6 @@ unsigned long timer_regs[NR_CPUS] =
#endif #endif
}; };
extern void update_xtime_from_cmos(void);
extern int set_rtc_mmss(unsigned long nowtime); extern int set_rtc_mmss(unsigned long nowtime);
extern int have_rtc; extern int have_rtc;
@ -198,9 +197,6 @@ handle_watchdog_bite(struct pt_regs* regs)
#endif #endif
} }
/* Last time the cmos clock got updated. */
static long last_rtc_update = 0;
/* /*
* timer_interrupt() needs to keep up the real-time clock, * timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick. * as well as call the "do_timer()" routine every clocktick.
@ -238,25 +234,6 @@ timer_interrupt(int irq, void *dev_id)
/* Call the real timer interrupt handler */ /* Call the real timer interrupt handler */
do_timer(1); do_timer(1);
/*
* If we have an externally synchronized Linux clock, then update
* CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
* called as close as possible to 500 ms before the new second starts.
*
* The division here is not time critical since it will run once in
* 11 minutes
*/
if ((time_status & STA_UNSYNC) == 0 &&
xtime.tv_sec > last_rtc_update + 660 &&
(xtime.tv_nsec / 1000) >= 500000 - (tick_nsec / 1000) / 2 &&
(xtime.tv_nsec / 1000) <= 500000 + (tick_nsec / 1000) / 2) {
if (set_rtc_mmss(xtime.tv_sec) == 0)
last_rtc_update = xtime.tv_sec;
else
/* Do it again in 60 s */
last_rtc_update = xtime.tv_sec - 600;
}
return IRQ_HANDLED; return IRQ_HANDLED;
} }
@ -309,23 +286,10 @@ time_init(void)
*/ */
loops_per_usec = 50; loops_per_usec = 50;
if(RTC_INIT() < 0) { if(RTC_INIT() < 0)
/* No RTC, start at 1980 */
xtime.tv_sec = 0;
xtime.tv_nsec = 0;
have_rtc = 0; have_rtc = 0;
} else { else
/* Get the current time */
have_rtc = 1; have_rtc = 1;
update_xtime_from_cmos();
}
/*
* Initialize wall_to_monotonic such that adding it to
* xtime will yield zero, the tv_nsec field must be normalized
* (i.e., 0 <= nsec < NSEC_PER_SEC).
*/
set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec);
/* Start CPU local timer. */ /* Start CPU local timer. */
cris_timer_init(); cris_timer_init();

View File

@ -98,6 +98,8 @@ unsigned long
get_cmos_time(void) get_cmos_time(void)
{ {
unsigned int year, mon, day, hour, min, sec; unsigned int year, mon, day, hour, min, sec;
if(!have_rtc)
return 0;
sec = CMOS_READ(RTC_SECONDS); sec = CMOS_READ(RTC_SECONDS);
min = CMOS_READ(RTC_MINUTES); min = CMOS_READ(RTC_MINUTES);
@ -119,19 +121,19 @@ get_cmos_time(void)
return mktime(year, mon, day, hour, min, sec); return mktime(year, mon, day, hour, min, sec);
} }
/* update xtime from the CMOS settings. used when /dev/rtc gets a SET_TIME.
* TODO: this doesn't reset the fancy NTP phase stuff as do_settimeofday does.
*/
void int update_persistent_clock(struct timespec now)
update_xtime_from_cmos(void)
{ {
if(have_rtc) { return set_rtc_mmss(now.tv_sec);
xtime.tv_sec = get_cmos_time();
xtime.tv_nsec = 0;
}
} }
void read_persistent_clock(struct timespec *ts)
{
ts->tv_sec = get_cmos_time();
ts->tv_nsec = 0;
}
extern void cris_profile_sample(struct pt_regs* regs); extern void cris_profile_sample(struct pt_regs* regs);
void void

View File

@ -48,20 +48,12 @@ static struct irqaction timer_irq = {
.name = "timer", .name = "timer",
}; };
static inline int set_rtc_mmss(unsigned long nowtime)
{
return -1;
}
/* /*
* timer_interrupt() needs to keep up the real-time clock, * timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick * as well as call the "do_timer()" routine every clocktick
*/ */
static irqreturn_t timer_interrupt(int irq, void *dummy) static irqreturn_t timer_interrupt(int irq, void *dummy)
{ {
/* last time the cmos clock got updated */
static long last_rtc_update = 0;
profile_tick(CPU_PROFILING); profile_tick(CPU_PROFILING);
/* /*
* Here we are in the timer irq handler. We just have irqs locally * Here we are in the timer irq handler. We just have irqs locally
@ -74,22 +66,6 @@ static irqreturn_t timer_interrupt(int irq, void *dummy)
do_timer(1); do_timer(1);
/*
* If we have an externally synchronized Linux clock, then update
* CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
* called as close as possible to 500 ms before the new second starts.
*/
if (ntp_synced() &&
xtime.tv_sec > last_rtc_update + 660 &&
(xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
(xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2
) {
if (set_rtc_mmss(xtime.tv_sec) == 0)
last_rtc_update = xtime.tv_sec;
else
last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
}
#ifdef CONFIG_HEARTBEAT #ifdef CONFIG_HEARTBEAT
static unsigned short n; static unsigned short n;
n++; n++;
@ -119,7 +95,8 @@ void time_divisor_init(void)
__set_TCSR_DATA(0, base >> 8); __set_TCSR_DATA(0, base >> 8);
} }
void time_init(void)
void read_persistent_clock(struct timespec *ts)
{ {
unsigned int year, mon, day, hour, min, sec; unsigned int year, mon, day, hour, min, sec;
@ -135,9 +112,12 @@ void time_init(void)
if ((year += 1900) < 1970) if ((year += 1900) < 1970)
year += 100; year += 100;
xtime.tv_sec = mktime(year, mon, day, hour, min, sec); ts->tv_sec = mktime(year, mon, day, hour, min, sec);
xtime.tv_nsec = 0; ts->tv_nsec = 0;
}
void time_init(void)
{
/* install scheduling interrupt handler */ /* install scheduling interrupt handler */
setup_irq(IRQ_CPU_TIMER0, &timer_irq); setup_irq(IRQ_CPU_TIMER0, &timer_irq);

View File

@ -41,7 +41,7 @@ void h8300_timer_tick(void)
update_process_times(user_mode(get_irq_regs())); update_process_times(user_mode(get_irq_regs()));
} }
void __init time_init(void) void read_persistent_clock(struct timespec *ts)
{ {
unsigned int year, mon, day, hour, min, sec; unsigned int year, mon, day, hour, min, sec;
@ -56,8 +56,12 @@ void __init time_init(void)
#endif #endif
if ((year += 1900) < 1970) if ((year += 1900) < 1970)
year += 100; year += 100;
xtime.tv_sec = mktime(year, mon, day, hour, min, sec); ts->tv_sec = mktime(year, mon, day, hour, min, sec);
xtime.tv_nsec = 0; ts->tv_nsec = 0;
}
void __init time_init(void)
{
h8300_timer_setup(); h8300_timer_setup();
} }

View File

@ -430,18 +430,16 @@ static int __init rtc_init(void)
} }
module_init(rtc_init); module_init(rtc_init);
void read_persistent_clock(struct timespec *ts)
{
efi_gettimeofday(ts);
}
void __init void __init
time_init (void) time_init (void)
{ {
register_percpu_irq(IA64_TIMER_VECTOR, &timer_irqaction); register_percpu_irq(IA64_TIMER_VECTOR, &timer_irqaction);
efi_gettimeofday(&xtime);
ia64_init_itm(); ia64_init_itm();
/*
* Initialize wall_to_monotonic such that adding it to xtime will yield zero, the
* tv_nsec field must be normalized (i.e., 0 <= nsec < NSEC_PER_SEC).
*/
set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec);
} }
/* /*

View File

@ -105,24 +105,6 @@ u32 arch_gettimeoffset(void)
return elapsed_time * 1000; return elapsed_time * 1000;
} }
/*
* In order to set the CMOS clock precisely, set_rtc_mmss has to be
* called 500 ms after the second nowtime has started, because when
* nowtime is written into the registers of the CMOS clock, it will
* jump to the next second precisely 500 ms later. Check the Motorola
* MC146818A or Dallas DS12887 data sheet for details.
*
* BUG: This routine does not handle hour overflow properly; it just
* sets the minutes. Usually you won't notice until after reboot!
*/
static inline int set_rtc_mmss(unsigned long nowtime)
{
return 0;
}
/* last time the cmos clock got updated */
static long last_rtc_update = 0;
/* /*
* timer_interrupt() needs to keep up the real-time clock, * timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick * as well as call the "do_timer()" routine every clocktick
@ -138,23 +120,6 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
update_process_times(user_mode(get_irq_regs())); update_process_times(user_mode(get_irq_regs()));
#endif #endif
/*
* If we have an externally synchronized Linux clock, then update
* CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
* called as close as possible to 500 ms before the new second starts.
*/
write_seqlock(&xtime_lock);
if (ntp_synced()
&& xtime.tv_sec > last_rtc_update + 660
&& (xtime.tv_nsec / 1000) >= 500000 - ((unsigned)TICK_SIZE) / 2
&& (xtime.tv_nsec / 1000) <= 500000 + ((unsigned)TICK_SIZE) / 2)
{
if (set_rtc_mmss(xtime.tv_sec) == 0)
last_rtc_update = xtime.tv_sec;
else /* do it again in 60 s */
last_rtc_update = xtime.tv_sec - 600;
}
write_sequnlock(&xtime_lock);
/* As we return to user mode fire off the other CPU schedulers.. /* As we return to user mode fire off the other CPU schedulers..
this is basically because we don't yet share IRQ's around. this is basically because we don't yet share IRQ's around.
This message is rigged to be safe on the 386 - basically it's This message is rigged to be safe on the 386 - basically it's
@ -174,7 +139,7 @@ static struct irqaction irq0 = {
.name = "MFT2", .name = "MFT2",
}; };
void __init time_init(void) void read_persistent_clock(struct timespec *ts)
{ {
unsigned int epoch, year, mon, day, hour, min, sec; unsigned int epoch, year, mon, day, hour, min, sec;
@ -194,11 +159,13 @@ void __init time_init(void)
epoch = 1952; epoch = 1952;
year += epoch; year += epoch;
xtime.tv_sec = mktime(year, mon, day, hour, min, sec); ts->tv_sec = mktime(year, mon, day, hour, min, sec);
xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); ts->tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
set_normalized_timespec(&wall_to_monotonic, }
-xtime.tv_sec, -xtime.tv_nsec);
void __init time_init(void)
{
#if defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_XNUX2) \ #if defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_XNUX2) \
|| defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_M32700) \ || defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_M32700) \
|| defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104) || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)

View File

@ -73,21 +73,24 @@ static irqreturn_t timer_interrupt(int irq, void *dummy)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
void __init time_init(void) void read_persistent_clock(struct timespec *ts)
{ {
struct rtc_time time; struct rtc_time time;
ts->tv_sec = 0;
ts->tv_nsec = 0;
if (mach_hwclk) { if (mach_hwclk) {
mach_hwclk(0, &time); mach_hwclk(0, &time);
if ((time.tm_year += 1900) < 1970) if ((time.tm_year += 1900) < 1970)
time.tm_year += 100; time.tm_year += 100;
xtime.tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday, ts->tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday,
time.tm_hour, time.tm_min, time.tm_sec); time.tm_hour, time.tm_min, time.tm_sec);
xtime.tv_nsec = 0;
} }
wall_to_monotonic.tv_sec = -xtime.tv_sec; }
void __init time_init(void)
{
mach_sched_init(timer_interrupt); mach_sched_init(timer_interrupt);
} }

View File

@ -37,6 +37,9 @@ config GENERIC_HARDIRQS_NO__DO_IRQ
config GENERIC_CALIBRATE_DELAY config GENERIC_CALIBRATE_DELAY
def_bool y def_bool y
config GENERIC_CMOS_UPDATE
def_bool y
config GENERIC_FIND_NEXT_BIT config GENERIC_FIND_NEXT_BIT
def_bool y def_bool y

View File

@ -26,17 +26,15 @@ static long last_rtc_update;
/* time for RTC to update itself in ioclks */ /* time for RTC to update itself in ioclks */
static unsigned long mn10300_rtc_update_period; static unsigned long mn10300_rtc_update_period;
/* void read_persistent_clock(struct timespec *ts)
* read the current RTC time
*/
unsigned long __init get_initial_rtc_time(void)
{ {
struct rtc_time tm; struct rtc_time tm;
get_rtc_time(&tm); get_rtc_time(&tm);
return mktime(tm.tm_year, tm.tm_mon, tm.tm_mday, ts->tv_sec = mktime(tm.tm_year, tm.tm_mon, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec); tm.tm_hour, tm.tm_min, tm.tm_sec);
ts->tv_nsec = 0;
} }
/* /*
@ -110,24 +108,9 @@ static int set_rtc_mmss(unsigned long nowtime)
return retval; return retval;
} }
void check_rtc_time(void) int update_persistent_clock(struct timespec now)
{ {
/* the RTC clock just finished ticking over again this second return set_rtc_mms(now.tv_sec);
* - if we have an externally synchronized Linux clock, then update
* RTC clock accordingly every ~11 minutes. set_rtc_mmss() has to be
* called as close as possible to 500 ms before the new second starts.
*/
if ((time_status & STA_UNSYNC) == 0 &&
xtime.tv_sec > last_rtc_update + 660 &&
xtime.tv_nsec / 1000 >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
xtime.tv_nsec / 1000 <= 500000 + ((unsigned) TICK_SIZE) / 2
) {
if (set_rtc_mmss(xtime.tv_sec) == 0)
last_rtc_update = xtime.tv_sec;
else
/* do it again in 60s */
last_rtc_update = xtime.tv_sec - 600;
}
} }
/* /*

View File

@ -111,7 +111,6 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
/* advance the kernel's time tracking system */ /* advance the kernel's time tracking system */
profile_tick(CPU_PROFILING); profile_tick(CPU_PROFILING);
do_timer(1); do_timer(1);
check_rtc_time();
} }
write_sequnlock(&xtime_lock); write_sequnlock(&xtime_lock);
@ -139,9 +138,6 @@ void __init time_init(void)
" (calibrated against RTC)\n", " (calibrated against RTC)\n",
MN10300_TSCCLK / 1000000, (MN10300_TSCCLK / 10000) % 100); MN10300_TSCCLK / 1000000, (MN10300_TSCCLK / 10000) % 100);
xtime.tv_sec = get_initial_rtc_time();
xtime.tv_nsec = 0;
mn10300_last_tsc = TMTSCBC; mn10300_last_tsc = TMTSCBC;
/* use timer 0 & 1 cascaded to tick at as close to HZ as possible */ /* use timer 0 & 1 cascaded to tick at as close to HZ as possible */

View File

@ -75,7 +75,7 @@ config ARCH_USES_GETTIMEOFFSET
config GENERIC_CMOS_UPDATE config GENERIC_CMOS_UPDATE
bool bool
default y if SPARC64 default y
config GENERIC_CLOCKEVENTS config GENERIC_CLOCKEVENTS
bool bool

View File

@ -78,6 +78,11 @@ __volatile__ unsigned int *master_l10_counter;
u32 (*do_arch_gettimeoffset)(void); u32 (*do_arch_gettimeoffset)(void);
int update_persistent_clock(struct timespec now)
{
return set_rtc_mmss(now.tv_sec);
}
/* /*
* timer_interrupt() needs to keep up the real-time clock, * timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick * as well as call the "do_timer()" routine every clocktick
@ -87,9 +92,6 @@ u32 (*do_arch_gettimeoffset)(void);
static irqreturn_t timer_interrupt(int dummy, void *dev_id) static irqreturn_t timer_interrupt(int dummy, void *dev_id)
{ {
/* last time the cmos clock got updated */
static long last_rtc_update;
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
profile_tick(CPU_PROFILING); profile_tick(CPU_PROFILING);
#endif #endif
@ -101,16 +103,6 @@ static irqreturn_t timer_interrupt(int dummy, void *dev_id)
do_timer(1); do_timer(1);
/* Determine when to update the Mostek clock. */
if (ntp_synced() &&
xtime.tv_sec > last_rtc_update + 660 &&
(xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
(xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
if (set_rtc_mmss(xtime.tv_sec) == 0)
last_rtc_update = xtime.tv_sec;
else
last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
}
write_sequnlock(&xtime_lock); write_sequnlock(&xtime_lock);
#ifndef CONFIG_SMP #ifndef CONFIG_SMP

View File

@ -476,6 +476,7 @@ void xen_timer_resume(void)
__init void xen_time_init(void) __init void xen_time_init(void)
{ {
int cpu = smp_processor_id(); int cpu = smp_processor_id();
struct timespec tp;
clocksource_register(&xen_clocksource); clocksource_register(&xen_clocksource);
@ -487,9 +488,8 @@ __init void xen_time_init(void)
} }
/* Set initial system time with full resolution */ /* Set initial system time with full resolution */
xen_read_wallclock(&xtime); xen_read_wallclock(&tp);
set_normalized_timespec(&wall_to_monotonic, do_settimeofday(&tp);
-xtime.tv_sec, -xtime.tv_nsec);
setup_force_cpu_cap(X86_FEATURE_TSC); setup_force_cpu_cap(X86_FEATURE_TSC);

View File

@ -60,11 +60,6 @@ static struct irqaction timer_irqaction = {
void __init time_init(void) void __init time_init(void)
{ {
/* FIXME: xtime&wall_to_monotonic are set in timekeeping_init. */
read_persistent_clock(&xtime);
set_normalized_timespec(&wall_to_monotonic,
-xtime.tv_sec, -xtime.tv_nsec);
#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
printk("Calibrating CPU frequency "); printk("Calibrating CPU frequency ");
platform_calibrate_ccount(); platform_calibrate_ccount();