diff options
Diffstat (limited to 'drivers/cpuidle/cpuidle-psci-domain.c')
| -rw-r--r-- | drivers/cpuidle/cpuidle-psci-domain.c | 37 |
1 files changed, 13 insertions, 24 deletions
diff --git a/drivers/cpuidle/cpuidle-psci-domain.c b/drivers/cpuidle/cpuidle-psci-domain.c index b88af1262f1a..37c41209eaf9 100644 --- a/drivers/cpuidle/cpuidle-psci-domain.c +++ b/drivers/cpuidle/cpuidle-psci-domain.c @@ -20,6 +20,7 @@ #include <linux/string.h> #include "cpuidle-psci.h" +#include "dt_idle_genpd.h" struct psci_pd_provider { struct list_head link; @@ -27,7 +28,6 @@ struct psci_pd_provider { }; static LIST_HEAD(psci_pd_providers); -static bool psci_pd_allow_domain_state; static int psci_pd_power_off(struct generic_pm_domain *pd) { @@ -37,12 +37,9 @@ static int psci_pd_power_off(struct generic_pm_domain *pd) if (!state->data) return 0; - if (!psci_pd_allow_domain_state) - return -EBUSY; - /* OSI mode is enabled, set the corresponding domain state. */ pd_state = state->data; - psci_set_domain_state(*pd_state); + psci_set_domain_state(pd, pd->state_idx, *pd_state); return 0; } @@ -66,12 +63,17 @@ static int psci_pd_init(struct device_node *np, bool use_osi) /* * Allow power off when OSI has been successfully enabled. - * PREEMPT_RT is not yet ready to enter domain idle states. + * On a PREEMPT_RT based configuration the domain idle states are + * supported, but only during system-wide suspend. */ - if (use_osi && !IS_ENABLED(CONFIG_PREEMPT_RT)) + if (use_osi) { pd->power_off = psci_pd_power_off; - else + pd->flags |= GENPD_FLAG_ACTIVE_WAKEUP; + if (IS_ENABLED(CONFIG_PREEMPT_RT)) + pd->flags |= GENPD_FLAG_RPM_ALWAYS_ON; + } else { pd->flags |= GENPD_FLAG_ALWAYS_ON; + } /* Use governor for CPU PM domains if it has some states to manage. */ pd_gov = pd->states ? &pm_domain_cpu_gov : NULL; @@ -120,15 +122,6 @@ static void psci_pd_remove(void) } } -static void psci_cpuidle_domain_sync_state(struct device *dev) -{ - /* - * All devices have now been attached/probed to the PM domain topology, - * hence it's fine to allow domain states to be picked. - */ - psci_pd_allow_domain_state = true; -} - static const struct of_device_id psci_of_match[] = { { .compatible = "arm,psci-1.0" }, {} @@ -137,7 +130,6 @@ static const struct of_device_id psci_of_match[] = { static int psci_cpuidle_domain_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; - struct device_node *node; bool use_osi = psci_has_osi_support(); int ret = 0, pd_count = 0; @@ -148,15 +140,13 @@ static int psci_cpuidle_domain_probe(struct platform_device *pdev) * Parse child nodes for the "#power-domain-cells" property and * initialize a genpd/genpd-of-provider pair when it's found. */ - for_each_child_of_node(np, node) { + for_each_child_of_node_scoped(np, node) { if (!of_property_present(node, "#power-domain-cells")) continue; ret = psci_pd_init(node, use_osi); - if (ret) { - of_node_put(node); + if (ret) goto exit; - } pd_count++; } @@ -192,7 +182,6 @@ static struct platform_driver psci_cpuidle_domain_driver = { .driver = { .name = "psci-cpuidle-domain", .of_match_table = psci_of_match, - .sync_state = psci_cpuidle_domain_sync_state, }, }; @@ -200,4 +189,4 @@ static int __init psci_idle_init_domains(void) { return platform_driver_register(&psci_cpuidle_domain_driver); } -subsys_initcall(psci_idle_init_domains); +core_initcall(psci_idle_init_domains); |
