aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/time')
-rw-r--r--kernel/time/timekeeping.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 0c6358186401..8427cc20bad6 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -47,6 +47,10 @@ struct timekeeper {
47 int ntp_error_shift; 47 int ntp_error_shift;
48 /* NTP adjusted clock multiplier */ 48 /* NTP adjusted clock multiplier */
49 u32 mult; 49 u32 mult;
50
51 /* time spent in suspend */
52 struct timespec total_sleep_time;
53
50}; 54};
51 55
52static struct timekeeper timekeeper; 56static struct timekeeper timekeeper;
@@ -159,7 +163,6 @@ __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock);
159 */ 163 */
160static struct timespec xtime __attribute__ ((aligned (16))); 164static struct timespec xtime __attribute__ ((aligned (16)));
161static struct timespec wall_to_monotonic __attribute__ ((aligned (16))); 165static struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
162static struct timespec total_sleep_time;
163 166
164/* 167/*
165 * The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock. 168 * The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock.
@@ -591,8 +594,8 @@ void __init timekeeping_init(void)
591 } 594 }
592 set_normalized_timespec(&wall_to_monotonic, 595 set_normalized_timespec(&wall_to_monotonic,
593 -boot.tv_sec, -boot.tv_nsec); 596 -boot.tv_sec, -boot.tv_nsec);
594 total_sleep_time.tv_sec = 0; 597 timekeeper.total_sleep_time.tv_sec = 0;
595 total_sleep_time.tv_nsec = 0; 598 timekeeper.total_sleep_time.tv_nsec = 0;
596 write_sequnlock_irqrestore(&xtime_lock, flags); 599 write_sequnlock_irqrestore(&xtime_lock, flags);
597} 600}
598 601
@@ -616,7 +619,8 @@ static void __timekeeping_inject_sleeptime(struct timespec *delta)
616 619
617 xtime = timespec_add(xtime, *delta); 620 xtime = timespec_add(xtime, *delta);
618 wall_to_monotonic = timespec_sub(wall_to_monotonic, *delta); 621 wall_to_monotonic = timespec_sub(wall_to_monotonic, *delta);
619 total_sleep_time = timespec_add(total_sleep_time, *delta); 622 timekeeper.total_sleep_time = timespec_add(
623 timekeeper.total_sleep_time, *delta);
620} 624}
621 625
622 626
@@ -1074,8 +1078,10 @@ static void update_wall_time(void)
1074void getboottime(struct timespec *ts) 1078void getboottime(struct timespec *ts)
1075{ 1079{
1076 struct timespec boottime = { 1080 struct timespec boottime = {
1077 .tv_sec = wall_to_monotonic.tv_sec + total_sleep_time.tv_sec, 1081 .tv_sec = wall_to_monotonic.tv_sec +
1078 .tv_nsec = wall_to_monotonic.tv_nsec + total_sleep_time.tv_nsec 1082 timekeeper.total_sleep_time.tv_sec,
1083 .tv_nsec = wall_to_monotonic.tv_nsec +
1084 timekeeper.total_sleep_time.tv_nsec
1079 }; 1085 };
1080 1086
1081 set_normalized_timespec(ts, -boottime.tv_sec, -boottime.tv_nsec); 1087 set_normalized_timespec(ts, -boottime.tv_sec, -boottime.tv_nsec);
@@ -1104,7 +1110,7 @@ void get_monotonic_boottime(struct timespec *ts)
1104 seq = read_seqbegin(&xtime_lock); 1110 seq = read_seqbegin(&xtime_lock);
1105 *ts = xtime; 1111 *ts = xtime;
1106 tomono = wall_to_monotonic; 1112 tomono = wall_to_monotonic;
1107 sleep = total_sleep_time; 1113 sleep = timekeeper.total_sleep_time;
1108 nsecs = timekeeping_get_ns(); 1114 nsecs = timekeeping_get_ns();
1109 1115
1110 } while (read_seqretry(&xtime_lock, seq)); 1116 } while (read_seqretry(&xtime_lock, seq));
@@ -1137,7 +1143,7 @@ EXPORT_SYMBOL_GPL(ktime_get_boottime);
1137 */ 1143 */
1138void monotonic_to_bootbased(struct timespec *ts) 1144void monotonic_to_bootbased(struct timespec *ts)
1139{ 1145{
1140 *ts = timespec_add(*ts, total_sleep_time); 1146 *ts = timespec_add(*ts, timekeeper.total_sleep_time);
1141} 1147}
1142EXPORT_SYMBOL_GPL(monotonic_to_bootbased); 1148EXPORT_SYMBOL_GPL(monotonic_to_bootbased);
1143 1149
@@ -1212,7 +1218,7 @@ void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim,
1212 seq = read_seqbegin(&xtime_lock); 1218 seq = read_seqbegin(&xtime_lock);
1213 *xtim = xtime; 1219 *xtim = xtime;
1214 *wtom = wall_to_monotonic; 1220 *wtom = wall_to_monotonic;
1215 *sleep = total_sleep_time; 1221 *sleep = timekeeper.total_sleep_time;
1216 } while (read_seqretry(&xtime_lock, seq)); 1222 } while (read_seqretry(&xtime_lock, seq));
1217} 1223}
1218 1224