]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - kernel/time/timekeeping.c
clocksource: introduce CLOCK_MONOTONIC_RAW
[linux-2.6-omap-h63xx.git] / kernel / time / timekeeping.c
index 83d3555a69989e2e5219886ab82dfd33e7e1dda8..5099c95b8aa2677def4d992c6082b46f521d055b 100644 (file)
@@ -75,6 +75,9 @@ static void clocksource_forward_now(void)
 
        nsec = cyc2ns(clock, cycle_delta);
        timespec_add_ns(&xtime, nsec);
+
+       nsec = ((s64)cycle_delta * clock->mult_orig) >> clock->shift;
+       clock->raw_time.tv_nsec += nsec;
 }
 
 /**
@@ -183,6 +186,8 @@ static void change_clocksource(void)
 
        clocksource_forward_now();
 
+       new->raw_time = clock->raw_time;
+
        clock = new;
        clock->cycle_last = 0;
        clock->cycle_last = clocksource_read(new);
@@ -204,6 +209,39 @@ static inline void clocksource_forward_now(void) { }
 static inline void change_clocksource(void) { }
 #endif
 
+/**
+ * getrawmonotonic - Returns the raw monotonic time in a timespec
+ * @ts:                pointer to the timespec to be set
+ *
+ * Returns the raw monotonic time (completely un-modified by ntp)
+ */
+void getrawmonotonic(struct timespec *ts)
+{
+       unsigned long seq;
+       s64 nsecs;
+       cycle_t cycle_now, cycle_delta;
+
+       do {
+               seq = read_seqbegin(&xtime_lock);
+
+               /* read clocksource: */
+               cycle_now = clocksource_read(clock);
+
+               /* calculate the delta since the last update_wall_time: */
+               cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
+
+               /* convert to nanoseconds: */
+               nsecs = ((s64)cycle_delta * clock->mult_orig) >> clock->shift;
+
+               *ts = clock->raw_time;
+
+       } while (read_seqretry(&xtime_lock, seq));
+
+       timespec_add_ns(ts, nsecs);
+}
+EXPORT_SYMBOL(getrawmonotonic);
+
+
 /**
  * timekeeping_valid_for_hres - Check if timekeeping is suitable for hres
  */
@@ -466,6 +504,12 @@ void update_wall_time(void)
                        second_overflow();
                }
 
+               clock->raw_time.tv_nsec += clock->raw_interval;
+               if (clock->raw_time.tv_nsec >= NSEC_PER_SEC) {
+                       clock->raw_time.tv_nsec -= NSEC_PER_SEC;
+                       clock->raw_time.tv_sec++;
+               }
+
                /* accumulate error between NTP and clock interval */
                clock->error += tick_length;
                clock->error -= clock->xtime_interval << (NTP_SCALE_SHIFT - clock->shift);