Merge "psci: utility api to invoke stop for other cores" into integration
This commit is contained in:
commit
86f75c2492
|
@ -89,6 +89,8 @@ void psci_warmboot_entrypoint(void);
|
||||||
void psci_register_spd_pm_hook(const spd_pm_ops_t *pm);
|
void psci_register_spd_pm_hook(const spd_pm_ops_t *pm);
|
||||||
void psci_prepare_next_non_secure_ctx(
|
void psci_prepare_next_non_secure_ctx(
|
||||||
entry_point_info_t *next_image_info);
|
entry_point_info_t *next_image_info);
|
||||||
|
int psci_stop_other_cores(unsigned int wait_ms,
|
||||||
|
void (*stop_func)(u_register_t mpidr));
|
||||||
#endif /* __ASSEMBLER__ */
|
#endif /* __ASSEMBLER__ */
|
||||||
|
|
||||||
#endif /* PSCI_LIB_H */
|
#endif /* PSCI_LIB_H */
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <common/bl_common.h>
|
#include <common/bl_common.h>
|
||||||
#include <common/debug.h>
|
#include <common/debug.h>
|
||||||
#include <context.h>
|
#include <context.h>
|
||||||
|
#include <drivers/delay_timer.h>
|
||||||
#include <lib/el3_runtime/context_mgmt.h>
|
#include <lib/el3_runtime/context_mgmt.h>
|
||||||
#include <lib/utils.h>
|
#include <lib/utils.h>
|
||||||
#include <plat/common/platform.h>
|
#include <plat/common/platform.h>
|
||||||
|
@ -973,3 +974,49 @@ void psci_do_pwrdown_sequence(unsigned int power_level)
|
||||||
psci_do_pwrdown_cache_maintenance(power_level);
|
psci_do_pwrdown_cache_maintenance(power_level);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* This function invokes the callback 'stop_func()' with the 'mpidr' of each
|
||||||
|
* online PE. Caller can pass suitable method to stop a remote core.
|
||||||
|
*
|
||||||
|
* 'wait_ms' is the timeout value in milliseconds for the other cores to
|
||||||
|
* transition to power down state. Passing '0' makes it non-blocking.
|
||||||
|
*
|
||||||
|
* The function returns 'PSCI_E_DENIED' if some cores failed to stop within the
|
||||||
|
* given timeout.
|
||||||
|
******************************************************************************/
|
||||||
|
int psci_stop_other_cores(unsigned int wait_ms,
|
||||||
|
void (*stop_func)(u_register_t mpidr))
|
||||||
|
{
|
||||||
|
unsigned int idx, this_cpu_idx;
|
||||||
|
|
||||||
|
this_cpu_idx = plat_my_core_pos();
|
||||||
|
|
||||||
|
/* Invoke stop_func for each core */
|
||||||
|
for (idx = 0U; idx < psci_plat_core_count; idx++) {
|
||||||
|
/* skip current CPU */
|
||||||
|
if (idx == this_cpu_idx) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the CPU is ON */
|
||||||
|
if (psci_get_aff_info_state_by_idx(idx) == AFF_STATE_ON) {
|
||||||
|
(*stop_func)(psci_cpu_pd_nodes[idx].mpidr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Need to wait for other cores to shutdown */
|
||||||
|
if (wait_ms != 0U) {
|
||||||
|
while ((wait_ms-- != 0U) && (psci_is_last_on_cpu() != 0U)) {
|
||||||
|
mdelay(1U);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (psci_is_last_on_cpu() != 0U) {
|
||||||
|
WARN("Failed to stop all cores!\n");
|
||||||
|
psci_print_power_domain_map();
|
||||||
|
return PSCI_E_DENIED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PSCI_E_SUCCESS;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue