mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-17 01:54:22 +00:00
PSCI: Add pwr_domain_pwr_down_wfi() hook in plat_psci_ops
This patch adds a new optional platform hook `pwr_domain_pwr_down_wfi()` in the plat_psci_ops structure. This hook allows the platform to perform platform specific actions including the wfi invocation to enter powerdown. This hook is invoked by both psci_do_cpu_off() and psci_cpu_suspend_start() functions. The porting-guide.md is also updated for the same. This patch also modifies the `psci_power_down_wfi()` function to invoke `plat_panic_handler` incase of panic instead of the busy while loop. Fixes ARM-Software/tf-issues#375 Change-Id: Iba104469a1445ee8d59fb3a6fdd0a98e7f24dfa3
This commit is contained in:
parent
e141aa0357
commit
ac1cc8eb76
5 changed files with 36 additions and 9 deletions
|
@ -1715,6 +1715,22 @@ latter case, the power domain is expected to save enough state so that it can
|
|||
resume execution by restoring this state when its powered on (see
|
||||
`pwr_domain_suspend_finish()`).
|
||||
|
||||
#### plat_psci_ops.pwr_domain_pwr_down_wfi()
|
||||
|
||||
This is an optional function and, if implemented, is expected to perform
|
||||
platform specific actions including the `wfi` invocation which allows the
|
||||
CPU to powerdown. Since this function is invoked outside the PSCI locks,
|
||||
the actions performed in this hook must be local to the CPU or the platform
|
||||
must ensure that races between multiple CPUs cannot occur.
|
||||
|
||||
The `target_state` has a similar meaning as described in the `pwr_domain_off()`
|
||||
operation and it encodes the platform coordinated target local power states for
|
||||
the CPU power domain and its parent power domain levels. This function must
|
||||
not return back to the caller.
|
||||
|
||||
If this function is not implemented by the platform, PSCI generic
|
||||
implementation invokes `psci_power_down_wfi()` for power down.
|
||||
|
||||
#### plat_psci_ops.pwr_domain_on_finish()
|
||||
|
||||
This function is called by the PSCI implementation after the calling CPU is
|
||||
|
|
|
@ -265,6 +265,8 @@ typedef struct plat_psci_ops {
|
|||
void (*pwr_domain_on_finish)(const psci_power_state_t *target_state);
|
||||
void (*pwr_domain_suspend_finish)(
|
||||
const psci_power_state_t *target_state);
|
||||
void (*pwr_domain_pwr_down_wfi)(
|
||||
const psci_power_state_t *target_state) __dead2;
|
||||
void (*system_off)(void) __dead2;
|
||||
void (*system_reset)(void) __dead2;
|
||||
int (*validate_power_state)(unsigned int power_state,
|
||||
|
|
|
@ -106,7 +106,6 @@ endfunc psci_entrypoint
|
|||
func psci_power_down_wfi
|
||||
dsb sy // ensure write buffer empty
|
||||
wfi
|
||||
wfi_spill:
|
||||
b wfi_spill
|
||||
bl plat_panic_handler
|
||||
endfunc psci_power_down_wfi
|
||||
|
||||
|
|
|
@ -138,11 +138,16 @@ exit:
|
|||
dsbish();
|
||||
inv_cpu_data(psci_svc_cpu_data.aff_info_state);
|
||||
|
||||
/*
|
||||
* Enter a wfi loop which will allow the power controller to
|
||||
* physically power down this cpu.
|
||||
*/
|
||||
psci_power_down_wfi();
|
||||
if (psci_plat_pm_ops->pwr_domain_pwr_down_wfi) {
|
||||
/* This function must not return */
|
||||
psci_plat_pm_ops->pwr_domain_pwr_down_wfi(&state_info);
|
||||
} else {
|
||||
/*
|
||||
* Enter a wfi loop which will allow the power
|
||||
* controller to physically power down this cpu.
|
||||
*/
|
||||
psci_power_down_wfi();
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
|
|
@ -189,8 +189,13 @@ exit:
|
|||
if (skip_wfi)
|
||||
return;
|
||||
|
||||
if (is_power_down_state)
|
||||
psci_power_down_wfi();
|
||||
if (is_power_down_state) {
|
||||
/* The function calls below must not return */
|
||||
if (psci_plat_pm_ops->pwr_domain_pwr_down_wfi)
|
||||
psci_plat_pm_ops->pwr_domain_pwr_down_wfi(state_info);
|
||||
else
|
||||
psci_power_down_wfi();
|
||||
}
|
||||
|
||||
/*
|
||||
* We will reach here if only retention/standby states have been
|
||||
|
|
Loading…
Add table
Reference in a new issue