diff options
-rw-r--r-- | include/linux/timekeeper_internal.h | 4 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 35 |
2 files changed, 19 insertions, 20 deletions
diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h index cb88096222c0..75bb8add78f5 100644 --- a/include/linux/timekeeper_internal.h +++ b/include/linux/timekeeper_internal.h | |||
@@ -29,6 +29,10 @@ | |||
29 | struct timekeeper { | 29 | struct timekeeper { |
30 | /* Current clocksource used for timekeeping. */ | 30 | /* Current clocksource used for timekeeping. */ |
31 | struct clocksource *clock; | 31 | struct clocksource *clock; |
32 | /* Read function of @clock */ | ||
33 | cycle_t (*read)(struct clocksource *cs); | ||
34 | /* Bitmask for two's complement subtraction of non 64bit counters */ | ||
35 | cycle_t mask; | ||
32 | /* Last cycle value */ | 36 | /* Last cycle value */ |
33 | cycle_t cycle_last; | 37 | cycle_t cycle_last; |
34 | /* NTP adjusted clock multiplier */ | 38 | /* NTP adjusted clock multiplier */ |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 4e748c404749..14b7367e6b94 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -121,7 +121,9 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock) | |||
121 | 121 | ||
122 | old_clock = tk->clock; | 122 | old_clock = tk->clock; |
123 | tk->clock = clock; | 123 | tk->clock = clock; |
124 | tk->cycle_last = clock->read(clock); | 124 | tk->read = clock->read; |
125 | tk->mask = clock->mask; | ||
126 | tk->cycle_last = tk->read(clock); | ||
125 | 127 | ||
126 | /* Do the ns -> cycle conversion first, using original mult */ | 128 | /* Do the ns -> cycle conversion first, using original mult */ |
127 | tmp = NTP_INTERVAL_LENGTH; | 129 | tmp = NTP_INTERVAL_LENGTH; |
@@ -174,15 +176,13 @@ static inline u32 arch_gettimeoffset(void) { return 0; } | |||
174 | static inline s64 timekeeping_get_ns(struct timekeeper *tk) | 176 | static inline s64 timekeeping_get_ns(struct timekeeper *tk) |
175 | { | 177 | { |
176 | cycle_t cycle_now, delta; | 178 | cycle_t cycle_now, delta; |
177 | struct clocksource *clock; | ||
178 | s64 nsec; | 179 | s64 nsec; |
179 | 180 | ||
180 | /* read clocksource: */ | 181 | /* read clocksource: */ |
181 | clock = tk->clock; | 182 | cycle_now = tk->read(tk->clock); |
182 | cycle_now = clock->read(clock); | ||
183 | 183 | ||
184 | /* calculate the delta since the last update_wall_time: */ | 184 | /* calculate the delta since the last update_wall_time: */ |
185 | delta = clocksource_delta(cycle_now, tk->cycle_last, clock->mask); | 185 | delta = clocksource_delta(cycle_now, tk->cycle_last, tk->mask); |
186 | 186 | ||
187 | nsec = delta * tk->mult + tk->xtime_nsec; | 187 | nsec = delta * tk->mult + tk->xtime_nsec; |
188 | nsec >>= tk->shift; | 188 | nsec >>= tk->shift; |
@@ -193,16 +193,15 @@ static inline s64 timekeeping_get_ns(struct timekeeper *tk) | |||
193 | 193 | ||
194 | static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk) | 194 | static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk) |
195 | { | 195 | { |
196 | struct clocksource *clock = tk->clock; | ||
196 | cycle_t cycle_now, delta; | 197 | cycle_t cycle_now, delta; |
197 | struct clocksource *clock; | ||
198 | s64 nsec; | 198 | s64 nsec; |
199 | 199 | ||
200 | /* read clocksource: */ | 200 | /* read clocksource: */ |
201 | clock = tk->clock; | 201 | cycle_now = tk->read(clock); |
202 | cycle_now = clock->read(clock); | ||
203 | 202 | ||
204 | /* calculate the delta since the last update_wall_time: */ | 203 | /* calculate the delta since the last update_wall_time: */ |
205 | delta = clocksource_delta(cycle_now, tk->cycle_last, clock->mask); | 204 | delta = clocksource_delta(cycle_now, tk->cycle_last, tk->mask); |
206 | 205 | ||
207 | /* convert delta to nanoseconds. */ | 206 | /* convert delta to nanoseconds. */ |
208 | nsec = clocksource_cyc2ns(delta, clock->mult, clock->shift); | 207 | nsec = clocksource_cyc2ns(delta, clock->mult, clock->shift); |
@@ -337,13 +336,12 @@ static void timekeeping_update(struct timekeeper *tk, unsigned int action) | |||
337 | */ | 336 | */ |
338 | static void timekeeping_forward_now(struct timekeeper *tk) | 337 | static void timekeeping_forward_now(struct timekeeper *tk) |
339 | { | 338 | { |
339 | struct clocksource *clock = tk->clock; | ||
340 | cycle_t cycle_now, delta; | 340 | cycle_t cycle_now, delta; |
341 | struct clocksource *clock; | ||
342 | s64 nsec; | 341 | s64 nsec; |
343 | 342 | ||
344 | clock = tk->clock; | 343 | cycle_now = tk->read(clock); |
345 | cycle_now = clock->read(clock); | 344 | delta = clocksource_delta(cycle_now, tk->cycle_last, tk->mask); |
346 | delta = clocksource_delta(cycle_now, tk->cycle_last, clock->mask); | ||
347 | tk->cycle_last = cycle_now; | 345 | tk->cycle_last = cycle_now; |
348 | 346 | ||
349 | tk->xtime_nsec += delta * tk->mult; | 347 | tk->xtime_nsec += delta * tk->mult; |
@@ -1019,7 +1017,7 @@ static void timekeeping_resume(void) | |||
1019 | * The less preferred source will only be tried if there is no better | 1017 | * The less preferred source will only be tried if there is no better |
1020 | * usable source. The rtc part is handled separately in rtc core code. | 1018 | * usable source. The rtc part is handled separately in rtc core code. |
1021 | */ | 1019 | */ |
1022 | cycle_now = clock->read(clock); | 1020 | cycle_now = tk->read(clock); |
1023 | if ((clock->flags & CLOCK_SOURCE_SUSPEND_NONSTOP) && | 1021 | if ((clock->flags & CLOCK_SOURCE_SUSPEND_NONSTOP) && |
1024 | cycle_now > tk->cycle_last) { | 1022 | cycle_now > tk->cycle_last) { |
1025 | u64 num, max = ULLONG_MAX; | 1023 | u64 num, max = ULLONG_MAX; |
@@ -1028,7 +1026,7 @@ static void timekeeping_resume(void) | |||
1028 | s64 nsec = 0; | 1026 | s64 nsec = 0; |
1029 | 1027 | ||
1030 | cycle_delta = clocksource_delta(cycle_now, tk->cycle_last, | 1028 | cycle_delta = clocksource_delta(cycle_now, tk->cycle_last, |
1031 | clock->mask); | 1029 | tk->mask); |
1032 | 1030 | ||
1033 | /* | 1031 | /* |
1034 | * "cycle_delta * mutl" may cause 64 bits overflow, if the | 1032 | * "cycle_delta * mutl" may cause 64 bits overflow, if the |
@@ -1415,7 +1413,6 @@ static cycle_t logarithmic_accumulation(struct timekeeper *tk, cycle_t offset, | |||
1415 | */ | 1413 | */ |
1416 | void update_wall_time(void) | 1414 | void update_wall_time(void) |
1417 | { | 1415 | { |
1418 | struct clocksource *clock; | ||
1419 | struct timekeeper *real_tk = &tk_core.timekeeper; | 1416 | struct timekeeper *real_tk = &tk_core.timekeeper; |
1420 | struct timekeeper *tk = &shadow_timekeeper; | 1417 | struct timekeeper *tk = &shadow_timekeeper; |
1421 | cycle_t offset; | 1418 | cycle_t offset; |
@@ -1429,13 +1426,11 @@ void update_wall_time(void) | |||
1429 | if (unlikely(timekeeping_suspended)) | 1426 | if (unlikely(timekeeping_suspended)) |
1430 | goto out; | 1427 | goto out; |
1431 | 1428 | ||
1432 | clock = real_tk->clock; | ||
1433 | |||
1434 | #ifdef CONFIG_ARCH_USES_GETTIMEOFFSET | 1429 | #ifdef CONFIG_ARCH_USES_GETTIMEOFFSET |
1435 | offset = real_tk->cycle_interval; | 1430 | offset = real_tk->cycle_interval; |
1436 | #else | 1431 | #else |
1437 | offset = clocksource_delta(clock->read(clock), tk->cycle_last, | 1432 | offset = clocksource_delta(tk->read(tk->clock), tk->cycle_last, |
1438 | clock->mask); | 1433 | tk->mask); |
1439 | #endif | 1434 | #endif |
1440 | 1435 | ||
1441 | /* Check if there's really nothing to do */ | 1436 | /* Check if there's really nothing to do */ |