From 28c139f6537be2d254b1e370affcc1110b0f63be Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 20 Jul 2023 16:24:38 +0200 Subject: [PATCH] drivers: pm_cpu_ops: psci: provide sys_poweroff hook Instead of implementing a custom power off API (pm_system_off), implement the sys_poweroff hook, and indicate power off is supported by selecting HAS_POWEROFF. Note that according to the PSCI specification (DEN0022E), the SYSTEM_OFF operation does not return, however, an error is printed and system is halted in case this occurs. Note that the pm_system_off has also been deleted, from now on, systems supporting PSCI should enable CONFIG_POWEROFF and call the standard sys_poweroff() API. Signed-off-by: Gerard Marull-Paretas --- arch/arm64/core/fatal.c | 6 +++++- drivers/pm_cpu_ops/Kconfig | 1 + drivers/pm_cpu_ops/pm_cpu_ops_psci.c | 23 ++++++++++++++++------- include/zephyr/drivers/pm_cpu_ops.h | 13 ------------- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/arch/arm64/core/fatal.c b/arch/arm64/core/fatal.c index f986aa033e6..fb337be5254 100644 --- a/arch/arm64/core/fatal.c +++ b/arch/arm64/core/fatal.c @@ -17,6 +17,7 @@ #include #include #include +#include LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); @@ -350,7 +351,10 @@ FUNC_NORETURN void arch_system_halt(unsigned int reason) ARG_UNUSED(reason); (void)arch_irq_lock(); - (void)pm_system_off(); + +#ifdef CONFIG_POWEROFF + sys_poweroff(); +#endif /* CONFIG_POWEROFF */ for (;;) { /* Spin endlessly as fallback */ diff --git a/drivers/pm_cpu_ops/Kconfig b/drivers/pm_cpu_ops/Kconfig index 712480c1d43..c38c6779fa1 100644 --- a/drivers/pm_cpu_ops/Kconfig +++ b/drivers/pm_cpu_ops/Kconfig @@ -22,6 +22,7 @@ config PM_CPU_OPS_PSCI default y depends on DT_HAS_ARM_PSCI_0_2_ENABLED || DT_HAS_ARM_PSCI_1_1_ENABLED select PM_CPU_OPS_HAS_DRIVER + select HAS_POWEROFF help Say Y here if you want Zephyr to communicate with system firmware implementing the PSCI specification for CPU-centric power diff --git a/drivers/pm_cpu_ops/pm_cpu_ops_psci.c b/drivers/pm_cpu_ops/pm_cpu_ops_psci.c index c110764e0a8..5b9df7858a6 100644 --- a/drivers/pm_cpu_ops/pm_cpu_ops_psci.c +++ b/drivers/pm_cpu_ops/pm_cpu_ops_psci.c @@ -21,6 +21,11 @@ LOG_MODULE_REGISTER(psci); #include #include "pm_cpu_ops_psci.h" +#ifdef CONFIG_POWEROFF +#include +#include +#endif /* CONFIG_POWEROFF */ + /* PSCI data object. */ static struct psci_data_t psci_data; @@ -69,19 +74,23 @@ int pm_cpu_on(unsigned long cpuid, return psci_to_dev_err(ret); } -int pm_system_off(void) +#ifdef CONFIG_POWEROFF +void z_sys_poweroff(void) { int ret; - if (psci_data.conduit == SMCCC_CONDUIT_NONE) { - return -EINVAL; + __ASSERT_NO_MSG(psci_data.conduit != SMCCC_CONDUIT_NONE); + + ret = psci_data.invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0); + if (ret < 0) { + printk("System power off failed (%d) - halting\n", ret); } - /* A compliant PSCI implementation will never return from this call */ - ret = psci_data.invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0); - - return psci_to_dev_err(ret); + for (;;) { + /* wait for power off */ + } } +#endif /* CONFIG_POWEROFF */ /** * This function checks whether the given ID is supported or not, using diff --git a/include/zephyr/drivers/pm_cpu_ops.h b/include/zephyr/drivers/pm_cpu_ops.h index 49ea67e155c..ac69ac52e64 100644 --- a/include/zephyr/drivers/pm_cpu_ops.h +++ b/include/zephyr/drivers/pm_cpu_ops.h @@ -55,19 +55,6 @@ int pm_cpu_off(void); */ int pm_cpu_on(unsigned long cpuid, uintptr_t entry_point); -/** - * @brief Power down the system - * - * This call is used to power down the whole system. - * - * A compliant PSCI implementation will never return, but some real-world - * implementations do return errors in some cases. - * - * @retval does not return on success, a negative errno otherwise - * @retval -ENOTSUP If the operation is not supported - */ -int pm_system_off(void); - /** * @brief System reset *