This can be used to do the necessary preparation in order to wake up a specific core. It calls the platform specific pwr_domain_pwr_down_wfi_wakeup.
Signed-off-by: Abel Vesa abel.vesa@nxp.com --- include/lib/psci/psci.h | 3 +++ lib/psci/psci_main.c | 17 +++++++++++++++++ lib/psci/psci_setup.c | 2 ++ 3 files changed, 22 insertions(+)
diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h index fe279d4..72525d1 100644 --- a/include/lib/psci/psci.h +++ b/include/lib/psci/psci.h @@ -41,7 +41,9 @@ ******************************************************************************/ #define PSCI_VERSION U(0x84000000) #define PSCI_CPU_SUSPEND_AARCH32 U(0x84000001) +#define PSCI_CPU_WAKE_AARCH32 U(0x8400000b) #define PSCI_CPU_SUSPEND_AARCH64 U(0xc4000001) +#define PSCI_CPU_WAKE_AARCH64 U(0xc400000b) #define PSCI_CPU_OFF U(0x84000002) #define PSCI_CPU_ON_AARCH32 U(0x84000003) #define PSCI_CPU_ON_AARCH64 U(0xc4000003) @@ -305,6 +307,7 @@ typedef struct plat_psci_ops { const psci_power_state_t *target_state); void __dead2 (*pwr_domain_pwr_down_wfi)( const psci_power_state_t *target_state); + int (*pwr_domain_pwr_down_wfi_wakeup)(unsigned int index); void __dead2 (*system_off)(void); void __dead2 (*system_reset)(void); int (*validate_power_state)(unsigned int power_state, diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c index 5c0e952..bdf6d46 100644 --- a/lib/psci/psci_main.c +++ b/lib/psci/psci_main.c @@ -51,6 +51,13 @@ unsigned int psci_version(void) return PSCI_MAJOR_VER | PSCI_MINOR_VER; }
+int psci_cpu_wake(unsigned int index) +{ + if (psci_plat_pm_ops->pwr_domain_pwr_down_wfi_wakeup != NULL) + psci_plat_pm_ops->pwr_domain_pwr_down_wfi_wakeup(index); + return 0; +} + int psci_cpu_suspend(unsigned int power_state, uintptr_t entrypoint, u_register_t context_id) @@ -408,6 +415,11 @@ u_register_t psci_smc_handler(uint32_t smc_fid, ret = (u_register_t)psci_cpu_suspend(r1, r2, r3); break;
+ case PSCI_CPU_WAKE_AARCH32: + ret = (u_register_t) + psci_cpu_wake(r1); + break; + case PSCI_CPU_ON_AARCH32: ret = (u_register_t)psci_cpu_on(r1, r2, r3); break; @@ -486,6 +498,11 @@ u_register_t psci_smc_handler(uint32_t smc_fid, psci_cpu_suspend((unsigned int)x1, x2, x3); break;
+ case PSCI_CPU_WAKE_AARCH64: + ret = (u_register_t) + psci_cpu_wake((unsigned int)x1); + break; + case PSCI_CPU_ON_AARCH64: ret = (u_register_t)psci_cpu_on(x1, x2, x3); break; diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c index b9467d3..9c2179e 100644 --- a/lib/psci/psci_setup.c +++ b/lib/psci/psci_setup.c @@ -235,6 +235,8 @@ int __init psci_setup(const psci_lib_args_t *lib_args) if ((psci_plat_pm_ops->pwr_domain_on != NULL) && (psci_plat_pm_ops->pwr_domain_on_finish != NULL)) psci_caps |= define_psci_cap(PSCI_CPU_ON_AARCH64); + if (psci_plat_pm_ops->pwr_domain_pwr_down_wfi_wakeup != NULL) + psci_caps |= define_psci_cap(PSCI_CPU_WAKE_AARCH64); if ((psci_plat_pm_ops->pwr_domain_suspend != NULL) && (psci_plat_pm_ops->pwr_domain_suspend_finish != NULL)) { psci_caps |= define_psci_cap(PSCI_CPU_SUSPEND_AARCH64);