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: John 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: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
0b046b217a
commit
f8935983f1
5 changed files with 46 additions and 51 deletions
|
@ -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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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);
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
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);
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue