diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-20 02:44:40 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-20 02:44:40 +0200 |
commit | 7e6628e4bcb3b3546c625ec63ca724f28ab14f0c (patch) | |
tree | 111a94cefa9d800ec5c5e59520f4b5d1880965d0 /kernel/time/clocksource.c | |
parent | Merge branch 'timers-clocksource-for-linus' of git://git.kernel.org/pub/scm/l... (diff) | |
parent | x86: hpet: Cleanup the clockevents init and register code (diff) | |
download | linux-7e6628e4bcb3b3546c625ec63ca724f28ab14f0c.tar.xz linux-7e6628e4bcb3b3546c625ec63ca724f28ab14f0c.zip |
Merge branch 'timers-clockevents-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'timers-clockevents-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
x86: hpet: Cleanup the clockevents init and register code
x86: Convert PIT to clockevents_config_and_register()
clockevents: Provide interface to reconfigure an active clock event device
clockevents: Provide combined configure and register function
clockevents: Restructure clock_event_device members
clocksource: Get rid of the hardcoded 5 seconds sleep time limit
clocksource: Restructure clocksource struct members
Diffstat (limited to 'kernel/time/clocksource.c')
-rw-r--r-- | kernel/time/clocksource.c | 38 |
1 files changed, 19 insertions, 19 deletions
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 0e17c10f8a9d..d9d5f8c885f6 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c @@ -626,19 +626,6 @@ static void clocksource_enqueue(struct clocksource *cs) list_add(&cs->list, entry); } - -/* - * Maximum time we expect to go between ticks. This includes idle - * tickless time. It provides the trade off between selecting a - * mult/shift pair that is very precise but can only handle a short - * period of time, vs. a mult/shift pair that can handle long periods - * of time but isn't as precise. - * - * This is a subsystem constant, and actual hardware limitations - * may override it (ie: clocksources that wrap every 3 seconds). - */ -#define MAX_UPDATE_LENGTH 5 /* Seconds */ - /** * __clocksource_updatefreq_scale - Used update clocksource with new freq * @t: clocksource to be registered @@ -652,15 +639,28 @@ static void clocksource_enqueue(struct clocksource *cs) */ void __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq) { + unsigned long sec; + /* - * Ideally we want to use some of the limits used in - * clocksource_max_deferment, to provide a more informed - * MAX_UPDATE_LENGTH. But for now this just gets the - * register interface working properly. + * Calc the maximum number of seconds which we can run before + * wrapping around. For clocksources which have a mask > 32bit + * we need to limit the max sleep time to have a good + * conversion precision. 10 minutes is still a reasonable + * amount. That results in a shift value of 24 for a + * clocksource with mask >= 40bit and f >= 4GHz. That maps to + * ~ 0.06ppm granularity for NTP. We apply the same 12.5% + * margin as we do in clocksource_max_deferment() */ + sec = (cs->mask - (cs->mask >> 5)); + do_div(sec, freq); + do_div(sec, scale); + if (!sec) + sec = 1; + else if (sec > 600 && cs->mask > UINT_MAX) + sec = 600; + clocks_calc_mult_shift(&cs->mult, &cs->shift, freq, - NSEC_PER_SEC/scale, - MAX_UPDATE_LENGTH*scale); + NSEC_PER_SEC / scale, sec * scale); cs->max_idle_ns = clocksource_max_deferment(cs); } EXPORT_SYMBOL_GPL(__clocksource_updatefreq_scale); |