Skip to content

Commit 573f1e5

Browse files
dlezcanogregkh
authored andcommitted
cpuidle: psci: Fix cpuhotplug routine with PREEMPT_RT=y
commit 621a88d upstream. Currently cpu hotplug with the PREEMPT_RT option set in the kernel is not supported because the underlying generic power domain functions used in the cpu hotplug callbacks are incompatible from a lock point of view. This situation prevents the suspend to idle to reach the deepest idle state for the "cluster" as identified in the undermentioned commit. Use the compatible ones when PREEMPT_RT is enabled and remove the boolean disabling the hotplug callbacks with this option. With this change the platform can reach the deepest idle state allowing at suspend time to consume less power. Tested-on Lenovo T14s with the following script: echo 0 > /sys/devices/system/cpu/cpu3/online BEFORE=$(cat /sys/kernel/debug/pm_genpd/power-domain-cpu-cluster0/idle_states | grep S0 | awk '{ print $3 }') ; rtcwake -s 1 -m mem; AFTER=$(cat /sys/kernel/debug/pm_genpd/power-domain-cpu-cluster0/idle_states | grep S0 | awk '{ print $3 }'); if [ $BEFORE -lt $AFTER ]; then echo "Test successful" else echo "Test failed" fi echo 1 > /sys/devices/system/cpu/cpu3/online Fixes: 1c4b293 ("cpuidle: psci: Enable the hierarchical topology for s2idle on PREEMPT_RT") Cc: Raghavendra Kakarla <quic_rkakarla@quicinc.com> Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> Reviewed-by: Sudeep Holla <sudeep.holla@arm.com> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20250709154728.733920-1-daniel.lezcano@linaro.org Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 9e11e0d commit 573f1e5

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

drivers/cpuidle/cpuidle-psci.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ struct psci_cpuidle_data {
3838
static DEFINE_PER_CPU_READ_MOSTLY(struct psci_cpuidle_data, psci_cpuidle_data);
3939
static DEFINE_PER_CPU(u32, domain_state);
4040
static bool psci_cpuidle_use_syscore;
41-
static bool psci_cpuidle_use_cpuhp;
4241

4342
void psci_set_domain_state(u32 state)
4443
{
@@ -105,8 +104,12 @@ static int psci_idle_cpuhp_up(unsigned int cpu)
105104
{
106105
struct device *pd_dev = __this_cpu_read(psci_cpuidle_data.dev);
107106

108-
if (pd_dev)
109-
pm_runtime_get_sync(pd_dev);
107+
if (pd_dev) {
108+
if (!IS_ENABLED(CONFIG_PREEMPT_RT))
109+
pm_runtime_get_sync(pd_dev);
110+
else
111+
dev_pm_genpd_resume(pd_dev);
112+
}
110113

111114
return 0;
112115
}
@@ -116,7 +119,11 @@ static int psci_idle_cpuhp_down(unsigned int cpu)
116119
struct device *pd_dev = __this_cpu_read(psci_cpuidle_data.dev);
117120

118121
if (pd_dev) {
119-
pm_runtime_put_sync(pd_dev);
122+
if (!IS_ENABLED(CONFIG_PREEMPT_RT))
123+
pm_runtime_put_sync(pd_dev);
124+
else
125+
dev_pm_genpd_suspend(pd_dev);
126+
120127
/* Clear domain state to start fresh at next online. */
121128
psci_set_domain_state(0);
122129
}
@@ -177,9 +184,6 @@ static void psci_idle_init_cpuhp(void)
177184
{
178185
int err;
179186

180-
if (!psci_cpuidle_use_cpuhp)
181-
return;
182-
183187
err = cpuhp_setup_state_nocalls(CPUHP_AP_CPU_PM_STARTING,
184188
"cpuidle/psci:online",
185189
psci_idle_cpuhp_up,
@@ -240,10 +244,8 @@ static int psci_dt_cpu_init_topology(struct cpuidle_driver *drv,
240244
* s2ram and s2idle.
241245
*/
242246
drv->states[state_count - 1].enter_s2idle = psci_enter_s2idle_domain_idle_state;
243-
if (!IS_ENABLED(CONFIG_PREEMPT_RT)) {
247+
if (!IS_ENABLED(CONFIG_PREEMPT_RT))
244248
drv->states[state_count - 1].enter = psci_enter_domain_idle_state;
245-
psci_cpuidle_use_cpuhp = true;
246-
}
247249

248250
return 0;
249251
}
@@ -320,7 +322,6 @@ static void psci_cpu_deinit_idle(int cpu)
320322

321323
dt_idle_detach_cpu(data->dev);
322324
psci_cpuidle_use_syscore = false;
323-
psci_cpuidle_use_cpuhp = false;
324325
}
325326

326327
static int psci_idle_init_cpu(struct device *dev, int cpu)

0 commit comments

Comments
 (0)