aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin
diff options
context:
space:
mode:
authorYi Li <yi.li@analog.com>2009-09-15 02:50:51 -0400
committerMike Frysinger <vapier@gentoo.org>2009-12-15 00:13:41 -0500
commitceb33be95afcfbc4079af334835a345288f9f6ca (patch)
tree7244fbd018015de1139df8620f52e2d52751c68e /arch/blackfin
parentf7036d649c88ad14b482b2787ffb1063c8a719d7 (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.c43
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
49static 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
52static inline void set_cyc2ns_scale(unsigned long cpu_khz) 49static 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
57static inline unsigned long long cycles_2_ns(cycle_t cyc) 54static 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
62static cycle_t bfin_read_cycles(struct clocksource *cs) 59#if defined(CONFIG_CYCLES_CLOCKSOURCE)
60
61static unsigned long cycles_cyc2ns_scale;
62
63static 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
76unsigned long long sched_clock(void) 77static 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
81static int __init bfin_cs_cycles_init(void) 82static 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
100unsigned long gptimer0_cyc2ns_scale;
101
99void __init setup_gptimer0(void) 102void __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
128static 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
125static int __init bfin_cs_gptimer0_init(void) 133static 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 */
154notrace 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