diff options
author | Yi Li <yi.li@analog.com> | 2009-09-15 02:50:51 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2009-12-15 00:13:41 -0500 |
commit | ceb33be95afcfbc4079af334835a345288f9f6ca (patch) | |
tree | 7244fbd018015de1139df8620f52e2d52751c68e /arch/blackfin | |
parent | f7036d649c88ad14b482b2787ffb1063c8a719d7 (diff) |
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')
-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 @@ | |||
22 | #include <asm/time.h> | 22 | #include <asm/time.h> |
23 | #include <asm/gptimers.h> | 23 | #include <asm/gptimers.h> |
24 | 24 | ||
25 | #if defined(CONFIG_CYCLES_CLOCKSOURCE) | ||
26 | |||
27 | /* Accelerators for sched_clock() | 25 | /* Accelerators for sched_clock() |
28 | * convert from cycles(64bits) => nanoseconds (64bits) | 26 | * convert from cycles(64bits) => nanoseconds (64bits) |
29 | * basic equation: | 27 | * basic equation: |
@@ -46,20 +44,23 @@ | |||
46 | * -johnstul@us.ibm.com "math is hard, lets go shopping!" | 44 | * -johnstul@us.ibm.com "math is hard, lets go shopping!" |
47 | */ | 45 | */ |
48 | 46 | ||
49 | static unsigned long cyc2ns_scale; | ||
50 | #define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ | 47 | #define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ |
51 | 48 | ||
52 | static inline void set_cyc2ns_scale(unsigned long cpu_khz) | 49 | static inline unsigned long cyc2ns_scale(unsigned long cpu_khz) |
53 | { | 50 | { |
54 | cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR) / cpu_khz; | 51 | return (1000000 << CYC2NS_SCALE_FACTOR) / cpu_khz; |
55 | } | 52 | } |
56 | 53 | ||
57 | static inline unsigned long long cycles_2_ns(cycle_t cyc) | 54 | static inline unsigned long long cycles_2_ns(cycle_t cyc, unsigned long cyc2ns_scale) |
58 | { | 55 | { |
59 | return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; | 56 | return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; |
60 | } | 57 | } |
61 | 58 | ||
62 | static cycle_t bfin_read_cycles(struct clocksource *cs) | 59 | #if defined(CONFIG_CYCLES_CLOCKSOURCE) |
60 | |||
61 | static unsigned long cycles_cyc2ns_scale; | ||
62 | |||
63 | static notrace cycle_t bfin_read_cycles(struct clocksource *cs) | ||
63 | { | 64 | { |
64 | return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod); | 65 | return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod); |
65 | } | 66 | } |
@@ -73,14 +74,14 @@ static struct clocksource bfin_cs_cycles = { | |||
73 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 74 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
74 | }; | 75 | }; |
75 | 76 | ||
76 | unsigned long long sched_clock(void) | 77 | static inline unsigned long long bfin_cs_cycles_sched_clock(void) |
77 | { | 78 | { |
78 | return cycles_2_ns(bfin_read_cycles(&bfin_cs_cycles)); | 79 | return cycles_2_ns(bfin_read_cycles(&bfin_cs_cycles), cycles_cyc2ns_scale); |
79 | } | 80 | } |
80 | 81 | ||
81 | static int __init bfin_cs_cycles_init(void) | 82 | static int __init bfin_cs_cycles_init(void) |
82 | { | 83 | { |
83 | set_cyc2ns_scale(get_cclk() / 1000); | 84 | cycles_cyc2ns_scale = cyc2ns_scale(get_cclk() / 1000); |
84 | 85 | ||
85 | bfin_cs_cycles.mult = \ | 86 | bfin_cs_cycles.mult = \ |
86 | clocksource_hz2mult(get_cclk(), bfin_cs_cycles.shift); | 87 | clocksource_hz2mult(get_cclk(), bfin_cs_cycles.shift); |
@@ -96,6 +97,8 @@ static int __init bfin_cs_cycles_init(void) | |||
96 | 97 | ||
97 | #ifdef CONFIG_GPTMR0_CLOCKSOURCE | 98 | #ifdef CONFIG_GPTMR0_CLOCKSOURCE |
98 | 99 | ||
100 | unsigned long gptimer0_cyc2ns_scale; | ||
101 | |||
99 | void __init setup_gptimer0(void) | 102 | void __init setup_gptimer0(void) |
100 | { | 103 | { |
101 | disable_gptimers(TIMER0bit); | 104 | disable_gptimers(TIMER0bit); |
@@ -122,8 +125,15 @@ static struct clocksource bfin_cs_gptimer0 = { | |||
122 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 125 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
123 | }; | 126 | }; |
124 | 127 | ||
128 | static inline unsigned long long bfin_cs_gptimer0_sched_clock(void) | ||
129 | { | ||
130 | return cycles_2_ns(bfin_read_TIMER0_COUNTER(), gptimer0_cyc2ns_scale); | ||
131 | } | ||
132 | |||
125 | static int __init bfin_cs_gptimer0_init(void) | 133 | static int __init bfin_cs_gptimer0_init(void) |
126 | { | 134 | { |
135 | gptimer0_cyc2ns_scale = cyc2ns_scale(get_sclk() / 1000); | ||
136 | |||
127 | setup_gptimer0(); | 137 | setup_gptimer0(); |
128 | 138 | ||
129 | bfin_cs_gptimer0.mult = \ | 139 | bfin_cs_gptimer0.mult = \ |
@@ -138,6 +148,19 @@ static int __init bfin_cs_gptimer0_init(void) | |||
138 | # define bfin_cs_gptimer0_init() | 148 | # define bfin_cs_gptimer0_init() |
139 | #endif | 149 | #endif |
140 | 150 | ||
151 | |||
152 | #if defined(CONFIG_GPTMR0_CLOCKSOURCE) || defined(CONFIG_CYCLES_CLOCKSOURCE) | ||
153 | /* prefer to use cycles since it has higher rating */ | ||
154 | notrace unsigned long long sched_clock(void) | ||
155 | { | ||
156 | #if defined(CONFIG_CYCLES_CLOCKSOURCE) | ||
157 | return bfin_cs_cycles_sched_clock(); | ||
158 | #else | ||
159 | return bfin_cs_gptimer0_sched_clock(); | ||
160 | #endif | ||
161 | } | ||
162 | #endif | ||
163 | |||
141 | #ifdef CONFIG_CORE_TIMER_IRQ_L1 | 164 | #ifdef CONFIG_CORE_TIMER_IRQ_L1 |
142 | __attribute__((l1_text)) | 165 | __attribute__((l1_text)) |
143 | #endif | 166 | #endif |