Merge tag 'cleanup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / arm / mach-omap2 / cpuidle44xx.c
index 9de47a70628f0e15a3ee49a47cb6c2be6a73d050..c443f2e97e103702531c79b70dccebc11a85218d 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * OMAP4 CPU idle Routines
+ * OMAP4+ CPU idle Routines
  *
- * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011-2013 Texas Instruments, Inc.
  * Santosh Shilimkar <santosh.shilimkar@ti.com>
  * Rajendra Nayak <rnayak@ti.com>
  *
@@ -14,8 +14,8 @@
 #include <linux/cpuidle.h>
 #include <linux/cpu_pm.h>
 #include <linux/export.h>
-#include <linux/clockchips.h>
 
+#include <asm/cpuidle.h>
 #include <asm/proc-fns.h>
 
 #include "common.h"
 #include "clockdomain.h"
 
 /* Machine specific information */
-struct omap4_idle_statedata {
+struct idle_statedata {
        u32 cpu_state;
        u32 mpu_logic_state;
        u32 mpu_state;
 };
 
-static struct omap4_idle_statedata omap4_idle_data[] = {
+static struct idle_statedata omap4_idle_data[] = {
        {
                .cpu_state = PWRDM_POWER_ON,
                .mpu_state = PWRDM_POWER_ON,
@@ -53,11 +53,12 @@ static struct clockdomain *cpu_clkdm[NR_CPUS];
 
 static atomic_t abort_barrier;
 static bool cpu_done[NR_CPUS];
+static struct idle_statedata *state_ptr = &omap4_idle_data[0];
 
 /* Private functions */
 
 /**
- * omap4_enter_idle_coupled_[simple/coupled] - OMAP4 cpuidle entry functions
+ * omap_enter_idle_[simple/coupled] - OMAP4PLUS cpuidle entry functions
  * @dev: cpuidle device
  * @drv: cpuidle driver
  * @index: the index of state to be entered
@@ -66,7 +67,7 @@ static bool cpu_done[NR_CPUS];
  * specified low power state selected by the governor.
  * Returns the amount of time spent in the low power state.
  */
-static int omap4_enter_idle_simple(struct cpuidle_device *dev,
+static int omap_enter_idle_simple(struct cpuidle_device *dev,
                        struct cpuidle_driver *drv,
                        int index)
 {
@@ -74,12 +75,11 @@ static int omap4_enter_idle_simple(struct cpuidle_device *dev,
        return index;
 }
 
-static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
+static int omap_enter_idle_coupled(struct cpuidle_device *dev,
                        struct cpuidle_driver *drv,
                        int index)
 {
-       struct omap4_idle_statedata *cx = &omap4_idle_data[index];
-       int cpu_id = smp_processor_id();
+       struct idle_statedata *cx = state_ptr + index;
 
        /*
         * CPU0 has to wait and stay ON until CPU1 is OFF state.
@@ -104,8 +104,6 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
                }
        }
 
-       clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id);
-
        /*
         * Call idle CPU PM enter notifier chain so that
         * VFP and per CPU interrupt context is saved.
@@ -145,11 +143,10 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
         * Call idle CPU cluster PM exit notifier chain
         * to restore GIC and wakeupgen context.
         */
-       if (omap4_mpuss_read_prev_context_state())
+       if ((cx->mpu_state == PWRDM_POWER_RET) &&
+               (cx->mpu_logic_state == PWRDM_POWER_OFF))
                cpu_cluster_pm_exit();
 
-       clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
-
 fail:
        cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
        cpu_done[dev->cpu] = false;
@@ -157,49 +154,38 @@ fail:
        return index;
 }
 
-/*
- * For each cpu, setup the broadcast timer because local timers
- * stops for the states above C1.
- */
-static void omap_setup_broadcast_timer(void *arg)
-{
-       int cpu = smp_processor_id();
-       clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
-}
-
-static DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev);
-
 static struct cpuidle_driver omap4_idle_driver = {
        .name                           = "omap4_idle",
        .owner                          = THIS_MODULE,
-       .en_core_tk_irqen               = 1,
        .states = {
                {
                        /* C1 - CPU0 ON + CPU1 ON + MPU ON */
                        .exit_latency = 2 + 2,
                        .target_residency = 5,
                        .flags = CPUIDLE_FLAG_TIME_VALID,
-                       .enter = omap4_enter_idle_simple,
+                       .enter = omap_enter_idle_simple,
                        .name = "C1",
-                       .desc = "MPUSS ON"
+                       .desc = "CPUx ON, MPUSS ON"
                },
                {
                        /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */
                        .exit_latency = 328 + 440,
                        .target_residency = 960,
-                       .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED,
-                       .enter = omap4_enter_idle_coupled,
+                       .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED |
+                                CPUIDLE_FLAG_TIMER_STOP,
+                       .enter = omap_enter_idle_coupled,
                        .name = "C2",
-                       .desc = "MPUSS CSWR",
+                       .desc = "CPUx OFF, MPUSS CSWR",
                },
                {
                        /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */
                        .exit_latency = 460 + 518,
                        .target_residency = 1100,
-                       .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED,
-                       .enter = omap4_enter_idle_coupled,
+                       .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED |
+                                CPUIDLE_FLAG_TIMER_STOP,
+                       .enter = omap_enter_idle_coupled,
                        .name = "C3",
-                       .desc = "MPUSS OSWR",
+                       .desc = "CPUx OFF, MPUSS OSWR",
                },
        },
        .state_count = ARRAY_SIZE(omap4_idle_data),
@@ -209,16 +195,13 @@ static struct cpuidle_driver omap4_idle_driver = {
 /* Public functions */
 
 /**
- * omap4_idle_init - Init routine for OMAP4 idle
+ * omap4_idle_init - Init routine for OMAP4+ idle
  *
- * Registers the OMAP4 specific cpuidle driver to the cpuidle
+ * Registers the OMAP4+ specific cpuidle driver to the cpuidle
  * framework with the valid set of states.
  */
 int __init omap4_idle_init(void)
 {
-       struct cpuidle_device *dev;
-       unsigned int cpu_id = 0;
-
        mpu_pd = pwrdm_lookup("mpu_pwrdm");
        cpu_pd[0] = pwrdm_lookup("cpu0_pwrdm");
        cpu_pd[1] = pwrdm_lookup("cpu1_pwrdm");
@@ -230,22 +213,5 @@ int __init omap4_idle_init(void)
        if (!cpu_clkdm[0] || !cpu_clkdm[1])
                return -ENODEV;
 
-       /* Configure the broadcast timer on each cpu */
-       on_each_cpu(omap_setup_broadcast_timer, NULL, 1);
-
-       for_each_cpu(cpu_id, cpu_online_mask) {
-               dev = &per_cpu(omap4_idle_dev, cpu_id);
-               dev->cpu = cpu_id;
-#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
-               dev->coupled_cpus = *cpu_online_mask;
-#endif
-               cpuidle_register_driver(&omap4_idle_driver);
-
-               if (cpuidle_register_device(dev)) {
-                       pr_err("%s: CPUidle register failed\n", __func__);
-                       return -EIO;
-               }
-       }
-
-       return 0;
+       return cpuidle_register(&omap4_idle_driver, cpu_online_mask);
 }