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@atomide.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Tested-by: Tony Lindgren <tony@atomide.com> Tested-by: Ulf Hansson <ulf.hansson@linaro.org> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Frederic Weisbecker <frederic@kernel.org> Link: https://lkml.kernel.org/r/Yqcv6crSNKuSWoTu@atomide.com Link: https://lore.kernel.org/r/20230112195541.660272394@infradead.org
This commit is contained in:
parent
8c0956aa76
commit
a282e5ef29
@ -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;
|
||||
|
@ -105,9 +105,7 @@ static int omap_enter_idle_smp(struct cpuidle_device *dev,
|
||||
}
|
||||
raw_spin_unlock_irqrestore(&mpu_lock, flag);
|
||||
|
||||
ct_cpuidle_enter();
|
||||
omap4_enter_lowpower(dev->cpu, cx->cpu_state);
|
||||
ct_cpuidle_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,
|
||||
}
|
||||
}
|
||||
|
||||
ct_cpuidle_enter();
|
||||
omap4_enter_lowpower(dev->cpu, cx->cpu_state);
|
||||
omap4_enter_lowpower(dev->cpu, cx->cpu_state, true);
|
||||
cpu_done[dev->cpu] = true;
|
||||
ct_cpuidle_exit();
|
||||
|
||||
/* Wakeup CPU1 only if it is not offlined */
|
||||
if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
|
||||
|
@ -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)
|
||||
ct_cpuidle_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)
|
||||
ct_cpuidle_exit();
|
||||
|
||||
/*
|
||||
* Restore the CPUx power state to ON otherwise CPUx
|
||||
* power domain can transitions to programmed low power
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user