mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-22 12:34:19 +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
|
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 {
|
||||||
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
|
||||||
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,12 +138,17 @@ 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) {
|
||||||
|
/* 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
|
* Enter a wfi loop which will allow the power
|
||||||
* physically power down this cpu.
|
* controller to physically power down this cpu.
|
||||||
*/
|
*/
|
||||||
psci_power_down_wfi();
|
psci_power_down_wfi();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,8 +189,13 @@ exit:
|
||||||
if (skip_wfi)
|
if (skip_wfi)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (is_power_down_state)
|
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();
|
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
|
||||||
|
|
Loading…
Add table
Reference in a new issue