From: Ulf Hansson Date: Tue, 1 Jul 2025 11:47:24 +0000 (+0200) Subject: pmdomain: core: Leave powered-on genpds on until sync_state X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0e789b491ba04c31de5c71249487593e386baa67;p=thirdparty%2Flinux.git pmdomain: core: Leave powered-on genpds on until sync_state Powering-off a genpd that was on during boot, before all of its consumer devices have been probed, is certainly prone to problems. For OF based platforms we can rely on using the sync_state mechanism that the fw_devlink provides, to understand when all consumers for a genpd provider have been probed. Let's therefore prevent these genpds from being powered-off until the ->sync_state() callback gets called. Note that, for non-OF based platform we will keep relying on the late_initcall_sync, which seems to be the best we can do for now. Suggested-by: Saravana Kannan Tested-by: Hiago De Franco # Colibri iMX8X Tested-by: Tomi Valkeinen # TI AM62A,Xilinx ZynqMP ZCU106 Signed-off-by: Ulf Hansson Link: https://lore.kernel.org/r/20250701114733.636510-23-ulf.hansson@linaro.org --- diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c index 18951ed6295d8..a86aeda1c9556 100644 --- a/drivers/pmdomain/core.c +++ b/drivers/pmdomain/core.c @@ -1324,6 +1324,7 @@ err_poweroff: return ret; } +#ifndef CONFIG_PM_GENERIC_DOMAINS_OF static bool pd_ignore_unused; static int __init pd_ignore_unused_setup(char *__unused) { @@ -1359,6 +1360,7 @@ static int __init genpd_power_off_unused(void) return 0; } late_initcall_sync(genpd_power_off_unused); +#endif #ifdef CONFIG_PM_SLEEP @@ -3459,6 +3461,7 @@ void of_genpd_sync_state(struct device_node *np) list_for_each_entry(genpd, &gpd_list, gpd_list_node) { if (genpd->provider == of_fwnode_handle(np)) { genpd_lock(genpd); + genpd->stay_on = false; genpd_power_off(genpd, false, 0); genpd_unlock(genpd); } @@ -3486,6 +3489,7 @@ static void genpd_provider_sync_state(struct device *dev) case GENPD_SYNC_STATE_SIMPLE: genpd_lock(genpd); + genpd->stay_on = false; genpd_power_off(genpd, false, 0); genpd_unlock(genpd); break;