Commit 86f75c24 authored by Manish Pandey's avatar Manish Pandey Committed by TrustedFirmware Code Review
Browse files

Merge "psci: utility api to invoke stop for other cores" into integration

parents cd62b834 22744909
...@@ -89,6 +89,8 @@ void psci_warmboot_entrypoint(void); ...@@ -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 @@ ...@@ -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) ...@@ -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;
}
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