From 44ee7714a231652cfd20e88caff5d4420a2b8092 Mon Sep 17 00:00:00 2001 From: Boyan Karatotev Date: Mon, 30 Sep 2024 13:15:25 +0100 Subject: [PATCH] refactor(psci): factor common code out of the standby finisher psci_suspend_to_standby_finisher and psci_cpu_suspend_finish do mostly the same stuff, besides the system management associated with their respective wakeup paths. So bring the wake from standby path in line with the wake from reset path - caller acquires locks and manages context. This way both behave in vaguely the same way. We can also bring their names in line so it's more apparent how they are different. This is in preparation for cores waking from sleep, coming in another patch. No functional change is expected. Change-Id: I0e569d12f65d231606080faa0149d22efddc386d Signed-off-by: Boyan Karatotev --- lib/psci/psci_common.c | 2 +- lib/psci/psci_private.h | 4 +-- lib/psci/psci_suspend.c | 62 +++++++++++++++++++---------------------- 3 files changed, 31 insertions(+), 37 deletions(-) diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c index 5c7993bf2..25e8c5254 100644 --- a/lib/psci/psci_common.c +++ b/lib/psci/psci_common.c @@ -1021,7 +1021,7 @@ void psci_warmboot_entrypoint(void) if (psci_get_aff_info_state() == AFF_STATE_ON_PENDING) psci_cpu_on_finish(cpu_idx, &state_info); else - psci_cpu_suspend_finish(cpu_idx, &state_info); + psci_cpu_suspend_to_powerdown_finish(cpu_idx, &state_info); /* * Generic management: Now we just need to retrieve the diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h index 2eb4a9b70..e63275f64 100644 --- a/lib/psci/psci_private.h +++ b/lib/psci/psci_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -348,7 +348,7 @@ int psci_cpu_suspend_start(const entry_point_info_t *ep, psci_power_state_t *state_info, unsigned int is_power_down_state); -void psci_cpu_suspend_finish(unsigned int cpu_idx, const psci_power_state_t *state_info); +void psci_cpu_suspend_to_powerdown_finish(unsigned int cpu_idx, const psci_power_state_t *state_info); /* Private exported functions from psci_helpers.S */ void psci_do_pwrdown_cache_maintenance(unsigned int pwr_level); diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c index 300466672..83df099bc 100644 --- a/lib/psci/psci_suspend.c +++ b/lib/psci/psci_suspend.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -25,45 +25,18 @@ * This function does generic and platform specific operations after a wake-up * from standby/retention states at multiple power levels. ******************************************************************************/ -static void psci_suspend_to_standby_finisher(unsigned int cpu_idx, - unsigned int end_pwrlvl) +static void psci_cpu_suspend_to_standby_finish(unsigned int cpu_idx, + unsigned int end_pwrlvl, + psci_power_state_t *state_info) { - unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0}; - psci_power_state_t state_info; - - /* Get the parent nodes */ - psci_get_parent_pwr_domain_nodes(cpu_idx, end_pwrlvl, parent_nodes); - - psci_acquire_pwr_domain_locks(end_pwrlvl, parent_nodes); - - /* - * Find out which retention states this CPU has exited from until the - * 'end_pwrlvl'. The exit retention state could be deeper than the entry - * state as a result of state coordination amongst other CPUs post wfi. - */ - psci_get_target_local_pwr_states(end_pwrlvl, &state_info); - -#if ENABLE_PSCI_STAT - plat_psci_stat_accounting_stop(&state_info); - psci_stats_update_pwr_up(end_pwrlvl, &state_info); -#endif - /* * Plat. management: Allow the platform to do operations * on waking up from retention. */ - psci_plat_pm_ops->pwr_domain_suspend_finish(&state_info); + psci_plat_pm_ops->pwr_domain_suspend_finish(state_info); /* This loses its meaning when not suspending, reset so it's correct for OFF */ psci_set_suspend_pwrlvl(PLAT_MAX_PWR_LVL); - - /* - * Set the requested and target state of this CPU and all the higher - * power domain levels for this CPU to run. - */ - psci_set_pwr_domains_to_run(end_pwrlvl); - - psci_release_pwr_domain_locks(end_pwrlvl, parent_nodes); } /******************************************************************************* @@ -307,11 +280,32 @@ exit: PMF_NO_CACHE_MAINT); #endif + psci_acquire_pwr_domain_locks(end_pwrlvl, parent_nodes); + /* + * Find out which retention states this CPU has exited from until the + * 'end_pwrlvl'. The exit retention state could be deeper than the entry + * state as a result of state coordination amongst other CPUs post wfi. + */ + psci_get_target_local_pwr_states(end_pwrlvl, state_info); + +#if ENABLE_PSCI_STAT + plat_psci_stat_accounting_stop(state_info); + psci_stats_update_pwr_up(end_pwrlvl, state_info); +#endif + /* * After we wake up from context retaining suspend, call the * context retaining suspend finisher. */ - psci_suspend_to_standby_finisher(idx, end_pwrlvl); + psci_cpu_suspend_to_standby_finish(idx, end_pwrlvl, state_info); + + /* + * Set the requested and target state of this CPU and all the higher + * power domain levels for this CPU to run. + */ + psci_set_pwr_domains_to_run(end_pwrlvl); + + psci_release_pwr_domain_locks(end_pwrlvl, parent_nodes); return rc; } @@ -321,7 +315,7 @@ exit: * are called by the common finisher routine in psci_common.c. The `state_info` * is the psci_power_state from which this CPU has woken up from. ******************************************************************************/ -void psci_cpu_suspend_finish(unsigned int cpu_idx, const psci_power_state_t *state_info) +void psci_cpu_suspend_to_powerdown_finish(unsigned int cpu_idx, const psci_power_state_t *state_info) { unsigned int counter_freq; unsigned int max_off_lvl;