diff options
Diffstat (limited to 'kernel/time/timekeeping.c')
-rw-r--r-- | kernel/time/timekeeping.c | 79 |
1 files changed, 20 insertions, 59 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index caf8d4d4f5c8..e14c839e9faa 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -153,8 +153,8 @@ __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock); | |||
153 | * - wall_to_monotonic is no longer the boot time, getboottime must be | 153 | * - wall_to_monotonic is no longer the boot time, getboottime must be |
154 | * used instead. | 154 | * used instead. |
155 | */ | 155 | */ |
156 | struct timespec xtime __attribute__ ((aligned (16))); | 156 | static struct timespec xtime __attribute__ ((aligned (16))); |
157 | struct timespec wall_to_monotonic __attribute__ ((aligned (16))); | 157 | static struct timespec wall_to_monotonic __attribute__ ((aligned (16))); |
158 | static struct timespec total_sleep_time; | 158 | static struct timespec total_sleep_time; |
159 | 159 | ||
160 | /* | 160 | /* |
@@ -170,11 +170,10 @@ void timekeeping_leap_insert(int leapsecond) | |||
170 | { | 170 | { |
171 | xtime.tv_sec += leapsecond; | 171 | xtime.tv_sec += leapsecond; |
172 | wall_to_monotonic.tv_sec -= leapsecond; | 172 | wall_to_monotonic.tv_sec -= leapsecond; |
173 | update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult); | 173 | update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, |
174 | timekeeper.mult); | ||
174 | } | 175 | } |
175 | 176 | ||
176 | #ifdef CONFIG_GENERIC_TIME | ||
177 | |||
178 | /** | 177 | /** |
179 | * timekeeping_forward_now - update clock to the current time | 178 | * timekeeping_forward_now - update clock to the current time |
180 | * | 179 | * |
@@ -328,7 +327,8 @@ int do_settimeofday(struct timespec *tv) | |||
328 | timekeeper.ntp_error = 0; | 327 | timekeeper.ntp_error = 0; |
329 | ntp_clear(); | 328 | ntp_clear(); |
330 | 329 | ||
331 | update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult); | 330 | update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, |
331 | timekeeper.mult); | ||
332 | 332 | ||
333 | write_sequnlock_irqrestore(&xtime_lock, flags); | 333 | write_sequnlock_irqrestore(&xtime_lock, flags); |
334 | 334 | ||
@@ -376,52 +376,6 @@ void timekeeping_notify(struct clocksource *clock) | |||
376 | tick_clock_notify(); | 376 | tick_clock_notify(); |
377 | } | 377 | } |
378 | 378 | ||
379 | #else /* GENERIC_TIME */ | ||
380 | |||
381 | static inline void timekeeping_forward_now(void) { } | ||
382 | |||
383 | /** | ||
384 | * ktime_get - get the monotonic time in ktime_t format | ||
385 | * | ||
386 | * returns the time in ktime_t format | ||
387 | */ | ||
388 | ktime_t ktime_get(void) | ||
389 | { | ||
390 | struct timespec now; | ||
391 | |||
392 | ktime_get_ts(&now); | ||
393 | |||
394 | return timespec_to_ktime(now); | ||
395 | } | ||
396 | EXPORT_SYMBOL_GPL(ktime_get); | ||
397 | |||
398 | /** | ||
399 | * ktime_get_ts - get the monotonic clock in timespec format | ||
400 | * @ts: pointer to timespec variable | ||
401 | * | ||
402 | * The function calculates the monotonic clock from the realtime | ||
403 | * clock and the wall_to_monotonic offset and stores the result | ||
404 | * in normalized timespec format in the variable pointed to by @ts. | ||
405 | */ | ||
406 | void ktime_get_ts(struct timespec *ts) | ||
407 | { | ||
408 | struct timespec tomono; | ||
409 | unsigned long seq; | ||
410 | |||
411 | do { | ||
412 | seq = read_seqbegin(&xtime_lock); | ||
413 | getnstimeofday(ts); | ||
414 | tomono = wall_to_monotonic; | ||
415 | |||
416 | } while (read_seqretry(&xtime_lock, seq)); | ||
417 | |||
418 | set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec, | ||
419 | ts->tv_nsec + tomono.tv_nsec); | ||
420 | } | ||
421 | EXPORT_SYMBOL_GPL(ktime_get_ts); | ||
422 | |||
423 | #endif /* !GENERIC_TIME */ | ||
424 | |||
425 | /** | 379 | /** |
426 | * ktime_get_real - get the real (wall-) time in ktime_t format | 380 | * ktime_get_real - get the real (wall-) time in ktime_t format |
427 | * | 381 | * |
@@ -579,9 +533,9 @@ static int timekeeping_resume(struct sys_device *dev) | |||
579 | 533 | ||
580 | if (timespec_compare(&ts, &timekeeping_suspend_time) > 0) { | 534 | if (timespec_compare(&ts, &timekeeping_suspend_time) > 0) { |
581 | ts = timespec_sub(ts, timekeeping_suspend_time); | 535 | ts = timespec_sub(ts, timekeeping_suspend_time); |
582 | xtime = timespec_add_safe(xtime, ts); | 536 | xtime = timespec_add(xtime, ts); |
583 | wall_to_monotonic = timespec_sub(wall_to_monotonic, ts); | 537 | wall_to_monotonic = timespec_sub(wall_to_monotonic, ts); |
584 | total_sleep_time = timespec_add_safe(total_sleep_time, ts); | 538 | total_sleep_time = timespec_add(total_sleep_time, ts); |
585 | } | 539 | } |
586 | /* re-base the last cycle value */ | 540 | /* re-base the last cycle value */ |
587 | timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock); | 541 | timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock); |
@@ -784,10 +738,11 @@ void update_wall_time(void) | |||
784 | return; | 738 | return; |
785 | 739 | ||
786 | clock = timekeeper.clock; | 740 | clock = timekeeper.clock; |
787 | #ifdef CONFIG_GENERIC_TIME | 741 | |
788 | offset = (clock->read(clock) - clock->cycle_last) & clock->mask; | 742 | #ifdef CONFIG_ARCH_USES_GETTIMEOFFSET |
789 | #else | ||
790 | offset = timekeeper.cycle_interval; | 743 | offset = timekeeper.cycle_interval; |
744 | #else | ||
745 | offset = (clock->read(clock) - clock->cycle_last) & clock->mask; | ||
791 | #endif | 746 | #endif |
792 | timekeeper.xtime_nsec = (s64)xtime.tv_nsec << timekeeper.shift; | 747 | timekeeper.xtime_nsec = (s64)xtime.tv_nsec << timekeeper.shift; |
793 | 748 | ||
@@ -856,7 +811,8 @@ void update_wall_time(void) | |||
856 | } | 811 | } |
857 | 812 | ||
858 | /* check to see if there is a new clocksource to use */ | 813 | /* check to see if there is a new clocksource to use */ |
859 | update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult); | 814 | update_vsyscall(&xtime, &wall_to_monotonic, timekeeper.clock, |
815 | timekeeper.mult); | ||
860 | } | 816 | } |
861 | 817 | ||
862 | /** | 818 | /** |
@@ -887,7 +843,7 @@ EXPORT_SYMBOL_GPL(getboottime); | |||
887 | */ | 843 | */ |
888 | void monotonic_to_bootbased(struct timespec *ts) | 844 | void monotonic_to_bootbased(struct timespec *ts) |
889 | { | 845 | { |
890 | *ts = timespec_add_safe(*ts, total_sleep_time); | 846 | *ts = timespec_add(*ts, total_sleep_time); |
891 | } | 847 | } |
892 | EXPORT_SYMBOL_GPL(monotonic_to_bootbased); | 848 | EXPORT_SYMBOL_GPL(monotonic_to_bootbased); |
893 | 849 | ||
@@ -902,6 +858,11 @@ struct timespec __current_kernel_time(void) | |||
902 | return xtime; | 858 | return xtime; |
903 | } | 859 | } |
904 | 860 | ||
861 | struct timespec __get_wall_to_monotonic(void) | ||
862 | { | ||
863 | return wall_to_monotonic; | ||
864 | } | ||
865 | |||
905 | struct timespec current_kernel_time(void) | 866 | struct timespec current_kernel_time(void) |
906 | { | 867 | { |
907 | struct timespec now; | 868 | struct timespec now; |