diff options
author | Ulf Hansson <ulf.hansson@linaro.org> | 2018-03-06 13:17:00 +0100 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2018-11-08 00:49:27 +0100 |
commit | a272cb679587f161b879defa362fb53e5d661dcd (patch) | |
tree | fea2698b9614cb075762de2accf12bdb4239ab91 | |
parent | 249aff4ab4d385d167041ceeea39ab4b81dbfcaa (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.c | 12 |
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); } |