diff options
author | Tony Lindgren <tony@atomide.com> | 2011-01-18 20:00:00 -0500 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2011-01-19 13:38:46 -0500 |
commit | 4912cf04b202a9d0bdc4082ecb9247943584450d (patch) | |
tree | c22e7673e441cb03aabd894e606e1e53df16f6d1 /arch | |
parent | 05b5ca9b100300c8b98429962071aa66c5d2460e (diff) |
omap1: Fix sched_clock implementation when both MPU timer and 32K timer are used
Earlier patches select HAVE_SCHED_CLOCK for omaps. To have working sched_clock
also for MPU timer, we need to implement it in a way where the right one gets
selected during the runtime.
Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-omap1/time.c | 48 | ||||
-rw-r--r-- | arch/arm/plat-omap/counter_32k.c | 14 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/common.h | 1 |
3 files changed, 61 insertions, 2 deletions
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c index b03f34d55d88..f83fc335c613 100644 --- a/arch/arm/mach-omap1/time.c +++ b/arch/arm/mach-omap1/time.c | |||
@@ -219,6 +219,24 @@ static struct clocksource clocksource_mpu = { | |||
219 | 219 | ||
220 | static DEFINE_CLOCK_DATA(cd); | 220 | static DEFINE_CLOCK_DATA(cd); |
221 | 221 | ||
222 | static inline unsigned long long notrace _omap_mpu_sched_clock(void) | ||
223 | { | ||
224 | u32 cyc = mpu_read(&clocksource_mpu); | ||
225 | return cyc_to_sched_clock(&cd, cyc, (u32)~0); | ||
226 | } | ||
227 | |||
228 | #ifndef CONFIG_OMAP_32K_TIMER | ||
229 | unsigned long long notrace sched_clock(void) | ||
230 | { | ||
231 | return _omap_mpu_sched_clock(); | ||
232 | } | ||
233 | #else | ||
234 | static unsigned long long notrace omap_mpu_sched_clock(void) | ||
235 | { | ||
236 | return _omap_mpu_sched_clock(); | ||
237 | } | ||
238 | #endif | ||
239 | |||
222 | static void notrace mpu_update_sched_clock(void) | 240 | static void notrace mpu_update_sched_clock(void) |
223 | { | 241 | { |
224 | u32 cyc = mpu_read(&clocksource_mpu); | 242 | u32 cyc = mpu_read(&clocksource_mpu); |
@@ -262,6 +280,30 @@ static inline void omap_mpu_timer_init(void) | |||
262 | } | 280 | } |
263 | #endif /* CONFIG_OMAP_MPU_TIMER */ | 281 | #endif /* CONFIG_OMAP_MPU_TIMER */ |
264 | 282 | ||
283 | #if defined(CONFIG_OMAP_MPU_TIMER) && defined(CONFIG_OMAP_32K_TIMER) | ||
284 | static unsigned long long (*preferred_sched_clock)(void); | ||
285 | |||
286 | unsigned long long notrace sched_clock(void) | ||
287 | { | ||
288 | if (!preferred_sched_clock) | ||
289 | return 0; | ||
290 | |||
291 | return preferred_sched_clock(); | ||
292 | } | ||
293 | |||
294 | static inline void preferred_sched_clock_init(bool use_32k_sched_clock) | ||
295 | { | ||
296 | if (use_32k_sched_clock) | ||
297 | preferred_sched_clock = omap_32k_sched_clock; | ||
298 | else | ||
299 | preferred_sched_clock = omap_mpu_sched_clock; | ||
300 | } | ||
301 | #else | ||
302 | static inline void preferred_sched_clock_init(bool use_32k_sched_clcok) | ||
303 | { | ||
304 | } | ||
305 | #endif | ||
306 | |||
265 | static inline int omap_32k_timer_usable(void) | 307 | static inline int omap_32k_timer_usable(void) |
266 | { | 308 | { |
267 | int res = false; | 309 | int res = false; |
@@ -283,8 +325,12 @@ static inline int omap_32k_timer_usable(void) | |||
283 | */ | 325 | */ |
284 | static void __init omap_timer_init(void) | 326 | static void __init omap_timer_init(void) |
285 | { | 327 | { |
286 | if (!omap_32k_timer_usable()) | 328 | if (omap_32k_timer_usable()) { |
329 | preferred_sched_clock_init(1); | ||
330 | } else { | ||
287 | omap_mpu_timer_init(); | 331 | omap_mpu_timer_init(); |
332 | preferred_sched_clock_init(0); | ||
333 | } | ||
288 | } | 334 | } |
289 | 335 | ||
290 | struct sys_timer omap_timer = { | 336 | struct sys_timer omap_timer = { |
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c index 5d7b08b5a13a..862dda95d61d 100644 --- a/arch/arm/plat-omap/counter_32k.c +++ b/arch/arm/plat-omap/counter_32k.c | |||
@@ -120,12 +120,24 @@ static DEFINE_CLOCK_DATA(cd); | |||
120 | #define SC_MULT 4000000000u | 120 | #define SC_MULT 4000000000u |
121 | #define SC_SHIFT 17 | 121 | #define SC_SHIFT 17 |
122 | 122 | ||
123 | unsigned long long notrace sched_clock(void) | 123 | static inline unsigned long long notrace _omap_32k_sched_clock(void) |
124 | { | 124 | { |
125 | u32 cyc = clocksource_32k.read(&clocksource_32k); | 125 | u32 cyc = clocksource_32k.read(&clocksource_32k); |
126 | return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT); | 126 | return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT); |
127 | } | 127 | } |
128 | 128 | ||
129 | #ifndef CONFIG_OMAP_MPU_TIMER | ||
130 | unsigned long long notrace sched_clock(void) | ||
131 | { | ||
132 | return _omap_32k_sched_clock(); | ||
133 | } | ||
134 | #else | ||
135 | unsigned long long notrace omap_32k_sched_clock(void) | ||
136 | { | ||
137 | return _omap_32k_sched_clock(); | ||
138 | } | ||
139 | #endif | ||
140 | |||
129 | static void notrace omap_update_sched_clock(void) | 141 | static void notrace omap_update_sched_clock(void) |
130 | { | 142 | { |
131 | u32 cyc = clocksource_32k.read(&clocksource_32k); | 143 | u32 cyc = clocksource_32k.read(&clocksource_32k); |
diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h index ef683e01701b..29b2afb4288f 100644 --- a/arch/arm/plat-omap/include/plat/common.h +++ b/arch/arm/plat-omap/include/plat/common.h | |||
@@ -37,6 +37,7 @@ extern void omap_map_common_io(void); | |||
37 | extern struct sys_timer omap_timer; | 37 | extern struct sys_timer omap_timer; |
38 | extern bool omap_32k_timer_init(void); | 38 | extern bool omap_32k_timer_init(void); |
39 | extern int __init omap_init_clocksource_32k(void); | 39 | extern int __init omap_init_clocksource_32k(void); |
40 | extern unsigned long long notrace omap_32k_sched_clock(void); | ||
40 | 41 | ||
41 | extern void omap_reserve(void); | 42 | extern void omap_reserve(void); |
42 | 43 | ||