diff options
Diffstat (limited to 'kernel/time/ntp.c')
-rw-r--r-- | kernel/time/ntp.c | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 24174b4d669b..072bb066bb7d 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/time.h> | 15 | #include <linux/time.h> |
16 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/rtc.h> | ||
18 | 19 | ||
19 | #include "tick-internal.h" | 20 | #include "tick-internal.h" |
20 | 21 | ||
@@ -22,7 +23,7 @@ | |||
22 | * NTP timekeeping variables: | 23 | * NTP timekeeping variables: |
23 | */ | 24 | */ |
24 | 25 | ||
25 | DEFINE_SPINLOCK(ntp_lock); | 26 | DEFINE_RAW_SPINLOCK(ntp_lock); |
26 | 27 | ||
27 | 28 | ||
28 | /* USER_HZ period (usecs): */ | 29 | /* USER_HZ period (usecs): */ |
@@ -347,7 +348,7 @@ void ntp_clear(void) | |||
347 | { | 348 | { |
348 | unsigned long flags; | 349 | unsigned long flags; |
349 | 350 | ||
350 | spin_lock_irqsave(&ntp_lock, flags); | 351 | raw_spin_lock_irqsave(&ntp_lock, flags); |
351 | 352 | ||
352 | time_adjust = 0; /* stop active adjtime() */ | 353 | time_adjust = 0; /* stop active adjtime() */ |
353 | time_status |= STA_UNSYNC; | 354 | time_status |= STA_UNSYNC; |
@@ -361,7 +362,7 @@ void ntp_clear(void) | |||
361 | 362 | ||
362 | /* Clear PPS state variables */ | 363 | /* Clear PPS state variables */ |
363 | pps_clear(); | 364 | pps_clear(); |
364 | spin_unlock_irqrestore(&ntp_lock, flags); | 365 | raw_spin_unlock_irqrestore(&ntp_lock, flags); |
365 | 366 | ||
366 | } | 367 | } |
367 | 368 | ||
@@ -371,9 +372,9 @@ u64 ntp_tick_length(void) | |||
371 | unsigned long flags; | 372 | unsigned long flags; |
372 | s64 ret; | 373 | s64 ret; |
373 | 374 | ||
374 | spin_lock_irqsave(&ntp_lock, flags); | 375 | raw_spin_lock_irqsave(&ntp_lock, flags); |
375 | ret = tick_length; | 376 | ret = tick_length; |
376 | spin_unlock_irqrestore(&ntp_lock, flags); | 377 | raw_spin_unlock_irqrestore(&ntp_lock, flags); |
377 | return ret; | 378 | return ret; |
378 | } | 379 | } |
379 | 380 | ||
@@ -394,7 +395,7 @@ int second_overflow(unsigned long secs) | |||
394 | int leap = 0; | 395 | int leap = 0; |
395 | unsigned long flags; | 396 | unsigned long flags; |
396 | 397 | ||
397 | spin_lock_irqsave(&ntp_lock, flags); | 398 | raw_spin_lock_irqsave(&ntp_lock, flags); |
398 | 399 | ||
399 | /* | 400 | /* |
400 | * Leap second processing. If in leap-insert state at the end of the | 401 | * Leap second processing. If in leap-insert state at the end of the |
@@ -478,13 +479,12 @@ int second_overflow(unsigned long secs) | |||
478 | time_adjust = 0; | 479 | time_adjust = 0; |
479 | 480 | ||
480 | out: | 481 | out: |
481 | spin_unlock_irqrestore(&ntp_lock, flags); | 482 | raw_spin_unlock_irqrestore(&ntp_lock, flags); |
482 | 483 | ||
483 | return leap; | 484 | return leap; |
484 | } | 485 | } |
485 | 486 | ||
486 | #ifdef CONFIG_GENERIC_CMOS_UPDATE | 487 | #if defined(CONFIG_GENERIC_CMOS_UPDATE) || defined(CONFIG_RTC_SYSTOHC) |
487 | |||
488 | static void sync_cmos_clock(struct work_struct *work); | 488 | static void sync_cmos_clock(struct work_struct *work); |
489 | 489 | ||
490 | static DECLARE_DELAYED_WORK(sync_cmos_work, sync_cmos_clock); | 490 | static DECLARE_DELAYED_WORK(sync_cmos_work, sync_cmos_clock); |
@@ -510,14 +510,26 @@ static void sync_cmos_clock(struct work_struct *work) | |||
510 | } | 510 | } |
511 | 511 | ||
512 | getnstimeofday(&now); | 512 | getnstimeofday(&now); |
513 | if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2) | 513 | if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2) { |
514 | fail = update_persistent_clock(now); | 514 | struct timespec adjust = now; |
515 | |||
516 | fail = -ENODEV; | ||
517 | if (persistent_clock_is_local) | ||
518 | adjust.tv_sec -= (sys_tz.tz_minuteswest * 60); | ||
519 | #ifdef CONFIG_GENERIC_CMOS_UPDATE | ||
520 | fail = update_persistent_clock(adjust); | ||
521 | #endif | ||
522 | #ifdef CONFIG_RTC_SYSTOHC | ||
523 | if (fail == -ENODEV) | ||
524 | fail = rtc_set_ntp_time(adjust); | ||
525 | #endif | ||
526 | } | ||
515 | 527 | ||
516 | next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec - (TICK_NSEC / 2); | 528 | next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec - (TICK_NSEC / 2); |
517 | if (next.tv_nsec <= 0) | 529 | if (next.tv_nsec <= 0) |
518 | next.tv_nsec += NSEC_PER_SEC; | 530 | next.tv_nsec += NSEC_PER_SEC; |
519 | 531 | ||
520 | if (!fail) | 532 | if (!fail || fail == -ENODEV) |
521 | next.tv_sec = 659; | 533 | next.tv_sec = 659; |
522 | else | 534 | else |
523 | next.tv_sec = 0; | 535 | next.tv_sec = 0; |
@@ -660,7 +672,7 @@ int do_adjtimex(struct timex *txc) | |||
660 | 672 | ||
661 | getnstimeofday(&ts); | 673 | getnstimeofday(&ts); |
662 | 674 | ||
663 | spin_lock_irq(&ntp_lock); | 675 | raw_spin_lock_irq(&ntp_lock); |
664 | 676 | ||
665 | if (txc->modes & ADJ_ADJTIME) { | 677 | if (txc->modes & ADJ_ADJTIME) { |
666 | long save_adjust = time_adjust; | 678 | long save_adjust = time_adjust; |
@@ -702,7 +714,7 @@ int do_adjtimex(struct timex *txc) | |||
702 | /* fill PPS status fields */ | 714 | /* fill PPS status fields */ |
703 | pps_fill_timex(txc); | 715 | pps_fill_timex(txc); |
704 | 716 | ||
705 | spin_unlock_irq(&ntp_lock); | 717 | raw_spin_unlock_irq(&ntp_lock); |
706 | 718 | ||
707 | txc->time.tv_sec = ts.tv_sec; | 719 | txc->time.tv_sec = ts.tv_sec; |
708 | txc->time.tv_usec = ts.tv_nsec; | 720 | txc->time.tv_usec = ts.tv_nsec; |
@@ -900,7 +912,7 @@ void hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts) | |||
900 | 912 | ||
901 | pts_norm = pps_normalize_ts(*phase_ts); | 913 | pts_norm = pps_normalize_ts(*phase_ts); |
902 | 914 | ||
903 | spin_lock_irqsave(&ntp_lock, flags); | 915 | raw_spin_lock_irqsave(&ntp_lock, flags); |
904 | 916 | ||
905 | /* clear the error bits, they will be set again if needed */ | 917 | /* clear the error bits, they will be set again if needed */ |
906 | time_status &= ~(STA_PPSJITTER | STA_PPSWANDER | STA_PPSERROR); | 918 | time_status &= ~(STA_PPSJITTER | STA_PPSWANDER | STA_PPSERROR); |
@@ -913,7 +925,7 @@ void hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts) | |||
913 | * just start the frequency interval */ | 925 | * just start the frequency interval */ |
914 | if (unlikely(pps_fbase.tv_sec == 0)) { | 926 | if (unlikely(pps_fbase.tv_sec == 0)) { |
915 | pps_fbase = *raw_ts; | 927 | pps_fbase = *raw_ts; |
916 | spin_unlock_irqrestore(&ntp_lock, flags); | 928 | raw_spin_unlock_irqrestore(&ntp_lock, flags); |
917 | return; | 929 | return; |
918 | } | 930 | } |
919 | 931 | ||
@@ -928,7 +940,7 @@ void hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts) | |||
928 | time_status |= STA_PPSJITTER; | 940 | time_status |= STA_PPSJITTER; |
929 | /* restart the frequency calibration interval */ | 941 | /* restart the frequency calibration interval */ |
930 | pps_fbase = *raw_ts; | 942 | pps_fbase = *raw_ts; |
931 | spin_unlock_irqrestore(&ntp_lock, flags); | 943 | raw_spin_unlock_irqrestore(&ntp_lock, flags); |
932 | pr_err("hardpps: PPSJITTER: bad pulse\n"); | 944 | pr_err("hardpps: PPSJITTER: bad pulse\n"); |
933 | return; | 945 | return; |
934 | } | 946 | } |
@@ -945,7 +957,7 @@ void hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts) | |||
945 | 957 | ||
946 | hardpps_update_phase(pts_norm.nsec); | 958 | hardpps_update_phase(pts_norm.nsec); |
947 | 959 | ||
948 | spin_unlock_irqrestore(&ntp_lock, flags); | 960 | raw_spin_unlock_irqrestore(&ntp_lock, flags); |
949 | } | 961 | } |
950 | EXPORT_SYMBOL(hardpps); | 962 | EXPORT_SYMBOL(hardpps); |
951 | 963 | ||