]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
cpuidle : handle clockevent notify from the cpuidle framework
authorDaniel Lezcano <daniel.lezcano@linaro.org>
Thu, 21 Mar 2013 12:21:31 +0000 (12:21 +0000)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 21 Mar 2013 21:56:21 +0000 (22:56 +0100)
When a cpu enters a deep idle state, the local timers are stopped and
the time framework falls back to the timer device used as a broadcast
timer.

The different cpuidle drivers are calling clockevents_notify ENTER/EXIT
when the idle state stops the local timer.

Add a new flag CPUIDLE_FLAG_TIMER_STOP which can be set by the cpuidle
drivers. If the flag is set, the cpuidle core code takes care of the
notification on behalf of the driver to avoid pointless code duplication.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/cpuidle/cpuidle.c
include/linux/cpuidle.h

index eba69290e0748b8fe5ee201bab4392916675c363..c50037029184b1e507690d133cd2ef87aa8c2c05 100644 (file)
@@ -8,6 +8,7 @@
  * This code is licenced under the GPL.
  */
 
+#include <linux/clockchips.h>
 #include <linux/kernel.h>
 #include <linux/mutex.h>
 #include <linux/sched.h>
@@ -146,12 +147,20 @@ int cpuidle_idle_call(void)
 
        trace_cpu_idle_rcuidle(next_state, dev->cpu);
 
+       if (drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP)
+               clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
+                                  &dev->cpu);
+
        if (cpuidle_state_is_coupled(dev, drv, next_state))
                entered_state = cpuidle_enter_state_coupled(dev, drv,
                                                            next_state);
        else
                entered_state = cpuidle_enter_state(dev, drv, next_state);
 
+       if (drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP)
+               clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
+                                  &dev->cpu);
+
        trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
 
        /* give the governor an opportunity to reflect on the outcome */
index 480c14dc1ddd5936d48820739ae6847c6e0c52bb..a837b332df6551c1e478bdb288ca194e198580d9 100644 (file)
@@ -57,6 +57,7 @@ struct cpuidle_state {
 /* Idle State Flags */
 #define CPUIDLE_FLAG_TIME_VALID        (0x01) /* is residency time measurable? */
 #define CPUIDLE_FLAG_COUPLED   (0x02) /* state applies to multiple cpus */
+#define CPUIDLE_FLAG_TIMER_STOP (0x04)  /* timer is stopped on this state */
 
 #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000)