]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
ARM: OMAP2+: timer: Add suspend-resume callbacks for clkevent device
authorDave Gerlach <d-gerlach@ti.com>
Wed, 29 Mar 2017 01:57:55 +0000 (20:57 -0500)
committerTony Lindgren <tony@atomide.com>
Tue, 16 May 2017 15:44:49 +0000 (08:44 -0700)
OMAP timer code registers two timers - one as clocksource
and one as clockevent. Since AM33XX has only one usable timer
in the WKUP domain one of the timers needs suspend-resume
support to restore the configuration to pre-suspend state.

commit adc78e6b9946 ("timekeeping: Add suspend and resume
of clock event devices") introduced .suspend and .resume
callbacks for clock event devices. Leverage these
callbacks to have AM33XX clockevent timer behave properly
across system suspend. Extend the use of the .suspend and
.resume callbacks used by am335x clockevent to am437x as well.

Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/mach-omap2/timer.c

index 07dd692c47372f8aa145d00cb5532b75774429c5..70670dfd71359adde2da913b3ad37f36c7d15838 100644 (file)
@@ -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);
 }