Commit ac1cc8eb authored by Soby Mathew's avatar Soby Mathew
Browse files

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
parent e141aa03
...@@ -1715,6 +1715,22 @@ latter case, the power domain is expected to save enough state so that it can ...@@ -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 resume execution by restoring this state when its powered on (see
`pwr_domain_suspend_finish()`). `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() #### plat_psci_ops.pwr_domain_on_finish()
This function is called by the PSCI implementation after the calling CPU is This function is called by the PSCI implementation after the calling CPU is
......
...@@ -265,6 +265,8 @@ typedef struct plat_psci_ops { ...@@ -265,6 +265,8 @@ typedef struct plat_psci_ops {
void (*pwr_domain_on_finish)(const psci_power_state_t *target_state); void (*pwr_domain_on_finish)(const psci_power_state_t *target_state);
void (*pwr_domain_suspend_finish)( void (*pwr_domain_suspend_finish)(
const psci_power_state_t *target_state); 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_off)(void) __dead2;
void (*system_reset)(void) __dead2; void (*system_reset)(void) __dead2;
int (*validate_power_state)(unsigned int power_state, int (*validate_power_state)(unsigned int power_state,
......
...@@ -106,7 +106,6 @@ endfunc psci_entrypoint ...@@ -106,7 +106,6 @@ endfunc psci_entrypoint
func psci_power_down_wfi func psci_power_down_wfi
dsb sy // ensure write buffer empty dsb sy // ensure write buffer empty
wfi wfi
wfi_spill: bl plat_panic_handler
b wfi_spill
endfunc psci_power_down_wfi endfunc psci_power_down_wfi
...@@ -138,11 +138,16 @@ exit: ...@@ -138,11 +138,16 @@ exit:
dsbish(); dsbish();
inv_cpu_data(psci_svc_cpu_data.aff_info_state); inv_cpu_data(psci_svc_cpu_data.aff_info_state);
/* if (psci_plat_pm_ops->pwr_domain_pwr_down_wfi) {
* Enter a wfi loop which will allow the power controller to /* This function must not return */
* physically power down this cpu. psci_plat_pm_ops->pwr_domain_pwr_down_wfi(&state_info);
*/ } else {
psci_power_down_wfi(); /*
* Enter a wfi loop which will allow the power
* controller to physically power down this cpu.
*/
psci_power_down_wfi();
}
} }
return rc; return rc;
......
...@@ -189,8 +189,13 @@ exit: ...@@ -189,8 +189,13 @@ exit:
if (skip_wfi) if (skip_wfi)
return; return;
if (is_power_down_state) if (is_power_down_state) {
psci_power_down_wfi(); /* 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 * We will reach here if only retention/standby states have been
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment