diff options
Diffstat (limited to 'kernel/time')
-rw-r--r-- | kernel/time/timekeeping.c | 24 |
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 | ||
52 | static struct timekeeper timekeeper; | 56 | static struct timekeeper timekeeper; |
@@ -159,7 +163,6 @@ __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock); | |||
159 | */ | 163 | */ |
160 | static struct timespec xtime __attribute__ ((aligned (16))); | 164 | static struct timespec xtime __attribute__ ((aligned (16))); |
161 | static struct timespec wall_to_monotonic __attribute__ ((aligned (16))); | 165 | static struct timespec wall_to_monotonic __attribute__ ((aligned (16))); |
162 | static 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) | |||
1074 | void getboottime(struct timespec *ts) | 1078 | void 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 | */ |
1138 | void monotonic_to_bootbased(struct timespec *ts) | 1144 | void 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 | } |
1142 | EXPORT_SYMBOL_GPL(monotonic_to_bootbased); | 1148 | EXPORT_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 | ||