OSDN Git Service

cpuidle: psci: Prevent domain idlestates until consumers are ready
authorUlf Hansson <ulf.hansson@linaro.org>
Tue, 7 Jul 2020 12:58:04 +0000 (14:58 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 29 Jul 2020 16:38:30 +0000 (18:38 +0200)
Depending on the SoC/platform, additional devices may be part of the PSCI
PM domain topology. This is the case with 'qcom,rpmh-rsc' device, for
example, even if this is not yet visible in the corresponding DTS-files.

Without going into too much details, a device like the 'qcom,rpmh-rsc' may
have HW constraints that needs to be obeyed to, before a domain idlestate
can be picked.

Therefore, let's implement the ->sync_state() callback to receive a
notification when all consumers of the PSCI PM domain providers have been
attached/probed to it. In this way, we can make sure all constraints from
all relevant devices, are taken into account before allowing a domain
idlestate to be picked.

Acked-by: Saravana Kannan <saravanak@google.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/cpuidle/cpuidle-psci-domain.c

index bf527d2..b6e9649 100644 (file)
@@ -27,6 +27,7 @@ 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)
 {
@@ -36,6 +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);
@@ -222,6 +226,15 @@ static void psci_pd_remove_topology(struct device_node *np)
        psci_pd_init_topology(np, false);
 }
 
+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" },
        {}
@@ -289,6 +302,7 @@ 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,
        },
 };