aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-nomadik/timer.c
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@stericsson.com>2010-05-07 05:03:02 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-05-13 07:22:42 -0400
commit2a847513cdecd517f7efc06296c539c3a936cf98 (patch)
tree53e900b62c497d88524e6020a6b47a492336bd5e /arch/arm/plat-nomadik/timer.c
parentaf7dc2281fd3cedc04cb51bcc0887cdaf65c3fcc (diff)
ARM: 6107/1: plat-nomadik: use the MTU clocksrc for sched_clock
This provides some serious scheduling for the Nomadik family by introducing a sched_clock() using the MTU clock source in the same manner as e.g. OMAP or U300. This type of solutions has been discussed at no end in the past, however we need this resolution for making measurements and using HRTimers. Signed-off-by: Linus Walleij <linus.walleij@stericsson.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/plat-nomadik/timer.c')
-rw-r--r--arch/arm/plat-nomadik/timer.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
index db67402518a6..0ff3798769ab 100644
--- a/arch/arm/plat-nomadik/timer.c
+++ b/arch/arm/plat-nomadik/timer.c
@@ -20,6 +20,15 @@
20 20
21void __iomem *mtu_base; /* ssigned by machine code */ 21void __iomem *mtu_base; /* ssigned by machine code */
22 22
23/*
24 * Kernel assumes that sched_clock can be called early
25 * but the MTU may not yet be initialized.
26 */
27static cycle_t nmdk_read_timer_dummy(struct clocksource *cs)
28{
29 return 0;
30}
31
23/* clocksource: MTU decrements, so we negate the value being read. */ 32/* clocksource: MTU decrements, so we negate the value being read. */
24static cycle_t nmdk_read_timer(struct clocksource *cs) 33static cycle_t nmdk_read_timer(struct clocksource *cs)
25{ 34{
@@ -29,12 +38,27 @@ static cycle_t nmdk_read_timer(struct clocksource *cs)
29static struct clocksource nmdk_clksrc = { 38static struct clocksource nmdk_clksrc = {
30 .name = "mtu_0", 39 .name = "mtu_0",
31 .rating = 200, 40 .rating = 200,
32 .read = nmdk_read_timer, 41 .read = nmdk_read_timer_dummy,
33 .mask = CLOCKSOURCE_MASK(32), 42 .mask = CLOCKSOURCE_MASK(32),
34 .shift = 20, 43 .shift = 20,
35 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 44 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
36}; 45};
37 46
47/*
48 * Override the global weak sched_clock symbol with this
49 * local implementation which uses the clocksource to get some
50 * better resolution when scheduling the kernel. We accept that
51 * this wraps around for now, since it is just a relative time
52 * stamp. (Inspired by OMAP implementation.)
53 */
54unsigned long long notrace sched_clock(void)
55{
56 return clocksource_cyc2ns(nmdk_clksrc.read(
57 &nmdk_clksrc),
58 nmdk_clksrc.mult,
59 nmdk_clksrc.shift);
60}
61
38/* Clockevent device: use one-shot mode */ 62/* Clockevent device: use one-shot mode */
39static void nmdk_clkevt_mode(enum clock_event_mode mode, 63static void nmdk_clkevt_mode(enum clock_event_mode mode,
40 struct clock_event_device *dev) 64 struct clock_event_device *dev)
@@ -121,6 +145,8 @@ void __init nmdk_timer_init(void)
121 writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0)); 145 writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
122 146
123 nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift); 147 nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift);
148 /* Now the scheduling clock is ready */
149 nmdk_clksrc.read = nmdk_read_timer;
124 150
125 if (clocksource_register(&nmdk_clksrc)) 151 if (clocksource_register(&nmdk_clksrc))
126 pr_err("timer: failed to initialize clock source %s\n", 152 pr_err("timer: failed to initialize clock source %s\n",