diff options
Diffstat (limited to 'kernel/time/timekeeping.c')
-rw-r--r-- | kernel/time/timekeeping.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 83d3555a6998..5099c95b8aa2 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -75,6 +75,9 @@ static void clocksource_forward_now(void) | |||
75 | 75 | ||
76 | nsec = cyc2ns(clock, cycle_delta); | 76 | nsec = cyc2ns(clock, cycle_delta); |
77 | timespec_add_ns(&xtime, nsec); | 77 | timespec_add_ns(&xtime, nsec); |
78 | |||
79 | nsec = ((s64)cycle_delta * clock->mult_orig) >> clock->shift; | ||
80 | clock->raw_time.tv_nsec += nsec; | ||
78 | } | 81 | } |
79 | 82 | ||
80 | /** | 83 | /** |
@@ -183,6 +186,8 @@ static void change_clocksource(void) | |||
183 | 186 | ||
184 | clocksource_forward_now(); | 187 | clocksource_forward_now(); |
185 | 188 | ||
189 | new->raw_time = clock->raw_time; | ||
190 | |||
186 | clock = new; | 191 | clock = new; |
187 | clock->cycle_last = 0; | 192 | clock->cycle_last = 0; |
188 | clock->cycle_last = clocksource_read(new); | 193 | clock->cycle_last = clocksource_read(new); |
@@ -205,6 +210,39 @@ static inline void change_clocksource(void) { } | |||
205 | #endif | 210 | #endif |
206 | 211 | ||
207 | /** | 212 | /** |
213 | * getrawmonotonic - Returns the raw monotonic time in a timespec | ||
214 | * @ts: pointer to the timespec to be set | ||
215 | * | ||
216 | * Returns the raw monotonic time (completely un-modified by ntp) | ||
217 | */ | ||
218 | void getrawmonotonic(struct timespec *ts) | ||
219 | { | ||
220 | unsigned long seq; | ||
221 | s64 nsecs; | ||
222 | cycle_t cycle_now, cycle_delta; | ||
223 | |||
224 | do { | ||
225 | seq = read_seqbegin(&xtime_lock); | ||
226 | |||
227 | /* read clocksource: */ | ||
228 | cycle_now = clocksource_read(clock); | ||
229 | |||
230 | /* calculate the delta since the last update_wall_time: */ | ||
231 | cycle_delta = (cycle_now - clock->cycle_last) & clock->mask; | ||
232 | |||
233 | /* convert to nanoseconds: */ | ||
234 | nsecs = ((s64)cycle_delta * clock->mult_orig) >> clock->shift; | ||
235 | |||
236 | *ts = clock->raw_time; | ||
237 | |||
238 | } while (read_seqretry(&xtime_lock, seq)); | ||
239 | |||
240 | timespec_add_ns(ts, nsecs); | ||
241 | } | ||
242 | EXPORT_SYMBOL(getrawmonotonic); | ||
243 | |||
244 | |||
245 | /** | ||
208 | * timekeeping_valid_for_hres - Check if timekeeping is suitable for hres | 246 | * timekeeping_valid_for_hres - Check if timekeeping is suitable for hres |
209 | */ | 247 | */ |
210 | int timekeeping_valid_for_hres(void) | 248 | int timekeeping_valid_for_hres(void) |
@@ -466,6 +504,12 @@ void update_wall_time(void) | |||
466 | second_overflow(); | 504 | second_overflow(); |
467 | } | 505 | } |
468 | 506 | ||
507 | clock->raw_time.tv_nsec += clock->raw_interval; | ||
508 | if (clock->raw_time.tv_nsec >= NSEC_PER_SEC) { | ||
509 | clock->raw_time.tv_nsec -= NSEC_PER_SEC; | ||
510 | clock->raw_time.tv_sec++; | ||
511 | } | ||
512 | |||
469 | /* accumulate error between NTP and clock interval */ | 513 | /* accumulate error between NTP and clock interval */ |
470 | clock->error += tick_length; | 514 | clock->error += tick_length; |
471 | clock->error -= clock->xtime_interval << (NTP_SCALE_SHIFT - clock->shift); | 515 | clock->error -= clock->xtime_interval << (NTP_SCALE_SHIFT - clock->shift); |