diff options
author | John Stultz <johnstul@us.ibm.com> | 2010-03-03 22:57:16 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2010-03-12 19:14:08 -0500 |
commit | 1e871be1aa97babb467a929d6adcb1960659928b (patch) | |
tree | 350ce942e24d8890552bb62c4227ded8817a13bc /arch/alpha | |
parent | 104f9c471ffb425fd081074ef31521b38d77592a (diff) |
alpha: Convert alpha to use 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.
igned-off-by: John Stultz <johnstul@us.ibm.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Andrew Morton <akpm@linux-foundation.org>
LKML-Reference: <1267675049-12337-2-git-send-email-johnstul@us.ibm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/alpha')
-rw-r--r-- | arch/alpha/Kconfig | 3 | ||||
-rw-r--r-- | arch/alpha/kernel/time.c | 101 |
2 files changed, 50 insertions, 54 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index bd7261ea8f94..75fff7e5a0db 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig | |||
@@ -54,6 +54,9 @@ config ARCH_USES_GETTIMEOFFSET | |||
54 | bool | 54 | bool |
55 | default y | 55 | default y |
56 | 56 | ||
57 | config GENERIC_CMOS_UPDATE | ||
58 | def_bool y | ||
59 | |||
57 | config ZONE_DMA | 60 | config ZONE_DMA |
58 | bool | 61 | bool |
59 | default y | 62 | default y |
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index 5d0826654c61..5465e932e568 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c | |||
@@ -75,8 +75,6 @@ static struct { | |||
75 | __u32 last_time; | 75 | __u32 last_time; |
76 | /* ticks/cycle * 2^48 */ | 76 | /* ticks/cycle * 2^48 */ |
77 | unsigned long scaled_ticks_per_cycle; | 77 | unsigned long scaled_ticks_per_cycle; |
78 | /* last time the CMOS clock got updated */ | ||
79 | time_t last_rtc_update; | ||
80 | /* partial unused tick */ | 78 | /* partial unused tick */ |
81 | unsigned long partial_tick; | 79 | unsigned long partial_tick; |
82 | } state; | 80 | } state; |
@@ -91,6 +89,52 @@ static inline __u32 rpcc(void) | |||
91 | return result; | 89 | return result; |
92 | } | 90 | } |
93 | 91 | ||
92 | int update_persistent_clock(struct timespec now) | ||
93 | { | ||
94 | return set_rtc_mmss(now.tv_sec); | ||
95 | } | ||
96 | |||
97 | void read_persistent_clock(struct timespec *ts) | ||
98 | { | ||
99 | unsigned int year, mon, day, hour, min, sec, epoch; | ||
100 | |||
101 | sec = CMOS_READ(RTC_SECONDS); | ||
102 | min = CMOS_READ(RTC_MINUTES); | ||
103 | hour = CMOS_READ(RTC_HOURS); | ||
104 | day = CMOS_READ(RTC_DAY_OF_MONTH); | ||
105 | mon = CMOS_READ(RTC_MONTH); | ||
106 | year = CMOS_READ(RTC_YEAR); | ||
107 | |||
108 | if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { | ||
109 | sec = bcd2bin(sec); | ||
110 | min = bcd2bin(min); | ||
111 | hour = bcd2bin(hour); | ||
112 | day = bcd2bin(day); | ||
113 | mon = bcd2bin(mon); | ||
114 | year = bcd2bin(year); | ||
115 | } | ||
116 | |||
117 | /* PC-like is standard; used for year >= 70 */ | ||
118 | epoch = 1900; | ||
119 | if (year < 20) | ||
120 | epoch = 2000; | ||
121 | else if (year >= 20 && year < 48) | ||
122 | /* NT epoch */ | ||
123 | epoch = 1980; | ||
124 | else if (year >= 48 && year < 70) | ||
125 | /* Digital UNIX epoch */ | ||
126 | epoch = 1952; | ||
127 | |||
128 | printk(KERN_INFO "Using epoch = %d\n", epoch); | ||
129 | |||
130 | if ((year += epoch) < 1970) | ||
131 | year += 100; | ||
132 | |||
133 | ts->tv_sec = mktime(year, mon, day, hour, min, sec); | ||
134 | } | ||
135 | |||
136 | |||
137 | |||
94 | /* | 138 | /* |
95 | * timer_interrupt() needs to keep up the real-time clock, | 139 | * timer_interrupt() needs to keep up the real-time clock, |
96 | * as well as call the "do_timer()" routine every clocktick | 140 | * as well as call the "do_timer()" routine every clocktick |
@@ -123,19 +167,6 @@ irqreturn_t timer_interrupt(int irq, void *dev) | |||
123 | if (nticks) | 167 | if (nticks) |
124 | do_timer(nticks); | 168 | do_timer(nticks); |
125 | 169 | ||
126 | /* | ||
127 | * If we have an externally synchronized Linux clock, then update | ||
128 | * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be | ||
129 | * called as close as possible to 500 ms before the new second starts. | ||
130 | */ | ||
131 | if (ntp_synced() | ||
132 | && xtime.tv_sec > state.last_rtc_update + 660 | ||
133 | && xtime.tv_nsec >= 500000 - ((unsigned) TICK_SIZE) / 2 | ||
134 | && xtime.tv_nsec <= 500000 + ((unsigned) TICK_SIZE) / 2) { | ||
135 | int tmp = set_rtc_mmss(xtime.tv_sec); | ||
136 | state.last_rtc_update = xtime.tv_sec - (tmp ? 600 : 0); | ||
137 | } | ||
138 | |||
139 | write_sequnlock(&xtime_lock); | 170 | write_sequnlock(&xtime_lock); |
140 | 171 | ||
141 | #ifndef CONFIG_SMP | 172 | #ifndef CONFIG_SMP |
@@ -304,7 +335,7 @@ rpcc_after_update_in_progress(void) | |||
304 | void __init | 335 | void __init |
305 | time_init(void) | 336 | time_init(void) |
306 | { | 337 | { |
307 | unsigned int year, mon, day, hour, min, sec, cc1, cc2, epoch; | 338 | unsigned int cc1, cc2; |
308 | unsigned long cycle_freq, tolerance; | 339 | unsigned long cycle_freq, tolerance; |
309 | long diff; | 340 | long diff; |
310 | 341 | ||
@@ -348,43 +379,6 @@ time_init(void) | |||
348 | bogomips yet, but this is close on a 500Mhz box. */ | 379 | bogomips yet, but this is close on a 500Mhz box. */ |
349 | __delay(1000000); | 380 | __delay(1000000); |
350 | 381 | ||
351 | sec = CMOS_READ(RTC_SECONDS); | ||
352 | min = CMOS_READ(RTC_MINUTES); | ||
353 | hour = CMOS_READ(RTC_HOURS); | ||
354 | day = CMOS_READ(RTC_DAY_OF_MONTH); | ||
355 | mon = CMOS_READ(RTC_MONTH); | ||
356 | year = CMOS_READ(RTC_YEAR); | ||
357 | |||
358 | if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { | ||
359 | sec = bcd2bin(sec); | ||
360 | min = bcd2bin(min); | ||
361 | hour = bcd2bin(hour); | ||
362 | day = bcd2bin(day); | ||
363 | mon = bcd2bin(mon); | ||
364 | year = bcd2bin(year); | ||
365 | } | ||
366 | |||
367 | /* PC-like is standard; used for year >= 70 */ | ||
368 | epoch = 1900; | ||
369 | if (year < 20) | ||
370 | epoch = 2000; | ||
371 | else if (year >= 20 && year < 48) | ||
372 | /* NT epoch */ | ||
373 | epoch = 1980; | ||
374 | else if (year >= 48 && year < 70) | ||
375 | /* Digital UNIX epoch */ | ||
376 | epoch = 1952; | ||
377 | |||
378 | printk(KERN_INFO "Using epoch = %d\n", epoch); | ||
379 | |||
380 | if ((year += epoch) < 1970) | ||
381 | year += 100; | ||
382 | |||
383 | xtime.tv_sec = mktime(year, mon, day, hour, min, sec); | ||
384 | xtime.tv_nsec = 0; | ||
385 | |||
386 | wall_to_monotonic.tv_sec -= xtime.tv_sec; | ||
387 | wall_to_monotonic.tv_nsec = 0; | ||
388 | 382 | ||
389 | if (HZ > (1<<16)) { | 383 | if (HZ > (1<<16)) { |
390 | extern void __you_loose (void); | 384 | extern void __you_loose (void); |
@@ -394,7 +388,6 @@ time_init(void) | |||
394 | state.last_time = cc1; | 388 | state.last_time = cc1; |
395 | state.scaled_ticks_per_cycle | 389 | state.scaled_ticks_per_cycle |
396 | = ((unsigned long) HZ << FIX_SHIFT) / cycle_freq; | 390 | = ((unsigned long) HZ << FIX_SHIFT) / cycle_freq; |
397 | state.last_rtc_update = 0; | ||
398 | state.partial_tick = 0L; | 391 | state.partial_tick = 0L; |
399 | 392 | ||
400 | /* Startup the timer source. */ | 393 | /* Startup the timer source. */ |