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 <gerard@teslabs.com>
This commit is contained in:
Gerard Marull-Paretas 2023-07-20 16:24:38 +02:00 committed by Carles Cufí
parent 2e3bc500a9
commit 28c139f653
4 changed files with 22 additions and 21 deletions

View file

@ -17,6 +17,7 @@
#include <zephyr/exc_handle.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/poweroff.h>
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 */

View file

@ -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

View file

@ -21,6 +21,11 @@ LOG_MODULE_REGISTER(psci);
#include <zephyr/drivers/pm_cpu_ops.h>
#include "pm_cpu_ops_psci.h"
#ifdef CONFIG_POWEROFF
#include <zephyr/sys/__assert.h>
#include <zephyr/sys/poweroff.h>
#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

View file

@ -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
*