summaryrefslogtreecommitdiff
path: root/arch/arm/mach-ux500/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-ux500/timer.c')
-rw-r--r--arch/arm/mach-ux500/timer.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c
index d37df98b5c3..438c9715aab 100644
--- a/arch/arm/mach-ux500/timer.c
+++ b/arch/arm/mach-ux500/timer.c
@@ -7,6 +7,7 @@
#include <linux/io.h>
#include <linux/errno.h>
#include <linux/clksrc-dbx500-prcmu.h>
+#include <linux/clksrc-db5500-mtimer.h>
#include <linux/of.h>
#include <asm/smp_twd.h>
@@ -16,6 +17,21 @@
#include <mach/setup.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
+#include <mach/context.h>
+
+#ifdef CONFIG_UX500_CONTEXT
+static int mtu_context_notifier_call(struct notifier_block *this,
+ unsigned long event, void *data)
+{
+ if (event == CONTEXT_APE_RESTORE)
+ nmdk_clksrc_reset();
+ return NOTIFY_OK;
+}
+
+static struct notifier_block mtu_context_notifier = {
+ .notifier_call = mtu_context_notifier_call,
+};
+#endif
#ifdef CONFIG_HAVE_ARM_TWD
static DEFINE_TWD_LOCAL_TIMER(u5500_twd_local_timer,
@@ -51,7 +67,7 @@ static void __init ux500_timer_init(void)
if (cpu_is_u5500()) {
mtu_timer_base = __io_address(U5500_MTU0_BASE);
prcmu_timer_base = __io_address(U5500_PRCMU_TIMER_3_BASE);
- } else if (cpu_is_u8500()) {
+ } else if (cpu_is_u8500() || cpu_is_u9540()) {
mtu_timer_base = __io_address(U8500_MTU0_BASE);
prcmu_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE);
} else {
@@ -70,14 +86,24 @@ static void __init ux500_timer_init(void)
* depending on delay which is not yet calibrated. RTC-RTT is in the
* always-on powerdomain and is used as clockevent instead of twd when
* sleeping.
- * The PRCMU timer 4(3 for DB5500) register a clocksource and
- * sched_clock with higher rating then MTU since is always-on.
*
+ * The PRCMU timer 4 (3 for DB5500) registers a clocksource and
+ * sched_clock with higher rating than the MTU since it is
+ * always-on.
+ *
+ * On DB5500, the MTIMER is the best clocksource since, unlike the
+ * PRCMU timer, it doesn't occasionally go backwards.
*/
nmdk_timer_init(mtu_timer_base);
+ if (cpu_is_u5500())
+ db5500_mtimer_init(__io_address(U5500_MTIMER_BASE));
clksrc_dbx500_prcmu_init(prcmu_timer_base);
ux500_twd_init();
+
+#ifdef CONFIG_UX500_CONTEXT
+ WARN_ON(context_ape_notifier_register(&mtu_context_notifier));
+#endif
}
static void ux500_timer_reset(void)