summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2018-03-06 13:17:00 +0100
committerUlf Hansson <ulf.hansson@linaro.org>2018-11-08 00:49:27 +0100
commita272cb679587f161b879defa362fb53e5d661dcd (patch)
treefea2698b9614cb075762de2accf12bdb4239ab91
parent249aff4ab4d385d167041ceeea39ab4b81dbfcaa (diff)
drivers: firmware: psci: Support CPU hotplug for the hierarchical model
To deal with CPU hotplug when the hierarchical PM topology is used, the CPU device needs to be detached from its PM domain (genpd), when putting it offline. This is needed due to that the CPU would otherwise become considered as being active by genpd from a runtime PM point of view, which consequentially would lead to preventing other parts in the PM topology from entering low power states. Obviously, let's then also re-attach the CPU device to its PM domain, when the CPU becomes brought back online, as to restore the original behaviour. Changes in v10: - Make it work when the hierarchical PM topology is used, which may be used both for OSI mode and PC mode. Cc: Lina Iyer <ilina@codeaurora.org> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-rw-r--r--drivers/firmware/psci/psci.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
index 7dc9f4641346..7afa6c5761e0 100644
--- a/drivers/firmware/psci/psci.c
+++ b/drivers/firmware/psci/psci.c
@@ -203,6 +203,14 @@ static int psci_cpu_off(u32 state)
int err;
u32 fn;
+ /*
+ * If we are using the hierarchical PM topology, let's detach the CPU's
+ * device from its PM domain, as to avoid preventing idle states for
+ * other parts.
+ */
+ if (psci_dt_topology)
+ of_genpd_detach_cpu(smp_processor_id());
+
fn = psci_function_id[PSCI_FN_CPU_OFF];
err = invoke_psci_fn(fn, state, 0, 0);
return psci_to_linux_errno(err);
@@ -217,6 +225,10 @@ static int psci_cpu_on(unsigned long cpuid, unsigned long entry_point)
err = invoke_psci_fn(fn, cpuid, entry_point, 0);
/* Clear the domain state to start fresh. */
psci_set_domain_state(0);
+
+ if (!err && psci_dt_topology)
+ of_genpd_attach_cpu(cpuid);
+
return psci_to_linux_errno(err);
}