arm: arch_timer: Enable timer in set_mode only
Currently, we enable the timer hardware and unmask its interrupt in
the set_next_event callback. However, during hotplug, this callback
can be called after the timer is already supposed to be disabled.
Since the timer will be completely turned back on by set_next_event,
we will soon receive an interrupt, potentially causing us to wake up
from hotplug.
Instead, continue unmasking the interrupt when set_next_event is
called, but only enable the timer hardware in the set_mode callback.
This means that, once arch_timer_disable is called, we are guaranteed
to not receive more timer interrupts until the cpu is intentionally
hotplugged back in.
Signed-off-by: Subbaraman Narayanamurthy <subbaram@codeaurora.org>
(cherry picked from commit 9e31f169e9e9a6255fdfcef0dfda86c8287e5a54)
Change-Id: I24dd67905f8fd772fbb9dbc42ca3cdaa7dc4345f
Signed-off-by: Sudhir Sharma <sudsha@codeaurora.org>
diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c
index 23d310d..2455d1f 100644
--- a/arch/arm/kernel/arch_timer.c
+++ b/arch/arm/kernel/arch_timer.c
@@ -192,11 +192,17 @@
static void arch_timer_set_mode(enum clock_event_mode mode,
struct clock_event_device *clk)
{
+ unsigned long ctrl;
+
switch (mode) {
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_SHUTDOWN:
arch_timer_disable();
break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ ctrl = arch_specific_timer->reg_read(ARCH_TIMER_REG_CTRL);
+ ctrl |= ARCH_TIMER_CTRL_ENABLE;
+ arch_specific_timer->reg_write(ARCH_TIMER_REG_CTRL, ctrl);
default:
break;
}
@@ -208,11 +214,9 @@
unsigned long ctrl;
ctrl = arch_specific_timer->reg_read(ARCH_TIMER_REG_CTRL);
- ctrl &= ~(ARCH_TIMER_CTRL_ENABLE | ARCH_TIMER_CTRL_IT_MASK);
+ ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
arch_specific_timer->reg_write(ARCH_TIMER_REG_CTRL, ctrl);
arch_specific_timer->reg_write(ARCH_TIMER_REG_TVAL, evt);
- ctrl |= ARCH_TIMER_CTRL_ENABLE;
- arch_specific_timer->reg_write(ARCH_TIMER_REG_CTRL, ctrl);
return 0;
}