diff options
Diffstat (limited to 'arch/arm/mach-prima2')
-rw-r--r-- | arch/arm/mach-prima2/timer.c | 21 |
1 files changed, 7 insertions, 14 deletions
diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer.c index b7a6091ce791..0d024b1e916d 100644 --- a/arch/arm/mach-prima2/timer.c +++ b/arch/arm/mach-prima2/timer.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/of.h> | 18 | #include <linux/of.h> |
19 | #include <linux/of_address.h> | 19 | #include <linux/of_address.h> |
20 | #include <mach/map.h> | 20 | #include <mach/map.h> |
21 | #include <asm/sched_clock.h> | ||
21 | #include <asm/mach/time.h> | 22 | #include <asm/mach/time.h> |
22 | 23 | ||
23 | #define SIRFSOC_TIMER_COUNTER_LO 0x0000 | 24 | #define SIRFSOC_TIMER_COUNTER_LO 0x0000 |
@@ -165,21 +166,9 @@ static struct irqaction sirfsoc_timer_irq = { | |||
165 | }; | 166 | }; |
166 | 167 | ||
167 | /* Overwrite weak default sched_clock with more precise one */ | 168 | /* Overwrite weak default sched_clock with more precise one */ |
168 | unsigned long long notrace sched_clock(void) | 169 | static u32 notrace sirfsoc_read_sched_clock(void) |
169 | { | 170 | { |
170 | static int is_mapped; | 171 | return (u32)(sirfsoc_timer_read(NULL) & 0xffffffff); |
171 | |||
172 | /* | ||
173 | * sched_clock is called earlier than .init of sys_timer | ||
174 | * if we map timer memory in .init of sys_timer, system | ||
175 | * will panic due to illegal memory access | ||
176 | */ | ||
177 | if (!is_mapped) { | ||
178 | sirfsoc_of_timer_map(); | ||
179 | is_mapped = 1; | ||
180 | } | ||
181 | |||
182 | return sirfsoc_timer_read(NULL) * (NSEC_PER_SEC / CLOCK_TICK_RATE); | ||
183 | } | 172 | } |
184 | 173 | ||
185 | static void __init sirfsoc_clockevent_init(void) | 174 | static void __init sirfsoc_clockevent_init(void) |
@@ -210,6 +199,8 @@ static void __init sirfsoc_timer_init(void) | |||
210 | BUG_ON(rate < CLOCK_TICK_RATE); | 199 | BUG_ON(rate < CLOCK_TICK_RATE); |
211 | BUG_ON(rate % CLOCK_TICK_RATE); | 200 | BUG_ON(rate % CLOCK_TICK_RATE); |
212 | 201 | ||
202 | sirfsoc_of_timer_map(); | ||
203 | |||
213 | writel_relaxed(rate / CLOCK_TICK_RATE / 2 - 1, sirfsoc_timer_base + SIRFSOC_TIMER_DIV); | 204 | writel_relaxed(rate / CLOCK_TICK_RATE / 2 - 1, sirfsoc_timer_base + SIRFSOC_TIMER_DIV); |
214 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); | 205 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); |
215 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); | 206 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); |
@@ -217,6 +208,8 @@ static void __init sirfsoc_timer_init(void) | |||
217 | 208 | ||
218 | BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE)); | 209 | BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE)); |
219 | 210 | ||
211 | setup_sched_clock(sirfsoc_read_sched_clock, 32, CLOCK_TICK_RATE); | ||
212 | |||
220 | BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq)); | 213 | BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq)); |
221 | 214 | ||
222 | sirfsoc_clockevent_init(); | 215 | sirfsoc_clockevent_init(); |