diff options
-rw-r--r-- | include/linux/clocksource.h | 11 | ||||
-rw-r--r-- | kernel/time/clocksource.c | 3 | ||||
-rw-r--r-- | kernel/time/jiffies.c | 1 |
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 | ||