mirror of
https://github.com/CTCaer/switch-l4t-atf.git
synced 2025-02-12 13:48:23 +00:00
Fix use of stale power states in PSCI standby finisher
A PSCI CPU_SUSPEND request to place a CPU in retention states at power levels higher than the CPU power level is subject to the same state coordination as a power down state. A CPU could implement multiple retention states at a particular power level. When exiting WFI, the non-CPU power levels may be in a different retention state to what was initially requested, therefore each CPU should refresh its view of the states of all power levels. Previously, a CPU re-used the state of the power levels when it entered the retention state. This patch fixes this issue by ensuring that a CPU upon exit from retention reads the state of each power level afresh. Change-Id: I93b5f5065c63400c6fd2598dbaafac385748f989
This commit is contained in:
parent
3dd9835f8a
commit
61eae524b6
@ -252,8 +252,8 @@ static plat_local_state_t *psci_get_req_local_pwr_states(unsigned int pwrlvl,
|
||||
* function will be called after a cpu is powered on to find the local state
|
||||
* each power domain has emerged from.
|
||||
*****************************************************************************/
|
||||
static void psci_get_target_local_pwr_states(unsigned int end_pwrlvl,
|
||||
psci_power_state_t *target_state)
|
||||
void psci_get_target_local_pwr_states(unsigned int end_pwrlvl,
|
||||
psci_power_state_t *target_state)
|
||||
{
|
||||
unsigned int parent_idx, lvl;
|
||||
plat_local_state_t *pd_state = target_state->pwr_domain_state;
|
||||
|
@ -192,6 +192,8 @@ int psci_validate_power_state(unsigned int power_state,
|
||||
void psci_query_sys_suspend_pwrstate(psci_power_state_t *state_info);
|
||||
int psci_validate_mpidr(u_register_t mpidr);
|
||||
void psci_init_req_local_pwr_states(void);
|
||||
void psci_get_target_local_pwr_states(unsigned int end_pwrlvl,
|
||||
psci_power_state_t *target_state);
|
||||
int psci_validate_entry_point(entry_point_info_t *ep,
|
||||
uintptr_t entrypoint, u_register_t context_id);
|
||||
void psci_get_parent_pwr_domain_nodes(unsigned int cpu_idx,
|
||||
|
@ -45,17 +45,25 @@
|
||||
* from standby/retention states at multiple power levels.
|
||||
******************************************************************************/
|
||||
static void psci_suspend_to_standby_finisher(unsigned int cpu_idx,
|
||||
psci_power_state_t *state_info,
|
||||
unsigned int end_pwrlvl)
|
||||
{
|
||||
psci_power_state_t state_info;
|
||||
|
||||
psci_acquire_pwr_domain_locks(end_pwrlvl,
|
||||
cpu_idx);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/*
|
||||
* Set the requested and target state of this CPU and all the higher
|
||||
@ -222,7 +230,7 @@ exit:
|
||||
* After we wake up from context retaining suspend, call the
|
||||
* context retaining suspend finisher.
|
||||
*/
|
||||
psci_suspend_to_standby_finisher(idx, state_info, end_pwrlvl);
|
||||
psci_suspend_to_standby_finisher(idx, end_pwrlvl);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
Loading…
x
Reference in New Issue
Block a user