diff options
author | Stephen Boyd <sboyd@codeaurora.org> | 2011-11-08 13:34:09 -0500 |
---|---|---|
committer | David Brown <davidb@codeaurora.org> | 2011-11-10 13:36:33 -0500 |
commit | dde7d61e7f9bf0e844df375412ec5d51650db486 (patch) | |
tree | eebad0b8c5cd9a47a6d230907cbdd1444d164396 /arch/arm | |
parent | 2081a6b57fba2717fa4b04fe978abad238e1f9e4 (diff) |
msm: timer: Setup interrupt after registering clockevent
Some bootloaders may leave a pending interrupt for the timer and
thus msm_timer_interrupt() has a check for a NULL event handler.
Unmask and register for the interrupt after registering the
clockevent so that we can get the NULL pointer check out of the
fast path.
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: David Brown <davidb@codeaurora.org>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-msm/timer.c | 6 |
1 files changed, 2 insertions, 4 deletions
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index ca0a957d8626..3d80fbf34165 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c | |||
@@ -47,8 +47,6 @@ static void __iomem *event_base; | |||
47 | static irqreturn_t msm_timer_interrupt(int irq, void *dev_id) | 47 | static irqreturn_t msm_timer_interrupt(int irq, void *dev_id) |
48 | { | 48 | { |
49 | struct clock_event_device *evt = *(struct clock_event_device **)dev_id; | 49 | struct clock_event_device *evt = *(struct clock_event_device **)dev_id; |
50 | if (evt->event_handler == NULL) | ||
51 | return IRQ_HANDLED; | ||
52 | /* Stop the timer tick */ | 50 | /* Stop the timer tick */ |
53 | if (evt->mode == CLOCK_EVT_MODE_ONESHOT) { | 51 | if (evt->mode == CLOCK_EVT_MODE_ONESHOT) { |
54 | u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE); | 52 | u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE); |
@@ -174,6 +172,7 @@ static void __init msm_timer_init(void) | |||
174 | ce->cpumask = cpumask_of(0); | 172 | ce->cpumask = cpumask_of(0); |
175 | 173 | ||
176 | ce->irq = INT_GP_TIMER_EXP; | 174 | ce->irq = INT_GP_TIMER_EXP; |
175 | clockevents_register_device(ce); | ||
177 | if (cpu_is_msm8x60() || cpu_is_msm8960()) { | 176 | if (cpu_is_msm8x60() || cpu_is_msm8960()) { |
178 | msm_evt.percpu_evt = alloc_percpu(struct clock_event_device *); | 177 | msm_evt.percpu_evt = alloc_percpu(struct clock_event_device *); |
179 | if (!msm_evt.percpu_evt) { | 178 | if (!msm_evt.percpu_evt) { |
@@ -194,7 +193,6 @@ static void __init msm_timer_init(void) | |||
194 | 193 | ||
195 | if (res) | 194 | if (res) |
196 | pr_err("request_irq failed for %s\n", ce->name); | 195 | pr_err("request_irq failed for %s\n", ce->name); |
197 | clockevents_register_device(ce); | ||
198 | err: | 196 | err: |
199 | writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE); | 197 | writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE); |
200 | res = clocksource_register_hz(cs, dgt_hz); | 198 | res = clocksource_register_hz(cs, dgt_hz); |
@@ -224,8 +222,8 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt) | |||
224 | evt->min_delta_ns = clockevent_delta2ns(4, evt); | 222 | evt->min_delta_ns = clockevent_delta2ns(4, evt); |
225 | 223 | ||
226 | *__this_cpu_ptr(msm_evt.percpu_evt) = evt; | 224 | *__this_cpu_ptr(msm_evt.percpu_evt) = evt; |
227 | enable_percpu_irq(evt->irq, 0); | ||
228 | clockevents_register_device(evt); | 225 | clockevents_register_device(evt); |
226 | enable_percpu_irq(evt->irq, 0); | ||
229 | return 0; | 227 | return 0; |
230 | } | 228 | } |
231 | 229 | ||