aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/clocksource.h11
-rw-r--r--kernel/time/clocksource.c3
-rw-r--r--kernel/time/jiffies.c1
3 files changed, 11 insertions, 4 deletions
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index 55e434feec99..f0a7fb984413 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -45,7 +45,8 @@ struct clocksource;
45 * @read: returns a cycle value 45 * @read: returns a cycle value
46 * @mask: bitmask for two's complement 46 * @mask: bitmask for two's complement
47 * subtraction of non 64 bit counters 47 * subtraction of non 64 bit counters
48 * @mult: cycle to nanosecond multiplier 48 * @mult: cycle to nanosecond multiplier (adjusted by NTP)
49 * @mult_orig: cycle to nanosecond multiplier (unadjusted by NTP)
49 * @shift: cycle to nanosecond divisor (power of two) 50 * @shift: cycle to nanosecond divisor (power of two)
50 * @flags: flags describing special properties 51 * @flags: flags describing special properties
51 * @vread: vsyscall based read 52 * @vread: vsyscall based read
@@ -63,6 +64,7 @@ struct clocksource {
63 cycle_t (*read)(void); 64 cycle_t (*read)(void);
64 cycle_t mask; 65 cycle_t mask;
65 u32 mult; 66 u32 mult;
67 u32 mult_orig;
66 u32 shift; 68 u32 shift;
67 unsigned long flags; 69 unsigned long flags;
68 cycle_t (*vread)(void); 70 cycle_t (*vread)(void);
@@ -201,16 +203,17 @@ static inline void clocksource_calculate_interval(struct clocksource *c,
201{ 203{
202 u64 tmp; 204 u64 tmp;
203 205
204 /* XXX - All of this could use a whole lot of optimization */ 206 /* Do the ns -> cycle conversion first, using original mult */
205 tmp = length_nsec; 207 tmp = length_nsec;
206 tmp <<= c->shift; 208 tmp <<= c->shift;
207 tmp += c->mult/2; 209 tmp += c->mult_orig/2;
208 do_div(tmp, c->mult); 210 do_div(tmp, c->mult_orig);
209 211
210 c->cycle_interval = (cycle_t)tmp; 212 c->cycle_interval = (cycle_t)tmp;
211 if (c->cycle_interval == 0) 213 if (c->cycle_interval == 0)
212 c->cycle_interval = 1; 214 c->cycle_interval = 1;
213 215
216 /* Go back from cycles -> shifted ns, this time use ntp adjused mult */
214 c->xtime_interval = (u64)c->cycle_interval * c->mult; 217 c->xtime_interval = (u64)c->cycle_interval * c->mult;
215} 218}
216 219
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index 093d4acf993b..9ed2eec97526 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -325,6 +325,9 @@ int clocksource_register(struct clocksource *c)
325 unsigned long flags; 325 unsigned long flags;
326 int ret; 326 int ret;
327 327
328 /* save mult_orig on registration */
329 c->mult_orig = c->mult;
330
328 spin_lock_irqsave(&clocksource_lock, flags); 331 spin_lock_irqsave(&clocksource_lock, flags);
329 ret = clocksource_enqueue(c); 332 ret = clocksource_enqueue(c);
330 if (!ret) 333 if (!ret)
diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c
index 4c256fdb8875..1ca99557e929 100644
--- a/kernel/time/jiffies.c
+++ b/kernel/time/jiffies.c
@@ -61,6 +61,7 @@ struct clocksource clocksource_jiffies = {
61 .read = jiffies_read, 61 .read = jiffies_read,
62 .mask = 0xffffffff, /*32bits*/ 62 .mask = 0xffffffff, /*32bits*/
63 .mult = NSEC_PER_JIFFY << JIFFIES_SHIFT, /* details above */ 63 .mult = NSEC_PER_JIFFY << JIFFIES_SHIFT, /* details above */
64 .mult_orig = NSEC_PER_JIFFY << JIFFIES_SHIFT,
64 .shift = JIFFIES_SHIFT, 65 .shift = JIFFIES_SHIFT,
65}; 66};
66 67