diff options
| -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 | ||
