aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time/timekeeping.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/time/timekeeping.c')
-rw-r--r--kernel/time/timekeeping.c44
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 */
218void 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}
242EXPORT_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 */
210int timekeeping_valid_for_hres(void) 248int 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);