diff options
Diffstat (limited to 'drivers/cpuidle/cpuidle-psci.c')
-rw-r--r-- | drivers/cpuidle/cpuidle-psci.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c index 2562dc001fc1..2812e3bf200d 100644 --- a/drivers/cpuidle/cpuidle-psci.c +++ b/drivers/cpuidle/cpuidle-psci.c @@ -25,6 +25,7 @@ #include <linux/syscore_ops.h> #include <asm/cpuidle.h> +#include <trace/events/power.h> #include "cpuidle-psci.h" #include "dt_idle_states.h" @@ -38,7 +39,6 @@ struct psci_cpuidle_data { static DEFINE_PER_CPU_READ_MOSTLY(struct psci_cpuidle_data, psci_cpuidle_data); static DEFINE_PER_CPU(u32, domain_state); static bool psci_cpuidle_use_syscore; -static bool psci_cpuidle_use_cpuhp; void psci_set_domain_state(u32 state) { @@ -74,7 +74,9 @@ static __cpuidle int __psci_enter_domain_idle_state(struct cpuidle_device *dev, if (!state) state = states[idx]; + trace_psci_domain_idle_enter(dev->cpu, state, s2idle); ret = psci_cpu_suspend_enter(state) ? -1 : idx; + trace_psci_domain_idle_exit(dev->cpu, state, s2idle); if (s2idle) dev_pm_genpd_resume(pd_dev); @@ -105,8 +107,12 @@ static int psci_idle_cpuhp_up(unsigned int cpu) { struct device *pd_dev = __this_cpu_read(psci_cpuidle_data.dev); - if (pd_dev) - pm_runtime_get_sync(pd_dev); + if (pd_dev) { + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) + pm_runtime_get_sync(pd_dev); + else + dev_pm_genpd_resume(pd_dev); + } return 0; } @@ -116,7 +122,11 @@ static int psci_idle_cpuhp_down(unsigned int cpu) struct device *pd_dev = __this_cpu_read(psci_cpuidle_data.dev); if (pd_dev) { - pm_runtime_put_sync(pd_dev); + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) + pm_runtime_put_sync(pd_dev); + else + dev_pm_genpd_suspend(pd_dev); + /* Clear domain state to start fresh at next online. */ psci_set_domain_state(0); } @@ -177,9 +187,6 @@ static void psci_idle_init_cpuhp(void) { int err; - if (!psci_cpuidle_use_cpuhp) - return; - err = cpuhp_setup_state_nocalls(CPUHP_AP_CPU_PM_STARTING, "cpuidle/psci:online", psci_idle_cpuhp_up, @@ -240,10 +247,8 @@ static int psci_dt_cpu_init_topology(struct cpuidle_driver *drv, * s2ram and s2idle. */ drv->states[state_count - 1].enter_s2idle = psci_enter_s2idle_domain_idle_state; - if (!IS_ENABLED(CONFIG_PREEMPT_RT)) { + if (!IS_ENABLED(CONFIG_PREEMPT_RT)) drv->states[state_count - 1].enter = psci_enter_domain_idle_state; - psci_cpuidle_use_cpuhp = true; - } return 0; } @@ -320,7 +325,6 @@ static void psci_cpu_deinit_idle(int cpu) dt_idle_detach_cpu(data->dev); psci_cpuidle_use_syscore = false; - psci_cpuidle_use_cpuhp = false; } static int psci_idle_init_cpu(struct device *dev, int cpu) @@ -400,7 +404,7 @@ deinit: /* * psci_idle_probe - Initializes PSCI cpuidle driver * - * Initializes PSCI cpuidle driver for all CPUs, if any CPU fails + * Initializes PSCI cpuidle driver for all present CPUs, if any CPU fails * to register cpuidle driver then rollback to cancel all CPUs * registration. */ @@ -410,7 +414,7 @@ static int psci_cpuidle_probe(struct platform_device *pdev) struct cpuidle_driver *drv; struct cpuidle_device *dev; - for_each_possible_cpu(cpu) { + for_each_present_cpu(cpu) { ret = psci_idle_init_cpu(&pdev->dev, cpu); if (ret) goto out_fail; |