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:
parent
2e3bc500a9
commit
28c139f653
4 changed files with 22 additions and 21 deletions
|
@ -17,6 +17,7 @@
|
||||||
#include <zephyr/exc_handle.h>
|
#include <zephyr/exc_handle.h>
|
||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
|
#include <zephyr/sys/poweroff.h>
|
||||||
|
|
||||||
LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL);
|
LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL);
|
||||||
|
|
||||||
|
@ -350,7 +351,10 @@ FUNC_NORETURN void arch_system_halt(unsigned int reason)
|
||||||
ARG_UNUSED(reason);
|
ARG_UNUSED(reason);
|
||||||
|
|
||||||
(void)arch_irq_lock();
|
(void)arch_irq_lock();
|
||||||
(void)pm_system_off();
|
|
||||||
|
#ifdef CONFIG_POWEROFF
|
||||||
|
sys_poweroff();
|
||||||
|
#endif /* CONFIG_POWEROFF */
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* Spin endlessly as fallback */
|
/* Spin endlessly as fallback */
|
||||||
|
|
|
@ -22,6 +22,7 @@ config PM_CPU_OPS_PSCI
|
||||||
default y
|
default y
|
||||||
depends on DT_HAS_ARM_PSCI_0_2_ENABLED || DT_HAS_ARM_PSCI_1_1_ENABLED
|
depends on DT_HAS_ARM_PSCI_0_2_ENABLED || DT_HAS_ARM_PSCI_1_1_ENABLED
|
||||||
select PM_CPU_OPS_HAS_DRIVER
|
select PM_CPU_OPS_HAS_DRIVER
|
||||||
|
select HAS_POWEROFF
|
||||||
help
|
help
|
||||||
Say Y here if you want Zephyr to communicate with system firmware
|
Say Y here if you want Zephyr to communicate with system firmware
|
||||||
implementing the PSCI specification for CPU-centric power
|
implementing the PSCI specification for CPU-centric power
|
||||||
|
|
|
@ -21,6 +21,11 @@ LOG_MODULE_REGISTER(psci);
|
||||||
#include <zephyr/drivers/pm_cpu_ops.h>
|
#include <zephyr/drivers/pm_cpu_ops.h>
|
||||||
#include "pm_cpu_ops_psci.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. */
|
/* PSCI data object. */
|
||||||
static struct psci_data_t psci_data;
|
static struct psci_data_t psci_data;
|
||||||
|
|
||||||
|
@ -69,19 +74,23 @@ int pm_cpu_on(unsigned long cpuid,
|
||||||
return psci_to_dev_err(ret);
|
return psci_to_dev_err(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pm_system_off(void)
|
#ifdef CONFIG_POWEROFF
|
||||||
|
void z_sys_poweroff(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (psci_data.conduit == SMCCC_CONDUIT_NONE) {
|
__ASSERT_NO_MSG(psci_data.conduit != SMCCC_CONDUIT_NONE);
|
||||||
return -EINVAL;
|
|
||||||
|
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 */
|
for (;;) {
|
||||||
ret = psci_data.invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
|
/* wait for power off */
|
||||||
|
}
|
||||||
return psci_to_dev_err(ret);
|
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_POWEROFF */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function checks whether the given ID is supported or not, using
|
* This function checks whether the given ID is supported or not, using
|
||||||
|
|
|
@ -55,19 +55,6 @@ int pm_cpu_off(void);
|
||||||
*/
|
*/
|
||||||
int pm_cpu_on(unsigned long cpuid, uintptr_t entry_point);
|
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
|
* @brief System reset
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue