Commit 82644459c592a28a3eab682f9b88d81019ddfe8b

Authored by Thomas Gleixner
Committed by Linus Torvalds
1 parent 99bc2fcb28

NTP: move the cmos update code into ntp.c

i386 and sparc64 have the identical code to update the cmos clock.  Move it
into kernel/time/ntp.c as there are other architectures coming along with the
same requirements.

[akpm@linux-foundation.org: build fixes]
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Chris Wright <chrisw@sous-sol.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: john stultz <johnstul@us.ibm.com>
Cc: David Miller <davem@davemloft.net>
Cc: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 7 changed files with 71 additions and 103 deletions Side-by-side Diff

... ... @@ -18,6 +18,10 @@
18 18 bool
19 19 default y
20 20  
  21 +config GENERIC_CMOS_UPDATE
  22 + bool
  23 + default y
  24 +
21 25 config CLOCKSOURCE_WATCHDOG
22 26 bool
23 27 default y
arch/i386/kernel/time.c
... ... @@ -207,55 +207,9 @@
207 207 return retval;
208 208 }
209 209  
210   -static void sync_cmos_clock(unsigned long dummy);
211   -
212   -static DEFINE_TIMER(sync_cmos_timer, sync_cmos_clock, 0, 0);
213   -int no_sync_cmos_clock;
214   -
215   -static void sync_cmos_clock(unsigned long dummy)
  210 +int update_persistent_clock(struct timespec now)
216 211 {
217   - struct timeval now, next;
218   - int fail = 1;
219   -
220   - /*
221   - * If we have an externally synchronized Linux clock, then update
222   - * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
223   - * called as close as possible to 500 ms before the new second starts.
224   - * This code is run on a timer. If the clock is set, that timer
225   - * may not expire at the correct time. Thus, we adjust...
226   - */
227   - if (!ntp_synced())
228   - /*
229   - * Not synced, exit, do not restart a timer (if one is
230   - * running, let it run out).
231   - */
232   - return;
233   -
234   - do_gettimeofday(&now);
235   - if (now.tv_usec >= USEC_AFTER - ((unsigned) TICK_SIZE) / 2 &&
236   - now.tv_usec <= USEC_BEFORE + ((unsigned) TICK_SIZE) / 2)
237   - fail = set_rtc_mmss(now.tv_sec);
238   -
239   - next.tv_usec = USEC_AFTER - now.tv_usec;
240   - if (next.tv_usec <= 0)
241   - next.tv_usec += USEC_PER_SEC;
242   -
243   - if (!fail)
244   - next.tv_sec = 659;
245   - else
246   - next.tv_sec = 0;
247   -
248   - if (next.tv_usec >= USEC_PER_SEC) {
249   - next.tv_sec++;
250   - next.tv_usec -= USEC_PER_SEC;
251   - }
252   - mod_timer(&sync_cmos_timer, jiffies + timeval_to_jiffies(&next));
253   -}
254   -
255   -void notify_arch_cmos_timer(void)
256   -{
257   - if (!no_sync_cmos_clock)
258   - mod_timer(&sync_cmos_timer, jiffies + 1);
  212 + return set_rtc_mmss(now.tv_sec);
259 213 }
260 214  
261 215 extern void (*late_time_init)(void);
arch/sparc64/Kconfig
... ... @@ -23,6 +23,10 @@
23 23 bool
24 24 default y
25 25  
  26 +config GENERIC_CMOS_UPDATE
  27 + bool
  28 + default y
  29 +
26 30 config GENERIC_CLOCKEVENTS
27 31 bool
28 32 default y
arch/sparc64/kernel/time.c
... ... @@ -403,58 +403,9 @@
403 403  
404 404 static unsigned long timer_ticks_per_nsec_quotient __read_mostly;
405 405  
406   -#define TICK_SIZE (tick_nsec / 1000)
407   -
408   -#define USEC_AFTER 500000
409   -#define USEC_BEFORE 500000
410   -
411   -static void sync_cmos_clock(unsigned long dummy);
412   -
413   -static DEFINE_TIMER(sync_cmos_timer, sync_cmos_clock, 0, 0);
414   -
415   -static void sync_cmos_clock(unsigned long dummy)
  406 +int update_persistent_clock(struct timespec now)
416 407 {
417   - struct timeval now, next;
418   - int fail = 1;
419   -
420   - /*
421   - * If we have an externally synchronized Linux clock, then update
422   - * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
423   - * called as close as possible to 500 ms before the new second starts.
424   - * This code is run on a timer. If the clock is set, that timer
425   - * may not expire at the correct time. Thus, we adjust...
426   - */
427   - if (!ntp_synced())
428   - /*
429   - * Not synced, exit, do not restart a timer (if one is
430   - * running, let it run out).
431   - */
432   - return;
433   -
434   - do_gettimeofday(&now);
435   - if (now.tv_usec >= USEC_AFTER - ((unsigned) TICK_SIZE) / 2 &&
436   - now.tv_usec <= USEC_BEFORE + ((unsigned) TICK_SIZE) / 2)
437   - fail = set_rtc_mmss(now.tv_sec);
438   -
439   - next.tv_usec = USEC_AFTER - now.tv_usec;
440   - if (next.tv_usec <= 0)
441   - next.tv_usec += USEC_PER_SEC;
442   -
443   - if (!fail)
444   - next.tv_sec = 659;
445   - else
446   - next.tv_sec = 0;
447   -
448   - if (next.tv_usec >= USEC_PER_SEC) {
449   - next.tv_sec++;
450   - next.tv_usec -= USEC_PER_SEC;
451   - }
452   - mod_timer(&sync_cmos_timer, jiffies + timeval_to_jiffies(&next));
453   -}
454   -
455   -void notify_arch_cmos_timer(void)
456   -{
457   - mod_timer(&sync_cmos_timer, jiffies + 1);
  408 + return set_rtc_mmss(now.tv_sec);
458 409 }
459 410  
460 411 /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */
include/asm-i386/timer.h
... ... @@ -11,7 +11,6 @@
11 11  
12 12 extern int timer_ack;
13 13 extern int no_timer_check;
14   -extern int no_sync_cmos_clock;
15 14 extern int recalibrate_cpu_khz(void);
16 15  
17 16 #ifndef CONFIG_PARAVIRT
include/linux/time.h
... ... @@ -4,6 +4,7 @@
4 4 #include <linux/types.h>
5 5  
6 6 #ifdef __KERNEL__
  7 +# include <linux/cache.h>
7 8 # include <linux/seqlock.h>
8 9 #endif
9 10  
... ... @@ -94,6 +95,8 @@
94 95 extern seqlock_t xtime_lock __attribute__((weak));
95 96  
96 97 extern unsigned long read_persistent_clock(void);
  98 +extern int update_persistent_clock(struct timespec now);
  99 +extern int no_sync_cmos_clock __read_mostly;
97 100 void timekeeping_init(void);
98 101  
99 102 static inline unsigned long get_seconds(void)
... ... @@ -10,6 +10,7 @@
10 10  
11 11 #include <linux/mm.h>
12 12 #include <linux/time.h>
  13 +#include <linux/timer.h>
13 14 #include <linux/timex.h>
14 15 #include <linux/jiffies.h>
15 16 #include <linux/hrtimer.h>
16 17  
17 18  
18 19  
... ... @@ -175,12 +176,64 @@
175 176 return tick_length;
176 177 }
177 178  
  179 +#ifdef CONFIG_GENERIC_CMOS_UPDATE
178 180  
179   -void __attribute__ ((weak)) notify_arch_cmos_timer(void)
  181 +/* Disable the cmos update - used by virtualization and embedded */
  182 +int no_sync_cmos_clock __read_mostly;
  183 +
  184 +static void sync_cmos_clock(unsigned long dummy);
  185 +
  186 +static DEFINE_TIMER(sync_cmos_timer, sync_cmos_clock, 0, 0);
  187 +
  188 +static void sync_cmos_clock(unsigned long dummy)
180 189 {
181   - return;
  190 + struct timespec now, next;
  191 + int fail = 1;
  192 +
  193 + /*
  194 + * If we have an externally synchronized Linux clock, then update
  195 + * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
  196 + * called as close as possible to 500 ms before the new second starts.
  197 + * This code is run on a timer. If the clock is set, that timer
  198 + * may not expire at the correct time. Thus, we adjust...
  199 + */
  200 + if (!ntp_synced())
  201 + /*
  202 + * Not synced, exit, do not restart a timer (if one is
  203 + * running, let it run out).
  204 + */
  205 + return;
  206 +
  207 + getnstimeofday(&now);
  208 + if (abs(xtime.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2)
  209 + fail = update_persistent_clock(now);
  210 +
  211 + next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec;
  212 + if (next.tv_nsec <= 0)
  213 + next.tv_nsec += NSEC_PER_SEC;
  214 +
  215 + if (!fail)
  216 + next.tv_sec = 659;
  217 + else
  218 + next.tv_sec = 0;
  219 +
  220 + if (next.tv_nsec >= NSEC_PER_SEC) {
  221 + next.tv_sec++;
  222 + next.tv_nsec -= NSEC_PER_SEC;
  223 + }
  224 + mod_timer(&sync_cmos_timer, jiffies + timespec_to_jiffies(&next));
182 225 }
183 226  
  227 +static void notify_cmos_timer(void)
  228 +{
  229 + if (no_sync_cmos_clock)
  230 + mod_timer(&sync_cmos_timer, jiffies + 1);
  231 +}
  232 +
  233 +#else
  234 +static inline void notify_cmos_timer(void) { }
  235 +#endif
  236 +
184 237 /* adjtimex mainly allows reading (and writing, if superuser) of
185 238 * kernel time-keeping variables. used by xntpd.
186 239 */
... ... @@ -345,7 +398,7 @@
345 398 txc->stbcnt = 0;
346 399 write_sequnlock_irq(&xtime_lock);
347 400 do_gettimeofday(&txc->time);
348   - notify_arch_cmos_timer();
  401 + notify_cmos_timer();
349 402 return(result);
350 403 }