aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2011-01-18 20:00:00 -0500
committerTony Lindgren <tony@atomide.com>2011-01-19 13:38:46 -0500
commit4912cf04b202a9d0bdc4082ecb9247943584450d (patch)
treec22e7673e441cb03aabd894e606e1e53df16f6d1 /arch
parent05b5ca9b100300c8b98429962071aa66c5d2460e (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.c48
-rw-r--r--arch/arm/plat-omap/counter_32k.c14
-rw-r--r--arch/arm/plat-omap/include/plat/common.h1
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
220static DEFINE_CLOCK_DATA(cd); 220static DEFINE_CLOCK_DATA(cd);
221 221
222static 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
229unsigned long long notrace sched_clock(void)
230{
231 return _omap_mpu_sched_clock();
232}
233#else
234static unsigned long long notrace omap_mpu_sched_clock(void)
235{
236 return _omap_mpu_sched_clock();
237}
238#endif
239
222static void notrace mpu_update_sched_clock(void) 240static 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)
284static unsigned long long (*preferred_sched_clock)(void);
285
286unsigned long long notrace sched_clock(void)
287{
288 if (!preferred_sched_clock)
289 return 0;
290
291 return preferred_sched_clock();
292}
293
294static 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
302static inline void preferred_sched_clock_init(bool use_32k_sched_clcok)
303{
304}
305#endif
306
265static inline int omap_32k_timer_usable(void) 307static 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 */
284static void __init omap_timer_init(void) 326static 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
290struct sys_timer omap_timer = { 336struct 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
123unsigned long long notrace sched_clock(void) 123static 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
130unsigned long long notrace sched_clock(void)
131{
132 return _omap_32k_sched_clock();
133}
134#else
135unsigned long long notrace omap_32k_sched_clock(void)
136{
137 return _omap_32k_sched_clock();
138}
139#endif
140
129static void notrace omap_update_sched_clock(void) 141static 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);
37extern struct sys_timer omap_timer; 37extern struct sys_timer omap_timer;
38extern bool omap_32k_timer_init(void); 38extern bool omap_32k_timer_init(void);
39extern int __init omap_init_clocksource_32k(void); 39extern int __init omap_init_clocksource_32k(void);
40extern unsigned long long notrace omap_32k_sched_clock(void);
40 41
41extern void omap_reserve(void); 42extern void omap_reserve(void);
42 43