clocksource: Add module refcount
Add a module refcount, so the current clocksource cannot be removed unconditionally. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: John Stultz <john.stultz@linaro.org> Cc: Magnus Damm <magnus.damm@gmail.com> Link: http://lkml.kernel.org/r/20130425143435.762417789@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
ba919d1caa
commit
09ac369c82
|
@ -21,6 +21,7 @@
|
||||||
/* clocksource cycle base type */
|
/* clocksource cycle base type */
|
||||||
typedef u64 cycle_t;
|
typedef u64 cycle_t;
|
||||||
struct clocksource;
|
struct clocksource;
|
||||||
|
struct module;
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_CLOCKSOURCE_DATA
|
#ifdef CONFIG_ARCH_CLOCKSOURCE_DATA
|
||||||
#include <asm/clocksource.h>
|
#include <asm/clocksource.h>
|
||||||
|
@ -162,6 +163,7 @@ extern u64 timecounter_cyc2time(struct timecounter *tc,
|
||||||
* @suspend: suspend function for the clocksource, if necessary
|
* @suspend: suspend function for the clocksource, if necessary
|
||||||
* @resume: resume function for the clocksource, if necessary
|
* @resume: resume function for the clocksource, if necessary
|
||||||
* @cycle_last: most recent cycle counter value seen by ::read()
|
* @cycle_last: most recent cycle counter value seen by ::read()
|
||||||
|
* @owner: module reference, must be set by clocksource in modules
|
||||||
*/
|
*/
|
||||||
struct clocksource {
|
struct clocksource {
|
||||||
/*
|
/*
|
||||||
|
@ -195,6 +197,7 @@ struct clocksource {
|
||||||
cycle_t cs_last;
|
cycle_t cs_last;
|
||||||
cycle_t wd_last;
|
cycle_t wd_last;
|
||||||
#endif
|
#endif
|
||||||
|
struct module *owner;
|
||||||
} ____cacheline_aligned;
|
} ____cacheline_aligned;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -627,11 +627,20 @@ static int change_clocksource(void *data)
|
||||||
write_seqcount_begin(&timekeeper_seq);
|
write_seqcount_begin(&timekeeper_seq);
|
||||||
|
|
||||||
timekeeping_forward_now(tk);
|
timekeeping_forward_now(tk);
|
||||||
|
/*
|
||||||
|
* If the cs is in module, get a module reference. Succeeds
|
||||||
|
* for built-in code (owner == NULL) as well.
|
||||||
|
*/
|
||||||
|
if (try_module_get(new->owner)) {
|
||||||
if (!new->enable || new->enable(new) == 0) {
|
if (!new->enable || new->enable(new) == 0) {
|
||||||
old = tk->clock;
|
old = tk->clock;
|
||||||
tk_setup_internals(tk, new);
|
tk_setup_internals(tk, new);
|
||||||
if (old->disable)
|
if (old->disable)
|
||||||
old->disable(old);
|
old->disable(old);
|
||||||
|
module_put(old->owner);
|
||||||
|
} else {
|
||||||
|
module_put(new->owner);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
timekeeping_update(tk, true, true);
|
timekeeping_update(tk, true, true);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue