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 <boyan.karatotev@arm.com>
This commit is contained in:
Boyan Karatotev 2024-09-30 13:15:25 +01:00
parent 0c836554b2
commit 44ee7714a2
3 changed files with 31 additions and 37 deletions

View file

@ -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

View file

@ -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);

View file

@ -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;