aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-omap2/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/timer.c')
-rw-r--r--arch/arm/mach-omap2/timer.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 07dd692c4737..70670dfd7135 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -68,6 +68,9 @@
static struct omap_dm_timer clkev;
static struct clock_event_device clockevent_gpt;
+/* Clockevent hwmod for am335x and am437x suspend */
+static struct omap_hwmod *clockevent_gpt_hwmod;
+
#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
static unsigned long arch_timer_freq;
@@ -125,6 +128,23 @@ static int omap2_gp_timer_set_periodic(struct clock_event_device *evt)
return 0;
}
+static void omap_clkevt_idle(struct clock_event_device *unused)
+{
+ if (!clockevent_gpt_hwmod)
+ return;
+
+ omap_hwmod_idle(clockevent_gpt_hwmod);
+}
+
+static void omap_clkevt_unidle(struct clock_event_device *unused)
+{
+ if (!clockevent_gpt_hwmod)
+ return;
+
+ omap_hwmod_enable(clockevent_gpt_hwmod);
+ __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
+}
+
static struct clock_event_device clockevent_gpt = {
.features = CLOCK_EVT_FEAT_PERIODIC |
CLOCK_EVT_FEAT_ONESHOT,
@@ -358,6 +378,14 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
3, /* Timer internal resynch latency */
0xffffffff);
+ if (soc_is_am33xx() || soc_is_am43xx()) {
+ clockevent_gpt.suspend = omap_clkevt_idle;
+ clockevent_gpt.resume = omap_clkevt_unidle;
+
+ clockevent_gpt_hwmod =
+ omap_hwmod_lookup(clockevent_gpt.name);
+ }
+
pr_info("OMAP clockevent source: %s at %lu Hz\n", clockevent_gpt.name,
clkev.rate);
}