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;
 }