diff options
author | Yi Li <yi.li@analog.com> | 2009-09-15 06:50:51 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2009-12-15 00:13:41 -0500 |
commit | ceb33be95afcfbc4079af334835a345288f9f6ca (patch) | |
tree | 7244fbd018015de1139df8620f52e2d52751c68e /arch/blackfin/kernel | |
parent | f7036d649c88ad14b482b2787ffb1063c8a719d7 (diff) | |
download | talos-op-linux-ceb33be95afcfbc4079af334835a345288f9f6ca.tar.gz talos-op-linux-ceb33be95afcfbc4079af334835a345288f9f6ca.zip |
Blackfin: unify sched_clock() handling between clock sources
Currently sched_clock() is only defined when using CYCLES as a clock
source. Declare sched_clock() in common code and mark it with notrace to
prevent invoking sched_clock() recursively (because ftrace uses
sched_clock() to record time).
Signed-off-by: Yi Li <yi.li@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r-- | arch/blackfin/kernel/time-ts.c | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c index a54e569e3b62..2855f0ff865c 100644 --- a/arch/blackfin/kernel/time-ts.c +++ b/arch/blackfin/kernel/time-ts.c @@ -22,8 +22,6 @@ #include <asm/time.h> #include <asm/gptimers.h> -#if defined(CONFIG_CYCLES_CLOCKSOURCE) - /* Accelerators for sched_clock() * convert from cycles(64bits) => nanoseconds (64bits) * basic equation: @@ -46,20 +44,23 @@ * -johnstul@us.ibm.com "math is hard, lets go shopping!" */ -static unsigned long cyc2ns_scale; #define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ -static inline void set_cyc2ns_scale(unsigned long cpu_khz) +static inline unsigned long cyc2ns_scale(unsigned long cpu_khz) { - cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR) / cpu_khz; + return (1000000 << CYC2NS_SCALE_FACTOR) / cpu_khz; } -static inline unsigned long long cycles_2_ns(cycle_t cyc) +static inline unsigned long long cycles_2_ns(cycle_t cyc, unsigned long cyc2ns_scale) { return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; } -static cycle_t bfin_read_cycles(struct clocksource *cs) +#if defined(CONFIG_CYCLES_CLOCKSOURCE) + +static unsigned long cycles_cyc2ns_scale; + +static notrace cycle_t bfin_read_cycles(struct clocksource *cs) { return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod); } @@ -73,14 +74,14 @@ static struct clocksource bfin_cs_cycles = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -unsigned long long sched_clock(void) +static inline unsigned long long bfin_cs_cycles_sched_clock(void) { - return cycles_2_ns(bfin_read_cycles(&bfin_cs_cycles)); + return cycles_2_ns(bfin_read_cycles(&bfin_cs_cycles), cycles_cyc2ns_scale); } static int __init bfin_cs_cycles_init(void) { - set_cyc2ns_scale(get_cclk() / 1000); + cycles_cyc2ns_scale = cyc2ns_scale(get_cclk() / 1000); bfin_cs_cycles.mult = \ clocksource_hz2mult(get_cclk(), bfin_cs_cycles.shift); @@ -96,6 +97,8 @@ static int __init bfin_cs_cycles_init(void) #ifdef CONFIG_GPTMR0_CLOCKSOURCE +unsigned long gptimer0_cyc2ns_scale; + void __init setup_gptimer0(void) { disable_gptimers(TIMER0bit); @@ -122,8 +125,15 @@ static struct clocksource bfin_cs_gptimer0 = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; +static inline unsigned long long bfin_cs_gptimer0_sched_clock(void) +{ + return cycles_2_ns(bfin_read_TIMER0_COUNTER(), gptimer0_cyc2ns_scale); +} + static int __init bfin_cs_gptimer0_init(void) { + gptimer0_cyc2ns_scale = cyc2ns_scale(get_sclk() / 1000); + setup_gptimer0(); bfin_cs_gptimer0.mult = \ @@ -138,6 +148,19 @@ static int __init bfin_cs_gptimer0_init(void) # define bfin_cs_gptimer0_init() #endif + +#if defined(CONFIG_GPTMR0_CLOCKSOURCE) || defined(CONFIG_CYCLES_CLOCKSOURCE) +/* prefer to use cycles since it has higher rating */ +notrace unsigned long long sched_clock(void) +{ +#if defined(CONFIG_CYCLES_CLOCKSOURCE) + return bfin_cs_cycles_sched_clock(); +#else + return bfin_cs_gptimer0_sched_clock(); +#endif +} +#endif + #ifdef CONFIG_CORE_TIMER_IRQ_L1 __attribute__((l1_text)) #endif |