Commit f8935983 authored by John Stultz's avatar John Stultz Committed by Ingo Molnar

clocksource: Mostly kill clocksource_register()

A long running project has been to clean up remaining uses
of clocksource_register(), replacing it with the simpler
clocksource_register_khz/hz() functions.

However, there are a few cases where we need to self-define
our mult/shift values, so switch the function to a more
obviously internal __clocksource_register() name, and
consolidate much of the internal logic so we don't have
duplication.
Signed-off-by: default avatarJohn Stultz <john.stultz@linaro.org>
Cc: Dave Jones <davej@codemonkey.org.uk>
Cc: David S. Miller <davem@davemloft.net>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Stephen Boyd <sboyd@codeaurora.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1426133800-29329-10-git-send-email-john.stultz@linaro.org
[ Minor cleanups. ]
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 0b046b21
...@@ -283,7 +283,7 @@ void __init time_init(void) ...@@ -283,7 +283,7 @@ void __init time_init(void)
if (register_external_irq(EXT_IRQ_TIMING_ALERT, timing_alert_interrupt)) if (register_external_irq(EXT_IRQ_TIMING_ALERT, timing_alert_interrupt))
panic("Couldn't request external interrupt 0x1406"); panic("Couldn't request external interrupt 0x1406");
if (clocksource_register(&clocksource_tod) != 0) if (__clocksource_register(&clocksource_tod) != 0)
panic("Could not register TOD clock source"); panic("Could not register TOD clock source");
/* Enable TOD clock interrupts on the boot cpu. */ /* Enable TOD clock interrupts on the boot cpu. */
......
...@@ -191,7 +191,7 @@ static __init int setup_timer_cs(void) ...@@ -191,7 +191,7 @@ static __init int setup_timer_cs(void)
timer_cs.mult = clocksource_hz2mult(sparc_config.clock_rate, timer_cs.mult = clocksource_hz2mult(sparc_config.clock_rate,
timer_cs.shift); timer_cs.shift);
return clocksource_register(&timer_cs); return __clocksource_register(&timer_cs);
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
......
...@@ -179,7 +179,6 @@ static inline s64 clocksource_cyc2ns(cycle_t cycles, u32 mult, u32 shift) ...@@ -179,7 +179,6 @@ static inline s64 clocksource_cyc2ns(cycle_t cycles, u32 mult, u32 shift)
} }
extern int clocksource_register(struct clocksource*);
extern int clocksource_unregister(struct clocksource*); extern int clocksource_unregister(struct clocksource*);
extern void clocksource_touch_watchdog(void); extern void clocksource_touch_watchdog(void);
extern struct clocksource* clocksource_get_next(void); extern struct clocksource* clocksource_get_next(void);
...@@ -203,6 +202,15 @@ __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq); ...@@ -203,6 +202,15 @@ __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq);
extern void extern void
__clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq); __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq);
/*
* Don't call this unless you are a default clocksource
* (AKA: jiffies) and absolutely have to.
*/
static inline int __clocksource_register(struct clocksource *cs)
{
return __clocksource_register_scale(cs, 1, 0);
}
static inline int clocksource_register_hz(struct clocksource *cs, u32 hz) static inline int clocksource_register_hz(struct clocksource *cs, u32 hz)
{ {
return __clocksource_register_scale(cs, 1, hz); return __clocksource_register_scale(cs, 1, hz);
......
...@@ -656,38 +656,52 @@ static void clocksource_enqueue(struct clocksource *cs) ...@@ -656,38 +656,52 @@ static void clocksource_enqueue(struct clocksource *cs)
void __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq) void __clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq)
{ {
u64 sec; u64 sec;
/* /*
* Calc the maximum number of seconds which we can run before * Default clocksources are *special* and self-define their mult/shift.
* wrapping around. For clocksources which have a mask > 32bit * But, you're not special, so you should specify a freq value.
* 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.
*/ */
sec = cs->mask; if (freq) {
do_div(sec, freq); /*
do_div(sec, scale); * Calc the maximum number of seconds which we can run before
if (!sec) * wrapping around. For clocksources which have a mask > 32-bit
sec = 1; * we need to limit the max sleep time to have a good
else if (sec > 600 && cs->mask > UINT_MAX) * conversion precision. 10 minutes is still a reasonable
sec = 600; * amount. That results in a shift value of 24 for a
* clocksource with mask >= 40-bit and f >= 4GHz. That maps to
clocks_calc_mult_shift(&cs->mult, &cs->shift, freq, * ~ 0.06ppm granularity for NTP.
NSEC_PER_SEC / scale, sec * scale); */
sec = cs->mask;
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, sec * scale);
}
/* /*
* Ensure clocksources that have large 'mult' values don't overflow * Ensure clocksources that have large 'mult' values don't overflow
* when adjusted. * when adjusted.
*/ */
cs->maxadj = clocksource_max_adjustment(cs); cs->maxadj = clocksource_max_adjustment(cs);
while ((cs->mult + cs->maxadj < cs->mult) while (freq && ((cs->mult + cs->maxadj < cs->mult)
|| (cs->mult - cs->maxadj > cs->mult)) { || (cs->mult - cs->maxadj > cs->mult))) {
cs->mult >>= 1; cs->mult >>= 1;
cs->shift--; cs->shift--;
cs->maxadj = clocksource_max_adjustment(cs); cs->maxadj = clocksource_max_adjustment(cs);
} }
/*
* Only warn for *special* clocksources that self-define
* their mult/shift values and don't specify a freq.
*/
WARN_ONCE(cs->mult + cs->maxadj < cs->mult,
"timekeeping: Clocksource %s might overflow on 11%% adjustment\n",
cs->name);
clocksource_update_max_deferment(cs); clocksource_update_max_deferment(cs);
} }
EXPORT_SYMBOL_GPL(__clocksource_updatefreq_scale); EXPORT_SYMBOL_GPL(__clocksource_updatefreq_scale);
...@@ -719,33 +733,6 @@ int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq) ...@@ -719,33 +733,6 @@ int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq)
} }
EXPORT_SYMBOL_GPL(__clocksource_register_scale); EXPORT_SYMBOL_GPL(__clocksource_register_scale);
/**
* clocksource_register - Used to install new clocksources
* @cs: clocksource to be registered
*
* Returns -EBUSY if registration fails, zero otherwise.
*/
int clocksource_register(struct clocksource *cs)
{
/* calculate max adjustment for given mult/shift */
cs->maxadj = clocksource_max_adjustment(cs);
WARN_ONCE(cs->mult + cs->maxadj < cs->mult,
"Clocksource %s might overflow on 11%% adjustment\n",
cs->name);
/* Update max idle time permitted for this clocksource */
clocksource_update_max_deferment(cs);
mutex_lock(&clocksource_mutex);
clocksource_enqueue(cs);
clocksource_enqueue_watchdog(cs);
clocksource_select();
mutex_unlock(&clocksource_mutex);
return 0;
}
EXPORT_SYMBOL(clocksource_register);
static void __clocksource_change_rating(struct clocksource *cs, int rating) static void __clocksource_change_rating(struct clocksource *cs, int rating)
{ {
list_del(&cs->list); list_del(&cs->list);
......
...@@ -95,7 +95,7 @@ EXPORT_SYMBOL(jiffies); ...@@ -95,7 +95,7 @@ EXPORT_SYMBOL(jiffies);
static int __init init_jiffies_clocksource(void) static int __init init_jiffies_clocksource(void)
{ {
return clocksource_register(&clocksource_jiffies); return __clocksource_register(&clocksource_jiffies);
} }
core_initcall(init_jiffies_clocksource); core_initcall(init_jiffies_clocksource);
...@@ -131,6 +131,6 @@ int register_refined_jiffies(long cycles_per_second) ...@@ -131,6 +131,6 @@ int register_refined_jiffies(long cycles_per_second)
refined_jiffies.mult = ((u32)nsec_per_tick) << JIFFIES_SHIFT; refined_jiffies.mult = ((u32)nsec_per_tick) << JIFFIES_SHIFT;
clocksource_register(&refined_jiffies); __clocksource_register(&refined_jiffies);
return 0; return 0;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment