[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 34.5/36] cpuidle,omap4: Push RCU-idle into omap4_enter_lowpower()



OMAP4 uses full SoC suspend modes as idle states, as such it needs the
whole power-domain and clock-domain code from the idle path.

All that code is not suitable to run with RCU disabled, as such push
RCU-idle deeper still.

Signed-off-by: Tony Lindgren <tony@xxxxxxxxxxx>
---

Peter here's one more for your series, looks like this is needed to avoid
warnings similar to what you did for omap3.

---
 arch/arm/mach-omap2/common.h              |  6 ++++--
 arch/arm/mach-omap2/cpuidle44xx.c         |  8 ++------
 arch/arm/mach-omap2/omap-mpuss-lowpower.c | 12 +++++++++++-
 arch/arm/mach-omap2/pm44xx.c              |  2 +-
 4 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -284,11 +284,13 @@ extern u32 omap4_get_cpu1_ns_pa_addr(void);
 
 #if defined(CONFIG_SMP) && defined(CONFIG_PM)
 extern int omap4_mpuss_init(void);
-extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state);
+extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state,
+                               bool rcuidle);
 extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state);
 #else
 static inline int omap4_enter_lowpower(unsigned int cpu,
-                                       unsigned int power_state)
+                                       unsigned int power_state,
+                                       bool rcuidle)
 {
        cpu_do_idle();
        return 0;
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c 
b/arch/arm/mach-omap2/cpuidle44xx.c
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -105,9 +105,7 @@ static int omap_enter_idle_smp(struct cpuidle_device *dev,
        }
        raw_spin_unlock_irqrestore(&mpu_lock, flag);
 
-       cpuidle_rcu_enter();
-       omap4_enter_lowpower(dev->cpu, cx->cpu_state);
-       cpuidle_rcu_exit();
+       omap4_enter_lowpower(dev->cpu, cx->cpu_state, true);
 
        raw_spin_lock_irqsave(&mpu_lock, flag);
        if (cx->mpu_state_vote == num_online_cpus())
@@ -186,10 +184,8 @@ static int omap_enter_idle_coupled(struct cpuidle_device 
*dev,
                }
        }
 
-       cpuidle_rcu_enter();
-       omap4_enter_lowpower(dev->cpu, cx->cpu_state);
+       omap4_enter_lowpower(dev->cpu, cx->cpu_state, true);
        cpu_done[dev->cpu] = true;
-       cpuidle_rcu_exit();
 
        /* Wakeup CPU1 only if it is not offlined */
        if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c 
b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -33,6 +33,7 @@
  * and first to wake-up when MPUSS low power states are excercised
  */
 
+#include <linux/cpuidle.h>
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <linux/errno.h>
@@ -214,6 +215,7 @@ static void __init save_l2x0_context(void)
  * of OMAP4 MPUSS subsystem
  * @cpu : CPU ID
  * @power_state: Low power state.
+ * @rcuidle: RCU needs to be idled
  *
  * MPUSS states for the context save:
  * save_state =
@@ -222,7 +224,8 @@ static void __init save_l2x0_context(void)
  *     2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
  *     3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF
  */
-int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
+int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state,
+                        bool rcuidle)
 {
        struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);
        unsigned int save_state = 0, cpu_logic_state = PWRDM_POWER_RET;
@@ -268,6 +271,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int 
power_state)
        cpu_clear_prev_logic_pwrst(cpu);
        pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);
        pwrdm_set_logic_retst(pm_info->pwrdm, cpu_logic_state);
+
+       if (rcuidle)
+               cpuidle_rcu_enter();
+
        set_cpu_wakeup_addr(cpu, __pa_symbol(omap_pm_ops.resume));
        omap_pm_ops.scu_prepare(cpu, power_state);
        l2x0_pwrst_prepare(cpu, save_state);
@@ -283,6 +290,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int 
power_state)
        if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD) && cpu)
                gic_dist_enable();
 
+       if (rcuidle)
+               cpuidle_rcu_exit();
+
        /*
         * Restore the CPUx power state to ON otherwise CPUx
         * power domain can transitions to programmed low power
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -76,7 +76,7 @@ static int omap4_pm_suspend(void)
         * domain CSWR is not supported by hardware.
         * More details can be found in OMAP4430 TRM section 4.3.4.2.
         */
-       omap4_enter_lowpower(cpu_id, cpu_suspend_state);
+       omap4_enter_lowpower(cpu_id, cpu_suspend_state, false);
 
        /* Restore next powerdomain state */
        list_for_each_entry(pwrst, &pwrst_list, node) {
-- 
2.36.1



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.