summaryrefslogtreecommitdiff
path: root/drivers/cpuidle
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@oss.qualcomm.com>2026-09-14 17:01:40 +0200
committerUlf Hansson <ulfh@kernel.org>2026-09-17 15:30:58 +0200
commit6d3080bfe007c88c38b6faf6d3ab23171af359f0 (patch)
tree2dacd9e4ef25d30d684a2414002a22b2894813ed /drivers/cpuidle
parent2224d686e788d6ad3af4cc48bbf68723f8abd326 (diff)
downloadlinux-next-6d3080bfe007c88c38b6faf6d3ab23171af359f0.tar.gz
linux-next-6d3080bfe007c88c38b6faf6d3ab23171af359f0.zip
cpuidle: psci: Initialize the PM domains in powered off state for OSI
At the point when the PM domain and the topology are registered through the genpd subsystem, it's not really known whether corresponding CPUs are online and thus if the PM domain should be initialized as powered on or not. Instead this information becomes available when the CPU devices gets attached to their respective PM domain through dt_idle_attach_cpu(). This is a problem when using PSCI OS-initiated mode, as we may end up with a PM domain that has the genpd's status indicating it to be powered on, while it in fact may not be the case. In the less severe scenario, this leads to selecting a shallower domain idle state for the PM domain than necessary. A more critical problem is when a non-CPU device shares the PM domain, leading to their corresponding drivers not being able to trust the status of it. Let's fix these problems by initializing the state for the genpd's to be powered off and in the deepest possible domain idle state, when using OS-initiated mode. The support for ->sync_state() is maintained by setting the GENPD_FLAG_POWER_UNKNOWN for the genpds in question. Reported-by: Maulik Shah <maulik.shah@oss.qualcomm.com> Link: https://lore.kernel.org/all/20260811-domain_off_ss3-v1-0-6a0a0fc023f5@oss.qualcomm.com/ Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com> Tested-by: Yuanfang Zhang <yuanfang.zhang@oss.qualcomm.com> Signed-off-by: Ulf Hansson <ulf.hansson@oss.qualcomm.com> Reviewed-by: Dhruva Gole <goledhruva@gmail.com> Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Diffstat (limited to 'drivers/cpuidle')
-rw-r--r--drivers/cpuidle/cpuidle-psci-domain.c7
1 files changed, 3 insertions, 4 deletions
diff --git a/drivers/cpuidle/cpuidle-psci-domain.c b/drivers/cpuidle/cpuidle-psci-domain.c
index b9e4ad7d43a3..5722365b943e 100644
--- a/drivers/cpuidle/cpuidle-psci-domain.c
+++ b/drivers/cpuidle/cpuidle-psci-domain.c
@@ -68,9 +68,8 @@ static int psci_pd_init(struct device_node *np, bool use_osi)
*/
if (use_osi) {
pd->power_off = psci_pd_power_off;
- pd->flags |= GENPD_FLAG_ACTIVE_WAKEUP;
- if (IS_ENABLED(CONFIG_PREEMPT_RT))
- pd->flags |= GENPD_FLAG_RPM_ALWAYS_ON;
+ pd->flags |= GENPD_FLAG_ACTIVE_WAKEUP | GENPD_FLAG_POWER_UNKNOWN;
+ pd->state_idx = pd->state_count ? pd->state_count - 1 : 0;
} else {
pd->flags |= GENPD_FLAG_ALWAYS_ON;
}
@@ -78,7 +77,7 @@ static int psci_pd_init(struct device_node *np, bool use_osi)
/* Use governor for CPU PM domains if it has some states to manage. */
pd_gov = pd->states ? &pm_domain_cpu_gov : NULL;
- ret = pm_genpd_init(pd, pd_gov, false);
+ ret = pm_genpd_init(pd, pd_gov, use_osi);
if (ret)
goto free_pd_prov;