aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap1
diff options
context:
space:
mode:
authorMarc Zyngier <Marc.Zyngier@arm.com>2011-12-15 06:19:23 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-12-18 18:00:26 -0500
commit2f0778afac79bd8d226225556858a636931eeabc (patch)
treee00cea674f3d6cc8c5584aa5b75239f11f6d229d /arch/arm/mach-omap1
parent3bdc3484e8f2b1b219ad0397d81ce4601fbaf76d (diff)
ARM: 7205/2: sched_clock: allow sched_clock to be selected at runtime
sched_clock() is yet another blocker on the road to the single image. This patch implements an idea by Russell King: http://www.spinics.net/lists/linux-omap/msg49561.html Instead of asking the platform to implement both sched_clock() itself and the rollover callback, simply register a read() function, and let the ARM code care about sched_clock() itself, the conversion to ns and the rollover. sched_clock() uses this read() function as an indirection to the platform code. If the platform doesn't provide a read(), the code falls back to the jiffy counter (just like the default sched_clock). This allow some simplifications and possibly some footprint gain when multiple platforms are compiled in. Among the drawbacks, the removal of the *_fixed_sched_clock optimization which could negatively impact some platforms (sa1100, tegra, versatile and omap). Tested on 11MPCore, OMAP4 and Tegra. Cc: Imre Kaloz <kaloz@openwrt.org> Cc: Eric Miao <eric.y.miao@gmail.com> Cc: Colin Cross <ccross@android.com> Cc: Erik Gilling <konkers@android.com> Cc: Olof Johansson <olof@lixom.net> Cc: Sascha Hauer <kernel@pengutronix.de> Cc: Alessandro Rubini <rubini@unipv.it> Cc: STEricsson <STEricsson_nomadik_linux@list.st.com> Cc: Lennert Buytenhek <kernel@wantstofly.org> Cc: Ben Dooks <ben-linux@fluff.org> Tested-by: Jamie Iles <jamie@jamieiles.com> Tested-by: Tony Lindgren <tony@atomide.com> Tested-by: Kyungmin Park <kyungmin.park@samsung.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Nicolas Pitre <nico@linaro.org> Acked-by: Krzysztof Halasa <khc@pm.waw.pl> Acked-by: Kukjin Kim <kgene.kim@samsung.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-omap1')
-rw-r--r--arch/arm/mach-omap1/time.c58
1 files changed, 4 insertions, 54 deletions
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
index 485a21d31004..b8faffa44f9e 100644
--- a/arch/arm/mach-omap1/time.c
+++ b/arch/arm/mach-omap1/time.c
@@ -37,7 +37,6 @@
37#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/delay.h> 38#include <linux/delay.h>
39#include <linux/interrupt.h> 39#include <linux/interrupt.h>
40#include <linux/sched.h>
41#include <linux/spinlock.h> 40#include <linux/spinlock.h>
42#include <linux/clk.h> 41#include <linux/clk.h>
43#include <linux/err.h> 42#include <linux/err.h>
@@ -190,30 +189,9 @@ static __init void omap_init_mpu_timer(unsigned long rate)
190 * --------------------------------------------------------------------------- 189 * ---------------------------------------------------------------------------
191 */ 190 */
192 191
193static DEFINE_CLOCK_DATA(cd); 192static u32 notrace omap_mpu_read_sched_clock(void)
194
195static inline unsigned long long notrace _omap_mpu_sched_clock(void)
196{
197 u32 cyc = ~omap_mpu_timer_read(1);
198 return cyc_to_sched_clock(&cd, cyc, (u32)~0);
199}
200
201#ifndef CONFIG_OMAP_32K_TIMER
202unsigned long long notrace sched_clock(void)
203{
204 return _omap_mpu_sched_clock();
205}
206#else
207static unsigned long long notrace omap_mpu_sched_clock(void)
208{
209 return _omap_mpu_sched_clock();
210}
211#endif
212
213static void notrace mpu_update_sched_clock(void)
214{ 193{
215 u32 cyc = ~omap_mpu_timer_read(1); 194 return ~omap_mpu_timer_read(1);
216 update_sched_clock(&cd, cyc, (u32)~0);
217} 195}
218 196
219static void __init omap_init_clocksource(unsigned long rate) 197static void __init omap_init_clocksource(unsigned long rate)
@@ -223,7 +201,7 @@ static void __init omap_init_clocksource(unsigned long rate)
223 "%s: can't register clocksource!\n"; 201 "%s: can't register clocksource!\n";
224 202
225 omap_mpu_timer_start(1, ~0, 1); 203 omap_mpu_timer_start(1, ~0, 1);
226 init_sched_clock(&cd, mpu_update_sched_clock, 32, rate); 204 setup_sched_clock(omap_mpu_read_sched_clock, 32, rate);
227 205
228 if (clocksource_mmio_init(&timer->read_tim, "mpu_timer2", rate, 206 if (clocksource_mmio_init(&timer->read_tim, "mpu_timer2", rate,
229 300, 32, clocksource_mmio_readl_down)) 207 300, 32, clocksource_mmio_readl_down))
@@ -254,30 +232,6 @@ static inline void omap_mpu_timer_init(void)
254} 232}
255#endif /* CONFIG_OMAP_MPU_TIMER */ 233#endif /* CONFIG_OMAP_MPU_TIMER */
256 234
257#if defined(CONFIG_OMAP_MPU_TIMER) && defined(CONFIG_OMAP_32K_TIMER)
258static unsigned long long (*preferred_sched_clock)(void);
259
260unsigned long long notrace sched_clock(void)
261{
262 if (!preferred_sched_clock)
263 return 0;
264
265 return preferred_sched_clock();
266}
267
268static inline void preferred_sched_clock_init(bool use_32k_sched_clock)
269{
270 if (use_32k_sched_clock)
271 preferred_sched_clock = omap_32k_sched_clock;
272 else
273 preferred_sched_clock = omap_mpu_sched_clock;
274}
275#else
276static inline void preferred_sched_clock_init(bool use_32k_sched_clcok)
277{
278}
279#endif
280
281static inline int omap_32k_timer_usable(void) 235static inline int omap_32k_timer_usable(void)
282{ 236{
283 int res = false; 237 int res = false;
@@ -299,12 +253,8 @@ static inline int omap_32k_timer_usable(void)
299 */ 253 */
300static void __init omap1_timer_init(void) 254static void __init omap1_timer_init(void)
301{ 255{
302 if (omap_32k_timer_usable()) { 256 if (!omap_32k_timer_usable())
303 preferred_sched_clock_init(1);
304 } else {
305 omap_mpu_timer_init(); 257 omap_mpu_timer_init();
306 preferred_sched_clock_init(0);
307 }
308} 258}
309 259
310struct sys_timer omap1_timer = { 260struct sys_timer omap1_timer = {