2009-12-23 03:59:45

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 0/14] Convert remaining arches to read/update_persistent_clock

So as the timekeeping system has become more and more generic, folks
have been careful to allow a slow and steady evolution without breaking
all the arches at once, allowing each arch maintainer to convert over to
generic code when they're ready.

However, this slow conversion has forced us to keep multiple methods for
various functionality around, cluttering up the code and making
maintenance more difficult. Further, there's no central road-map or
notification to maintainers on when these new generic functions appear,
so its likely folks wouldn't notice until the old interfaces were
removed.

In this case the generic read_persistent_clock() and
update_persistent_clock() methods have been provided to allow the
generic timekeeping code to initialize xtime and set the persistent
clock when NTP is synced. However many arches haven't converted, so the
generic code has to handle the case where the arch is doing this
management itself.

This patch series tries to convert the following 14 architectures over
to use read_persistent_clock() and update_persistent_clock() as
applicable, killing off about 200 lines of arch specific code.

I'm posting this tonight in somewhat rough form (none of the code has
been compiled or tested) so I can get feedback tomorrow before I'm off
on vacation until the new year. I'd like to get these changes into
2.6.34 so further generic cleanups can be made.

Let me know what you think.

thanks
-john




2009-12-23 04:00:49

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 1/14] Convert alpha to read/update_persistent_clock

This patch converts the alpha architecture to use the generic
read_persistent_clock and update_persistent_clock interfaces, reducing
the amount of arch specific code we have to maintain, and allowing for
further cleanups in the future.

I have not built or tested this patch, so help from arch maintainers
would be appreciated.

Signed-off-by: John Stultz <[email protected]>
---
Kconfig | 3 +
kernel/time.c | 101 ++++++++++++++++++++++++++--------------------------------
2 files changed, 50 insertions(+), 54 deletions(-)

Index: gettimeoffset/arch/alpha/Kconfig
===================================================================
--- gettimeoffset.orig/arch/alpha/Kconfig 2009-12-22 18:50:55.000000000 -0800
+++ gettimeoffset/arch/alpha/Kconfig 2009-12-22 18:51:01.000000000 -0800
@@ -54,6 +54,9 @@ config ARCH_USES_GETTIMEOFFSET
bool
default y

+config GENERIC_CMOS_UPDATE
+ def_bool y
+
config ZONE_DMA
bool
default y
Index: gettimeoffset/arch/alpha/kernel/time.c
===================================================================
--- gettimeoffset.orig/arch/alpha/kernel/time.c 2009-12-22 18:50:55.000000000 -0800
+++ gettimeoffset/arch/alpha/kernel/time.c 2009-12-22 18:51:01.000000000 -0800
@@ -75,8 +75,6 @@ static struct {
__u32 last_time;
/* ticks/cycle * 2^48 */
unsigned long scaled_ticks_per_cycle;
- /* last time the CMOS clock got updated */
- time_t last_rtc_update;
/* partial unused tick */
unsigned long partial_tick;
} state;
@@ -91,6 +89,52 @@ static inline __u32 rpcc(void)
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,
* as well as call the "do_timer()" routine every clocktick
@@ -123,19 +167,6 @@ irqreturn_t timer_interrupt(int irq, voi
if (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);

#ifndef CONFIG_SMP
@@ -304,7 +335,7 @@ rpcc_after_update_in_progress(void)
void __init
time_init(void)
{
- unsigned int year, mon, day, hour, min, sec, cc1, cc2, epoch;
+ unsigned int cc1, cc2;
unsigned long cycle_freq, tolerance;
long diff;

@@ -348,43 +379,6 @@ time_init(void)
bogomips yet, but this is close on a 500Mhz box. */
__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)) {
extern void __you_loose (void);
@@ -394,7 +388,6 @@ time_init(void)
state.last_time = cc1;
state.scaled_ticks_per_cycle
= ((unsigned long) HZ << FIX_SHIFT) / cycle_freq;
- state.last_rtc_update = 0;
state.partial_tick = 0L;

/* Startup the timer source. */

2009-12-23 04:02:01

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 2/14] Convert arm to read/update_persistent_clock

This patch converts the arm architecture to use the generic
read_persistent_clock and update_persistent_clock interfaces, reducing
the amount of arch specific code we have to maintain, and allowing for
further cleanups in the future.

Also removes a direct xtime access, replacing it with
current_kernel_time()

I have not built or tested this patch, so help from arch maintainers
would be appreciated.

Signed-off-by: John Stultz <[email protected]>
---
Kconfig | 3 +++
include/asm/mach/time.h | 2 +-
kernel/time.c | 39 ++++++++-------------------------------
mach-footbridge/time.c | 4 ++--
4 files changed, 14 insertions(+), 34 deletions(-)

Index: gettimeoffset/arch/arm/Kconfig
===================================================================
--- gettimeoffset.orig/arch/arm/Kconfig 2009-12-22 18:50:54.000000000 -0800
+++ gettimeoffset/arch/arm/Kconfig 2009-12-22 18:51:20.000000000 -0800
@@ -38,6 +38,9 @@ config GENERIC_GPIO
config GENERIC_TIME
bool

+config GENERIC_CMOS_UPDATE
+ def_bool y
+
config GENERIC_CLOCKEVENTS
bool

Index: gettimeoffset/arch/arm/include/asm/mach/time.h
===================================================================
--- gettimeoffset.orig/arch/arm/include/asm/mach/time.h 2009-12-22 18:50:54.000000000 -0800
+++ gettimeoffset/arch/arm/include/asm/mach/time.h 2009-12-22 18:51:20.000000000 -0800
@@ -50,7 +50,7 @@ extern void timer_tick(void);
* Kernel time keeping support.
*/
struct timespec;
-extern int (*set_rtc)(void);
+extern int (*set_rtc)(struct timespec now);
extern void save_time_delta(struct timespec *delta, struct timespec *rtc);
extern void restore_time_delta(struct timespec *delta, struct timespec *rtc);

Index: gettimeoffset/arch/arm/kernel/time.c
===================================================================
--- gettimeoffset.orig/arch/arm/kernel/time.c 2009-12-22 18:50:54.000000000 -0800
+++ gettimeoffset/arch/arm/kernel/time.c 2009-12-22 18:51:20.000000000 -0800
@@ -80,7 +80,7 @@ EXPORT_SYMBOL(profile_pc);
/*
* hook for setting the RTC's idea of the current time.
*/
-int (*set_rtc)(void);
+int (*set_rtc)(struct timespec now);

#ifndef CONFIG_GENERIC_TIME
static unsigned long dummy_gettimeoffset(void)
@@ -89,34 +89,11 @@ static unsigned long dummy_gettimeoffset
}
#endif

-static unsigned long next_rtc_update;
-
-/*
- * If we have an externally synchronized linux clock, then update
- * CMOS clock accordingly every ~11 minutes. set_rtc() has to be
- * called as close as possible to 500 ms before the new second
- * starts.
- */
-static inline void do_set_rtc(void)
+int update_persistent_clock(struct timespec now)
{
- if (!ntp_synced() || set_rtc == NULL)
- return;
-
- if (next_rtc_update &&
- time_before((unsigned long)xtime.tv_sec, next_rtc_update))
- return;
-
- if (xtime.tv_nsec < 500000000 - ((unsigned) tick_nsec >> 1) &&
- xtime.tv_nsec >= 500000000 + ((unsigned) tick_nsec >> 1))
- return;
-
- if (set_rtc())
- /*
- * rtc update failed. Try again in 60s
- */
- next_rtc_update = xtime.tv_sec + 60;
- else
- next_rtc_update = xtime.tv_sec + 660;
+ if (set_rtc == NULL)
+ return -1;
+ return set_rtc(now);
}

#ifdef CONFIG_LEDS
@@ -305,9 +282,10 @@ EXPORT_SYMBOL(do_settimeofday);
*/
void save_time_delta(struct timespec *delta, struct timespec *rtc)
{
+ struct timespec now = current_kernel_time();
set_normalized_timespec(delta,
- xtime.tv_sec - rtc->tv_sec,
- xtime.tv_nsec - rtc->tv_nsec);
+ now.tv_sec - rtc->tv_sec,
+ now.tv_nsec - rtc->tv_nsec);
}
EXPORT_SYMBOL(save_time_delta);

@@ -336,7 +314,6 @@ void timer_tick(void)
{
profile_tick(CPU_PROFILING);
do_leds();
- do_set_rtc();
write_seqlock(&xtime_lock);
do_timer(1);
write_sequnlock(&xtime_lock);
Index: gettimeoffset/arch/arm/mach-footbridge/time.c
===================================================================
--- gettimeoffset.orig/arch/arm/mach-footbridge/time.c 2009-12-22 18:50:54.000000000 -0800
+++ gettimeoffset/arch/arm/mach-footbridge/time.c 2009-12-22 18:51:20.000000000 -0800
@@ -61,12 +61,12 @@ static unsigned long __init get_isa_cmos
return mktime(year, mon, day, hour, min, sec);
}

-static int set_isa_cmos_time(void)
+static int set_isa_cmos_time(struct timespec now)
{
int retval = 0;
int real_seconds, real_minutes, cmos_minutes;
unsigned char save_control, save_freq_select;
- unsigned long nowtime = xtime.tv_sec;
+ unsigned long nowtime = now.tv_sec;

save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);

2009-12-23 04:03:21

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 3/14] Convert avr32 to read/update_persistent_clock

This patch converts the avr32 architecture to use the generic
read_persistent_clock and update_persistent_clock interfaces, reducing
the amount of arch specific code we have to maintain, and allowing for
further cleanups in the future.

I have not built or tested this patch, so help from arch maintainers
would be appreciated.

Signed-off-by: John Stultz <[email protected]>
---
time.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

Index: gettimeoffset/arch/avr32/kernel/time.c
===================================================================
--- gettimeoffset.orig/arch/avr32/kernel/time.c 2009-12-22 18:50:55.000000000 -0800
+++ gettimeoffset/arch/avr32/kernel/time.c 2009-12-22 18:51:09.000000000 -0800
@@ -110,17 +110,17 @@ static struct clock_event_device compara
.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)
{
unsigned long counter_hz;
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 */
counter_hz = clk_get_rate(boot_cpu_data.clk);
counter.mult = clocksource_hz2mult(counter_hz, counter.shift);

2009-12-23 04:04:21

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 4/14] Convert blackfin to read/update_persistent_clock

This patch converts the blackfin architecture to use the generic
read_persistent_clock and update_persistent_clock interfaces, reducing
the amount of arch specific code we have to maintain, and allowing for
further cleanups in the future.

I have not built or tested this patch, so help from arch maintainers
would be appreciated.

Signed-off-by: John Stultz <[email protected]>
---
time-ts.c | 13 +++++++------
time.c | 39 ++++++---------------------------------
2 files changed, 13 insertions(+), 39 deletions(-)

Index: gettimeoffset/arch/blackfin/kernel/time-ts.c
===================================================================
--- gettimeoffset.orig/arch/blackfin/kernel/time-ts.c 2009-12-22 18:50:54.000000000 -0800
+++ gettimeoffset/arch/blackfin/kernel/time-ts.c 2009-12-22 18:51:13.000000000 -0800
@@ -348,9 +348,15 @@ static int __init bfin_clockevent_init(v
return 0;
}

-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 */
+ ts->tv_sec = secs_since_1970;
+ ts->tv_nsec = 0;
+}
+
+void __init time_init(void)
+{

#ifdef CONFIG_RTC_DRV_BFIN
/* [#2663] hack to filter junk RTC values that would cause
@@ -363,11 +369,6 @@ void __init time_init(void)
}
#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_gptimer0_init();
bfin_clockevent_init();
Index: gettimeoffset/arch/blackfin/kernel/time.c
===================================================================
--- gettimeoffset.orig/arch/blackfin/kernel/time.c 2009-12-22 18:50:54.000000000 -0800
+++ gettimeoffset/arch/blackfin/kernel/time.c 2009-12-22 18:51:13.000000000 -0800
@@ -112,11 +112,6 @@ u32 arch_gettimeoffset(void)
}
#endif

-static inline int set_rtc_mmss(unsigned long nowtime)
-{
- return 0;
-}
-
/*
* timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick
@@ -126,29 +121,8 @@ __attribute__((l1_text))
#endif
irqreturn_t timer_interrupt(int irq, void *dummy)
{
- /* last time the cmos clock got updated */
- static long last_rtc_update;
-
write_seqlock(&xtime_lock);
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);

#ifdef CONFIG_IPIPE
@@ -161,10 +135,15 @@ irqreturn_t timer_interrupt(int irq, voi
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 */
+ ts->tv_sec = secs_since_1970;
+ ts->tv_nsec = 0;
+}

+void __init time_init(void)
+{
#ifdef CONFIG_RTC_DRV_BFIN
/* [#2663] hack to filter junk RTC values that would cause
* userspace to have to deal with time values greater than
@@ -176,11 +155,5 @@ void __init time_init(void)
}
#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);
}

2009-12-23 04:05:41

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 5/14] Convert cris to read/update_persistent_clock

This patch converts the cris architecture to use the generic
read_persistent_clock and update_persistent_clock interfaces, reducing
the amount of arch specific code we have to maintain, and allowing for
further cleanups in the future.

I have not built or tested this patch, so help from arch maintainers
would be appreciated.


Signed-off-by: John Stultz <[email protected]>
---
Kconfig | 3 +++
arch-v10/kernel/time.c | 37 ++-----------------------------------
arch-v32/kernel/time.c | 40 ++--------------------------------------
kernel/time.c | 20 +++++++++++---------
4 files changed, 18 insertions(+), 82 deletions(-)

Index: gettimeoffset/arch/cris/Kconfig
===================================================================
--- gettimeoffset.orig/arch/cris/Kconfig 2009-12-22 18:50:54.000000000 -0800
+++ gettimeoffset/arch/cris/Kconfig 2009-12-22 18:51:26.000000000 -0800
@@ -20,6 +20,9 @@ config RWSEM_GENERIC_SPINLOCK
config RWSEM_XCHGADD_ALGORITHM
bool

+config GENERIC_CMOS_UPDATE
+ def_bool y
+
config GENERIC_IOMAP
bool
default y
Index: gettimeoffset/arch/cris/arch-v10/kernel/time.c
===================================================================
--- gettimeoffset.orig/arch/cris/arch-v10/kernel/time.c 2009-12-22 18:50:54.000000000 -0800
+++ gettimeoffset/arch/cris/arch-v10/kernel/time.c 2009-12-22 18:51:26.000000000 -0800
@@ -26,7 +26,6 @@
/* it will make jiffies at 96 hz instead of 100 hz though */
#undef USE_CASCADE_TIMERS

-extern void update_xtime_from_cmos(void);
extern int set_rtc_mmss(unsigned long nowtime);
extern int have_rtc;

@@ -188,8 +187,6 @@ stop_watchdog(void)
#endif
}

-/* last time the cmos clock got updated */
-static long last_rtc_update = 0;

/*
* timer_interrupt() needs to keep up the real-time clock,
@@ -232,24 +229,6 @@ timer_interrupt(int irq, void *dev_id)
do_timer(1);

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;
}

@@ -274,22 +253,10 @@ time_init(void)
*/
loops_per_usec = 50;

- if(RTC_INIT() < 0) {
- /* no RTC, start at 1980 */
- xtime.tv_sec = 0;
- xtime.tv_nsec = 0;
+ if(RTC_INIT() < 0)
have_rtc = 0;
- } else {
- /* get the current time */
+ else
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
* Base frequency is 25000 hz, divider 250 -> 100 HZ
Index: gettimeoffset/arch/cris/arch-v32/kernel/time.c
===================================================================
--- gettimeoffset.orig/arch/cris/arch-v32/kernel/time.c 2009-12-22 18:50:54.000000000 -0800
+++ gettimeoffset/arch/cris/arch-v32/kernel/time.c 2009-12-22 18:51:27.000000000 -0800
@@ -44,7 +44,6 @@ unsigned long timer_regs[NR_CPUS] =
#endif
};

-extern void update_xtime_from_cmos(void);
extern int set_rtc_mmss(unsigned long nowtime);
extern int have_rtc;

@@ -198,9 +197,6 @@ handle_watchdog_bite(struct pt_regs* reg
#endif
}

-/* Last time the cmos clock got updated. */
-static long last_rtc_update = 0;
-
/*
* timer_interrupt() needs to keep up the real-time clock,
* 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 */
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;
}

@@ -309,23 +286,10 @@ time_init(void)
*/
loops_per_usec = 50;

- if(RTC_INIT() < 0) {
- /* No RTC, start at 1980 */
- xtime.tv_sec = 0;
- xtime.tv_nsec = 0;
+ if(RTC_INIT() < 0)
have_rtc = 0;
- } else {
- /* Get the current time */
+ else
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. */
cris_timer_init();
Index: gettimeoffset/arch/cris/kernel/time.c
===================================================================
--- gettimeoffset.orig/arch/cris/kernel/time.c 2009-12-22 18:50:54.000000000 -0800
+++ gettimeoffset/arch/cris/kernel/time.c 2009-12-22 18:51:27.000000000 -0800
@@ -162,6 +162,8 @@ unsigned long
get_cmos_time(void)
{
unsigned int year, mon, day, hour, min, sec;
+ if(!have_rtc)
+ return 0;

sec = CMOS_READ(RTC_SECONDS);
min = CMOS_READ(RTC_MINUTES);
@@ -183,19 +185,19 @@ get_cmos_time(void)
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
-update_xtime_from_cmos(void)
+int update_persistent_clock(struct timespec now)
{
- if(have_rtc) {
- xtime.tv_sec = get_cmos_time();
- xtime.tv_nsec = 0;
- }
+ return set_rtc_mmss(now.tv_sec);
}

+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);

void

2009-12-23 04:06:36

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 6/14] Convert frv to read/update_persistent_clock

This patch converts the frv architecture to use the generic
read_persistent_clock and update_persistent_clock interfaces, reducing
the amount of arch specific code we have to maintain, and allowing for
further cleanups in the future.

I have not built or tested this patch, so help from arch maintainers
would be appreciated.

Signed-off-by: John Stultz <[email protected]>
---
time.c | 34 +++++++---------------------------
1 file changed, 7 insertions(+), 27 deletions(-)

Index: gettimeoffset/arch/frv/kernel/time.c
===================================================================
--- gettimeoffset.orig/arch/frv/kernel/time.c 2009-12-22 18:50:55.000000000 -0800
+++ gettimeoffset/arch/frv/kernel/time.c 2009-12-22 18:51:05.000000000 -0800
@@ -48,20 +48,12 @@ static struct irqaction timer_irq = {
.name = "timer",
};

-static inline int set_rtc_mmss(unsigned long nowtime)
-{
- return -1;
-}
-
/*
* timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick
*/
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);
/*
* Here we are in the timer irq handler. We just have irqs locally
@@ -74,22 +66,6 @@ static irqreturn_t timer_interrupt(int i

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
static unsigned short n;
n++;
@@ -119,7 +95,8 @@ void time_divisor_init(void)
__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;

@@ -135,9 +112,12 @@ void time_init(void)

if ((year += 1900) < 1970)
year += 100;
- xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
- xtime.tv_nsec = 0;
+ ts->tv_sec = mktime(year, mon, day, hour, min, sec);
+ ts->tv_nsec = 0;
+}

+void time_init(void)
+{
/* install scheduling interrupt handler */
setup_irq(IRQ_CPU_TIMER0, &timer_irq);


2009-12-23 04:08:13

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 7/14] Convert h8300 to read/update_persistent_clock

This patch converts the h8300 architecture to use the generic
read_persistent_clock and update_persistent_clock interfaces, reducing
the amount of arch specific code we have to maintain, and allowing for
further cleanups in the future.

I have not built or tested this patch, so help from arch maintainers
would be appreciated.

Signed-off-by: John Stultz <[email protected]>
---
time.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)

Index: gettimeoffset/arch/h8300/kernel/time.c
===================================================================
--- gettimeoffset.orig/arch/h8300/kernel/time.c 2009-12-22 18:50:55.000000000 -0800
+++ gettimeoffset/arch/h8300/kernel/time.c 2009-12-22 18:51:08.000000000 -0800
@@ -41,7 +41,7 @@ void h8300_timer_tick(void)
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;

@@ -56,8 +56,12 @@ void __init time_init(void)
#endif
if ((year += 1900) < 1970)
year += 100;
- xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
- xtime.tv_nsec = 0;
+ ts->tv_sec = mktime(year, mon, day, hour, min, sec);
+ ts->tv_nsec = 0;
+}
+
+void __init time_init(void)
+{

h8300_timer_setup();
}

2009-12-23 04:09:16

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 8/14] Convert ia64 to read/update_persistent_clock

This patch converts the ia64 architecture to use the generic
read_persistent_clock and update_persistent_clock interfaces, reducing
the amount of arch specific code we have to maintain, and allowing for
further cleanups in the future.

I have not built or tested this patch, so help from arch maintainers
would be appreciated.

Signed-off-by: John Stultz <[email protected]>
---
time.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)

Index: gettimeoffset/arch/ia64/kernel/time.c
===================================================================
--- gettimeoffset.orig/arch/ia64/kernel/time.c 2009-12-22 18:50:55.000000000 -0800
+++ gettimeoffset/arch/ia64/kernel/time.c 2009-12-22 18:51:10.000000000 -0800
@@ -430,18 +430,16 @@ static int __init rtc_init(void)
}
module_init(rtc_init);

+void read_persistent_clock(struct timespec *ts)
+{
+ efi_gettimeofday(ts);
+}
+
void __init
time_init (void)
{
register_percpu_irq(IA64_TIMER_VECTOR, &timer_irqaction);
- efi_gettimeofday(&xtime);
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);
}

/*

2009-12-23 04:10:31

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 9/14] Convert m32r to read/update_persistent_clock

This patch converts the m32r architecture to use the generic
read_persistent_clock and update_persistent_clock interfaces, reducing
the amount of arch specific code we have to maintain, and allowing for
further cleanups in the future.

I have not built or tested this patch, so help from arch maintainers
would be appreciated.

Signed-off-by: John Stultz <[email protected]>
---
time.c | 47 +++++++----------------------------------------
1 file changed, 7 insertions(+), 40 deletions(-)

Index: gettimeoffset/arch/m32r/kernel/time.c
===================================================================
--- gettimeoffset.orig/arch/m32r/kernel/time.c 2009-12-22 18:50:54.000000000 -0800
+++ gettimeoffset/arch/m32r/kernel/time.c 2009-12-22 18:51:15.000000000 -0800
@@ -106,24 +106,6 @@ u32 arch_gettimeoffset(void)
}

/*
- * 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,
* as well as call the "do_timer()" routine every clocktick
*/
@@ -138,23 +120,6 @@ static irqreturn_t timer_interrupt(int i
#ifndef CONFIG_SMP
update_process_times(user_mode(get_irq_regs()));
#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..
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
@@ -174,7 +139,7 @@ static struct irqaction irq0 = {
.name = "MFT2",
};

-void __init time_init(void)
+void read_persistent_clock(struct timespec *ts)
{
unsigned int epoch, year, mon, day, hour, min, sec;

@@ -194,11 +159,13 @@ void __init time_init(void)
epoch = 1952;
year += epoch;

- xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
- xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
- set_normalized_timespec(&wall_to_monotonic,
- -xtime.tv_sec, -xtime.tv_nsec);
+ ts->tv_sec = mktime(year, mon, day, hour, min, sec);
+ ts->tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
+}
+

+void __init time_init(void)
+{
#if defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_XNUX2) \
|| defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_M32700) \
|| defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)

2009-12-23 04:11:46

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 10/14] Convert m68k to read/update_persistent_clock

This patch converts the m68k architecture to use the generic
read_persistent_clock and update_persistent_clock interfaces, reducing
the amount of arch specific code we have to maintain, and allowing for
further cleanups in the future.

I have not built or tested this patch, so help from arch maintainers
would be appreciated.

Signed-off-by: John Stultz <[email protected]>
---
time.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)


Index: gettimeoffset/arch/m68k/kernel/time.c
===================================================================
--- gettimeoffset.orig/arch/m68k/kernel/time.c 2009-12-22 18:50:54.000000000 -0800
+++ gettimeoffset/arch/m68k/kernel/time.c 2009-12-22 18:51:18.000000000 -0800
@@ -73,21 +73,24 @@ static irqreturn_t timer_interrupt(int i
return IRQ_HANDLED;
}

-void __init time_init(void)
+void read_persistent_clock(struct timespec *ts)
{
struct rtc_time time;
+ ts->tv_sec = 0;
+ ts->tv_nsec = 0;

if (mach_hwclk) {
mach_hwclk(0, &time);

if ((time.tm_year += 1900) < 1970)
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);
- xtime.tv_nsec = 0;
}
- wall_to_monotonic.tv_sec = -xtime.tv_sec;
+}

+void __init time_init(void)
+{
mach_sched_init(timer_interrupt);
}


2009-12-23 04:12:59

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 11/14] Convert mn10300 to read/update_persistent_clock

This patch converts the mn10300 architecture to use the generic
read_persistent_clock and update_persistent_clock interfaces, reducing
the amount of arch specific code we have to maintain, and allowing for
further cleanups in the future.

I have not built or tested this patch, so help from arch maintainers
would be appreciated.

Signed-off-by: John Stultz <[email protected]>
---
Kconfig | 3 +++
kernel/rtc.c | 27 +++++----------------------
kernel/time.c | 4 ----
3 files changed, 8 insertions(+), 26 deletions(-)

Index: gettimeoffset/arch/mn10300/Kconfig
===================================================================
--- gettimeoffset.orig/arch/mn10300/Kconfig 2009-12-22 18:50:55.000000000 -0800
+++ gettimeoffset/arch/mn10300/Kconfig 2009-12-22 18:51:03.000000000 -0800
@@ -37,6 +37,9 @@ config GENERIC_HARDIRQS_NO__DO_IRQ
config GENERIC_CALIBRATE_DELAY
def_bool y

+config GENERIC_CMOS_UPDATE
+ def_bool y
+
config GENERIC_FIND_NEXT_BIT
def_bool y

Index: gettimeoffset/arch/mn10300/kernel/rtc.c
===================================================================
--- gettimeoffset.orig/arch/mn10300/kernel/rtc.c 2009-12-22 18:50:55.000000000 -0800
+++ gettimeoffset/arch/mn10300/kernel/rtc.c 2009-12-22 18:51:03.000000000 -0800
@@ -26,17 +26,15 @@ static long last_rtc_update;
/* time for RTC to update itself in ioclks */
static unsigned long mn10300_rtc_update_period;

-/*
- * read the current RTC time
- */
-unsigned long __init get_initial_rtc_time(void)
+void read_persistent_clock(struct timespec *ts)
{
struct 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);
+ ts->tv_nsec = 0;
}

/*
@@ -110,24 +108,9 @@ static int set_rtc_mmss(unsigned long no
return retval;
}

-void check_rtc_time(void)
+int update_persistent_clock(struct timespec now)
{
- /* the RTC clock just finished ticking over again this second
- * - 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;
- }
+ return set_rtc_mms(now.tv_sec);
}

/*
Index: gettimeoffset/arch/mn10300/kernel/time.c
===================================================================
--- gettimeoffset.orig/arch/mn10300/kernel/time.c 2009-12-22 18:50:55.000000000 -0800
+++ gettimeoffset/arch/mn10300/kernel/time.c 2009-12-22 18:51:03.000000000 -0800
@@ -111,7 +111,6 @@ static irqreturn_t timer_interrupt(int i
/* advance the kernel's time tracking system */
profile_tick(CPU_PROFILING);
do_timer(1);
- check_rtc_time();
}

write_sequnlock(&xtime_lock);
@@ -139,9 +138,6 @@ void __init time_init(void)
" (calibrated against RTC)\n",
MN10300_TSCCLK / 1000000, (MN10300_TSCCLK / 10000) % 100);

- xtime.tv_sec = get_initial_rtc_time();
- xtime.tv_nsec = 0;
-
mn10300_last_tsc = TMTSCBC;

/* use timer 0 & 1 cascaded to tick at as close to HZ as possible */

2009-12-23 04:14:16

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 12/14] Convert parisc to read/update_persistent_clock

This patch converts the parisc architecture to use the generic
read_persistent_clock and update_persistent_clock interfaces, reducing
the amount of arch specific code we have to maintain, and allowing for
further cleanups in the future.

I have not built or tested this patch, so help from arch maintainers
would be appreciated.

Signed-off-by: John Stultz <[email protected]>
---
time.c | 29 +++++++++++++----------------
1 file changed, 13 insertions(+), 16 deletions(-)

Index: gettimeoffset/arch/parisc/kernel/time.c
===================================================================
--- gettimeoffset.orig/arch/parisc/kernel/time.c 2009-12-22 18:50:55.000000000 -0800
+++ gettimeoffset/arch/parisc/kernel/time.c 2009-12-22 18:51:06.000000000 -0800
@@ -250,9 +250,21 @@ static int __init rtc_init(void)
}
module_init(rtc_init);

-void __init time_init(void)
+void read_persistent_clock(struct timespec *ts)
{
static struct pdc_tod tod_data;
+ if (pdc_tod_read(&tod_data) == 0) {
+ ts->tv_sec = tod_data.tod_sec;
+ ts->tv_nsec = tod_data.tod_usec * 1000;
+ } else {
+ printk(KERN_ERR "Error reading tod clock\n");
+ ts->tv_sec = 0;
+ ts->tv_nsec = 0;
+ }
+}
+
+void __init time_init(void)
+{
unsigned long current_cr16_khz;

clocktick = (100 * PAGE0->mem_10msec) / HZ;
@@ -264,19 +276,4 @@ void __init time_init(void)
clocksource_cr16.mult = clocksource_khz2mult(current_cr16_khz,
clocksource_cr16.shift);
clocksource_register(&clocksource_cr16);
-
- if (pdc_tod_read(&tod_data) == 0) {
- unsigned long flags;
-
- write_seqlock_irqsave(&xtime_lock, flags);
- xtime.tv_sec = tod_data.tod_sec;
- xtime.tv_nsec = tod_data.tod_usec * 1000;
- set_normalized_timespec(&wall_to_monotonic,
- -xtime.tv_sec, -xtime.tv_nsec);
- write_sequnlock_irqrestore(&xtime_lock, flags);
- } else {
- printk(KERN_ERR "Error reading tod clock\n");
- xtime.tv_sec = 0;
- xtime.tv_nsec = 0;
- }
}

2009-12-23 04:15:14

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 13/14] Convert sh to read/update_persistent_clock

This patch converts the sh architecture to use the generic
read_persistent_clock and update_persistent_clock interfaces, reducing
the amount of arch specific code we have to maintain, and allowing for
further cleanups in the future.

I have not built or tested this patch, so help from arch maintainers
would be appreciated.

Signed-off-by: John Stultz <[email protected]>
---
time.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)


Index: gettimeoffset/arch/sh/kernel/time.c
===================================================================
--- gettimeoffset.orig/arch/sh/kernel/time.c 2009-12-22 18:50:55.000000000 -0800
+++ gettimeoffset/arch/sh/kernel/time.c 2009-12-22 18:51:12.000000000 -0800
@@ -39,12 +39,12 @@ static int null_rtc_set_time(const time_
void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time;
int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time;

-#ifdef CONFIG_GENERIC_CMOS_UPDATE
void read_persistent_clock(struct timespec *ts)
{
rtc_sh_get_time(ts);
}

+#ifdef CONFIG_GENERIC_CMOS_UPDATE
int update_persistent_clock(struct timespec now)
{
return rtc_sh_set_time(now.tv_sec);
@@ -113,9 +113,5 @@ void __init time_init(void)
hwblk_init();
clk_init();

- rtc_sh_get_time(&xtime);
- set_normalized_timespec(&wall_to_monotonic,
- -xtime.tv_sec, -xtime.tv_nsec);
-
late_time_init = sh_late_time_init;
}

2009-12-23 04:16:25

by john stultz

[permalink] [raw]
Subject: [RFC][PATCH 14/14] Convert sparc to read/update_persistent_clock

This patch converts the sparc architecture to use the generic
read_persistent_clock and update_persistent_clock interfaces, reducing
the amount of arch specific code we have to maintain, and allowing for
further cleanups in the future.

I have not built or tested this patch, so help from arch maintainers
would be appreciated.

Signed-off-by: John Stultz <[email protected]>
---
Kconfig | 2 +-
kernel/time_32.c | 15 +++++----------
2 files changed, 6 insertions(+), 11 deletions(-)


Index: gettimeoffset/arch/sparc/Kconfig
===================================================================
--- gettimeoffset.orig/arch/sparc/Kconfig 2009-12-22 18:50:54.000000000 -0800
+++ gettimeoffset/arch/sparc/Kconfig 2009-12-22 18:51:25.000000000 -0800
@@ -69,7 +69,7 @@ config GENERIC_TIME

config GENERIC_CMOS_UPDATE
bool
- default y if SPARC64
+ default y

config GENERIC_CLOCKEVENTS
bool
Index: gettimeoffset/arch/sparc/kernel/time_32.c
===================================================================
--- gettimeoffset.orig/arch/sparc/kernel/time_32.c 2009-12-22 18:50:54.000000000 -0800
+++ gettimeoffset/arch/sparc/kernel/time_32.c 2009-12-22 18:51:25.000000000 -0800
@@ -76,6 +76,11 @@ EXPORT_SYMBOL(profile_pc);

__volatile__ unsigned int *master_l10_counter;

+int update_persistent_clock(struct timespec now)
+{
+ return set_rtc_mmss(now.tv_sec);
+}
+
/*
* timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick
@@ -99,16 +104,6 @@ static irqreturn_t timer_interrupt(int d

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

#ifndef CONFIG_SMP

2009-12-23 05:08:28

by Paul Mundt

[permalink] [raw]
Subject: Re: [RFC][PATCH 0/14] Convert remaining arches to read/update_persistent_clock

On Tue, Dec 22, 2009 at 07:59:22PM -0800, john stultz wrote:
> In this case the generic read_persistent_clock() and
> update_persistent_clock() methods have been provided to allow the
> generic timekeeping code to initialize xtime and set the persistent
> clock when NTP is synced. However many arches haven't converted, so the
> generic code has to handle the case where the arch is doing this
> management itself.
>
> This patch series tries to convert the following 14 architectures over
> to use read_persistent_clock() and update_persistent_clock() as
> applicable, killing off about 200 lines of arch specific code.
>
While I think that this is a good goal, many of the underlying
architectures have veered pretty far away from having meaningful
persistent clock interfaces after having moved entirely to generic
timekeeping and the RTC subsystem.

In the case of SH at least that interface along with the generic CMOS
stuff is largely a stop-gap for antiquated platforms that don't have
proper RTC drivers and likely never will, while the default for all of
the rest of the platforms effectively returns a fixed dummy value. I
copied this approach from MIPS originally, so there are at least a few
architectures that this will apply to.

In any event, I wonder if it might make more sense to take something like
the SPARC implementation that is simply a wrapper around the RTC, move
that out in to a more generic place, and permit architectures to select
an RTC class backed persistent clock instead (it seems to be only
platforms that haven't caught up yet in terms of generic time and RTC
migration that would want to define this interface on their own at all at
this point)?

2009-12-23 10:08:56

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [RFC][PATCH 0/14] Convert remaining arches to read/update_persistent_clock

On Wed, Dec 23, 2009 at 06:08, Paul Mundt <[email protected]> wrote:
> On Tue, Dec 22, 2009 at 07:59:22PM -0800, john stultz wrote:
>> In this case the generic read_persistent_clock() and
>> update_persistent_clock() methods have been provided to allow the
>> generic timekeeping code to initialize xtime and set the persistent
>> clock when NTP is synced. However many arches haven't converted, so the
>> generic code has to handle the case where the arch is doing this
>> management itself.
>>
>> This patch series tries to convert the following 14 architectures over
>> to use read_persistent_clock() and update_persistent_clock() as
>> applicable, killing off about 200 lines of arch specific code.
>>
> While I think that this is a good goal, many of the underlying
> architectures have veered pretty far away from having meaningful
> persistent clock interfaces after having moved entirely to generic
> timekeeping and the RTC subsystem.

Indeed. When moving to the RTC subsystem, you loose the persistent
clock at boot;
i.e. on m68k, mach_hwclk() can no longer be set, as the RTC driver is
in a separate
(possible loadable) module.

> In the case of SH at least that interface along with the generic CMOS
> stuff is largely a stop-gap for antiquated platforms that don't have
> proper RTC drivers and likely never will, while the default for all of
> the rest of the platforms effectively returns a fixed dummy value. I
> copied this approach from MIPS originally, so there are at least a few
> architectures that this will apply to.
>
> In any event, I wonder if it might make more sense to take something like
> the SPARC implementation that is simply a wrapper around the RTC, move
> that out in to a more generic place, and permit architectures to select
> an RTC class backed persistent clock instead (it seems to be only
> platforms that haven't caught up yet in terms of generic time and RTC
> migration that would want to define this interface on their own at all at
> this point)?

Hmm, haven't looked into how SPARC handles this yet...
Yes, looks like a good idea to me. Any disadvantages with this approach?

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2009-12-23 22:05:16

by john stultz

[permalink] [raw]
Subject: Re: [RFC][PATCH 0/14] Convert remaining arches to read/update_persistent_clock

On Wed, 2009-12-23 at 14:08 +0900, Paul Mundt wrote:
> On Tue, Dec 22, 2009 at 07:59:22PM -0800, john stultz wrote:
> > In this case the generic read_persistent_clock() and
> > update_persistent_clock() methods have been provided to allow the
> > generic timekeeping code to initialize xtime and set the persistent
> > clock when NTP is synced. However many arches haven't converted, so the
> > generic code has to handle the case where the arch is doing this
> > management itself.
> >
> > This patch series tries to convert the following 14 architectures over
> > to use read_persistent_clock() and update_persistent_clock() as
> > applicable, killing off about 200 lines of arch specific code.
> >
> While I think that this is a good goal, many of the underlying
> architectures have veered pretty far away from having meaningful
> persistent clock interfaces after having moved entirely to generic
> timekeeping and the RTC subsystem.
>
> In the case of SH at least that interface along with the generic CMOS
> stuff is largely a stop-gap for antiquated platforms that don't have
> proper RTC drivers and likely never will, while the default for all of
> the rest of the platforms effectively returns a fixed dummy value. I
> copied this approach from MIPS originally, so there are at least a few
> architectures that this will apply to.
>
> In any event, I wonder if it might make more sense to take something like
> the SPARC implementation that is simply a wrapper around the RTC, move
> that out in to a more generic place, and permit architectures to select
> an RTC class backed persistent clock instead (it seems to be only
> platforms that haven't caught up yet in terms of generic time and RTC
> migration that would want to define this interface on their own at all at
> this point)?

Yea, there's some additional complications with the RTC interface via
read_persistent_clock, as some RTC clocks require irqs enabled to be
able to read. This keeps them from being used via
read_persistent_clock() as it is used prior to irqs being enabled, and
then again with irqs disabled in the suspend and resume path.

This has a bit of a trade-off, as we can better handle timekeeping
around a suspend/resume with read_persistent_clock(), but for some
hardware we just can't use the RTC for that.

Anyway, if we can improve the timekeeping/RTC interface used for
initialization and suspend/resume, I'm all for it (maybe having the RTC
code to tell the timekeeping code if it can be accessed with irqs off?).
But for hardware that needs irqs, i'm not sure how we can handle resumes
correctly there. So suggestions would be welcome.

Anyway, the main point of this patch set is to remove the direct access
to timekeeping internals (xtime, wall_to_monotonic). Those need to go
soon, as they're limiting changes in the timekeeping code.
read_persistent_clock() is the current way to avoid it, but if systems
are fine doing a settimeofday() at init that's ok too (although some
oddities may be seen wrt boot time with the direct settimeofday, I need
to refresh my head on how the varying default boot times between arches
may be effected).

thanks
-john

2009-12-24 01:50:05

by Dialup Jon Norstog

[permalink] [raw]
Subject: Re: [RFC][PATCH 0/14] Convert remaining arches to read/update_persistent_clock

john,

IMO the biggest clock problem on Alpha is that dual booting Tru64 and Linux
whacks the clock every time you go from one OS to the other. Allowing Linux
to decouple from SRM's TOY clock would be a signal advance.

jon norstog


---------- Original Message -----------
From: john stultz <[email protected]>
To: Paul Mundt <[email protected]>
Cc: lkml <[email protected]>, Richard Henderson
<[email protected]>, [email protected], [email protected],
Russell King <[email protected]>, Haavard Skinnemoen
<[email protected]>, Mike Frysinger <[email protected]>, Mikael Starvik
<[email protected]>, David Howells <[email protected]>, Yoshinori Sato
<[email protected]>, Tony Luck <[email protected]>, Hirokazu
Takata <[email protected]>, Geert Uytterhoeven <[email protected]>,
Koichi Yasutake <[email protected]>, Kyle McMartin
<[email protected]>, "David S. Miller" <[email protected]>, David Brownell
<[email protected]>
Sent: Wed, 23 Dec 2009 14:04:59 -0800
Subject: Re: [RFC][PATCH 0/14] Convert remaining arches to
read/update_persistent_clock

> On Wed, 2009-12-23 at 14:08 +0900, Paul Mundt wrote:
> > On Tue, Dec 22, 2009 at 07:59:22PM -0800, john stultz wrote:
> > > In this case the generic read_persistent_clock() and
> > > update_persistent_clock() methods have been provided to allow the
> > > generic timekeeping code to initialize xtime and set the persistent
> > > clock when NTP is synced. However many arches haven't converted, so the
> > > generic code has to handle the case where the arch is doing this
> > > management itself.
> > >
> > > This patch series tries to convert the following 14 architectures over
> > > to use read_persistent_clock() and update_persistent_clock() as
> > > applicable, killing off about 200 lines of arch specific code.
> > >
> > While I think that this is a good goal, many of the underlying
> > architectures have veered pretty far away from having meaningful
> > persistent clock interfaces after having moved entirely to generic
> > timekeeping and the RTC subsystem.
> >
> > In the case of SH at least that interface along with the generic CMOS
> > stuff is largely a stop-gap for antiquated platforms that don't have
> > proper RTC drivers and likely never will, while the default for all of
> > the rest of the platforms effectively returns a fixed dummy value. I
> > copied this approach from MIPS originally, so there are at least a few
> > architectures that this will apply to.
> >
> > In any event, I wonder if it might make more sense to take something like
> > the SPARC implementation that is simply a wrapper around the RTC, move
> > that out in to a more generic place, and permit architectures to select
> > an RTC class backed persistent clock instead (it seems to be only
> > platforms that haven't caught up yet in terms of generic time and RTC
> > migration that would want to define this interface on their own at all at
> > this point)?
>
> Yea, there's some additional complications with the RTC interface via
> read_persistent_clock, as some RTC clocks require irqs enabled to be
> able to read. This keeps them from being used via
> read_persistent_clock() as it is used prior to irqs being enabled,
> and then again with irqs disabled in the suspend and resume path.
>
> This has a bit of a trade-off, as we can better handle timekeeping
> around a suspend/resume with read_persistent_clock(), but for some
> hardware we just can't use the RTC for that.
>
> Anyway, if we can improve the timekeeping/RTC interface used for
> initialization and suspend/resume, I'm all for it (maybe having the RTC
> code to tell the timekeeping code if it can be accessed with irqs
> off?). But for hardware that needs irqs, i'm not sure how we can
> handle resumes correctly there. So suggestions would be welcome.
>
> Anyway, the main point of this patch set is to remove the direct access
> to timekeeping internals (xtime, wall_to_monotonic). Those need to go
> soon, as they're limiting changes in the timekeeping code.
> read_persistent_clock() is the current way to avoid it, but if
> systems are fine doing a settimeofday() at init that's ok too
> (although some oddities may be seen wrt boot time with the direct
> settimeofday, I need to refresh my head on how the varying default
> boot times between arches may be effected).
>
> thanks
> -john
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-
> alpha" in the body of a message to [email protected] More
> majordomo info at http://vger.kernel.org/majordomo-info.html
>
> --
> This message has been scanned for viruses and
> dangerous content by MailScanner, and is
> believed to be clean.
------- End of Original Message -------

2009-12-24 04:52:43

by David Miller

[permalink] [raw]
Subject: Re: [RFC][PATCH 14/14] Convert sparc to read/update_persistent_clock

From: john stultz <[email protected]>
Date: Tue, 22 Dec 2009 20:16:11 -0800

> This patch converts the sparc architecture to use the generic
> read_persistent_clock and update_persistent_clock interfaces, reducing
> the amount of arch specific code we have to maintain, and allowing for
> further cleanups in the future.
>
> I have not built or tested this patch, so help from arch maintainers
> would be appreciated.
>
> Signed-off-by: John Stultz <[email protected]>

This looks fine to me:

Acked-by: David S. Miller <[email protected]>

2009-12-24 04:54:16

by David Miller

[permalink] [raw]
Subject: Re: [RFC][PATCH 0/14] Convert remaining arches to read/update_persistent_clock

From: Paul Mundt <[email protected]>
Date: Wed, 23 Dec 2009 14:08:10 +0900

> In any event, I wonder if it might make more sense to take something like
> the SPARC implementation that is simply a wrapper around the RTC, move
> that out in to a more generic place, and permit architectures to select
> an RTC class backed persistent clock instead (it seems to be only
> platforms that haven't caught up yet in terms of generic time and RTC
> migration that would want to define this interface on their own at all at
> this point)?

This sounds nice but don't we have a slew of RTC types that need
to be accessed over I2C and thus you can't touch them without
sleeping?

2009-12-24 05:10:44

by Paul Mundt

[permalink] [raw]
Subject: Re: [RFC][PATCH 0/14] Convert remaining arches to read/update_persistent_clock

On Wed, Dec 23, 2009 at 08:54:15PM -0800, David Miller wrote:
> From: Paul Mundt <[email protected]>
> Date: Wed, 23 Dec 2009 14:08:10 +0900
>
> > In any event, I wonder if it might make more sense to take something like
> > the SPARC implementation that is simply a wrapper around the RTC, move
> > that out in to a more generic place, and permit architectures to select
> > an RTC class backed persistent clock instead (it seems to be only
> > platforms that haven't caught up yet in terms of generic time and RTC
> > migration that would want to define this interface on their own at all at
> > this point)?
>
> This sounds nice but don't we have a slew of RTC types that need
> to be accessed over I2C and thus you can't touch them without
> sleeping?

Yes, and SPI and so on. We do however have plenty of available room for
adding a valid-for-persistent-clock flag to permit drivers to opt-in, so
we can certainly still do better than the status quo. I'll hack something
up and see how it goes.

2009-12-24 11:09:25

by Uwe Kleine-König

[permalink] [raw]
Subject: Re: [RFC][PATCH 2/14] Convert arm to read/update_persistent_clock

Hello,

On Tue, Dec 22, 2009 at 08:01:42PM -0800, john stultz wrote:
> This patch converts the arm architecture to use the generic
> read_persistent_clock and update_persistent_clock interfaces, reducing
> the amount of arch specific code we have to maintain, and allowing for
> further cleanups in the future.
>
> Also removes a direct xtime access, replacing it with
> current_kernel_time()
>
> I have not built or tested this patch, so help from arch maintainers
> would be appreciated.
I havn't tested either, but built footbridge_defconfig successfully.
bloat-o-meter reports:

add/remove: 4/1 grow/shrink: 2/2 up/down: 388/-196 (192)
function old new delta
sync_cmos_clock - 240 +240
update_persistent_clock - 52 +52
sync_cmos_work - 40 +40
do_adjtimex 1924 1956 +32
save_time_delta 56 76 +20
no_sync_cmos_clock - 4 +4
next_rtc_update 4 - -4
set_isa_cmos_time 372 364 -8
timer_tick 324 140 -184

Best regards
Uwe

--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |

2010-01-05 16:47:49

by David Howells

[permalink] [raw]
Subject: Re: [RFC][PATCH 6/14] Convert frv to read/update_persistent_clock

john stultz <[email protected]> wrote:

> This patch converts the frv architecture to use the generic
> read_persistent_clock and update_persistent_clock interfaces, reducing
> the amount of arch specific code we have to maintain, and allowing for
> further cleanups in the future.
>
> I have not built or tested this patch, so help from arch maintainers
> would be appreciated.
>
> Signed-off-by: John Stultz <[email protected]>

Acked-by: David Howells <[email protected]>

2010-01-05 17:09:25

by David Howells

[permalink] [raw]
Subject: Re: [RFC][PATCH 11/14] Convert mn10300 to read/update_persistent_clock

john stultz <[email protected]> wrote:

> This patch converts the mn10300 architecture to use the generic
> read_persistent_clock and update_persistent_clock interfaces, reducing
> the amount of arch specific code we have to maintain, and allowing for
> further cleanups in the future.
>
> I have not built or tested this patch, so help from arch maintainers
> would be appreciated.
>
> Signed-off-by: John Stultz <[email protected]>

arch/mn10300/kernel/rtc.c: In function `update_persistent_clock':
arch/mn10300/kernel/rtc.c:113: error: implicit declaration of function 'set_rtc_mms'
arch/mn10300/kernel/rtc.c: At top level:
arch/mn10300/kernel/rtc.c:24: warning: unused variable `last_rtc_update'
arch/mn10300/kernel/rtc.c:24: warning: 'last_rtc_update' defined but not used
arch/mn10300/kernel/rtc.c:51: warning: 'set_rtc_mmss' defined but not used

set_rtc_mms should be set_rtc_mmss in update_persistent_clock(). In fact,
set_rtc_mmss() should probably just be rolled into update_persistent_clock().

Furthermore, last_rtc_update and its comment should be deleted.

Apart from that, it seems to work.

David

2010-01-05 17:20:53

by Kristoffer Glembo

[permalink] [raw]
Subject: Re: [RFC][PATCH 14/14] Convert sparc to read/update_persistent_clock

Hi,

john stultz wrote:
> This patch converts the sparc architecture to use the generic
> read_persistent_clock and update_persistent_clock interfaces, reducing
> the amount of arch specific code we have to maintain, and allowing for
> further cleanups in the future.
>
> I have not built or tested this patch, so help from arch maintainers
> would be appreciated.
>
>
> Signed-off-by: John Stultz <[email protected]>
>

The sparc32 patch does not build because you forgot to remove the
last_rtc_update variable declaration:

arch/sparc/kernel/time_32.c: In function 'timer_interrupt':
arch/sparc/kernel/time_32.c:94: warning: unused variable 'last_rtc_update'

Best regards,
Kristoffer Glembo