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/arm/mach-omap1/time.c | |
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/arm/mach-omap1/time.c')
-rw-r--r-- | arch/arm/mach-omap1/time.c | 48 |
1 files changed, 47 insertions, 1 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 = { |