diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/plat-nomadik/timer.c | 28 |
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 | ||
21 | void __iomem *mtu_base; /* ssigned by machine code */ | 21 | void __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 | */ | ||
27 | static 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. */ |
24 | static cycle_t nmdk_read_timer(struct clocksource *cs) | 33 | static cycle_t nmdk_read_timer(struct clocksource *cs) |
25 | { | 34 | { |
@@ -29,12 +38,27 @@ static cycle_t nmdk_read_timer(struct clocksource *cs) | |||
29 | static struct clocksource nmdk_clksrc = { | 38 | static 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 | */ | ||
54 | unsigned 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 */ |
39 | static void nmdk_clkevt_mode(enum clock_event_mode mode, | 63 | static 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", |