zephyr/lib/os/poweroff.c

15 lines
219 B
C
Raw Normal View History

lib: os: add support for system power off Add a new API to perform an immediate system power off: `sys_poweroff()`. Until now, this functionality has been implemented via the system power management module, but in a clunky fashion. The way system PM works is by defining some idle states in devicetree, that, given some properties (e.g. minimal residency, exit latency, etc.) are automatically selected when system goes to idle based on the expected next wake-up. However, system off is a power state that one typically wants to control manually from the application because it implies state loss, and in most cases, configuring some sort of wake-up source. So in general, it is not desired to let the system enter this state automatically. This led to the following stuff in-tree: from `boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts`: ```c /* * Deep power-down mode is supported in this SoC through * 'PM_STATE_SOFT_OFF' state. There is no entry for this in device tree, * user can call pm_state_force to enter this state. */ ``` That is, state not being defined in devicetree so that PM subsystem doesn't pick it automatically, but still implemented in in the PM hooks: from `soc/arm/nxp_imx/rt5xx/power.c`, `pm_state_set()`: ```c case PM_STATE_SOFT_OFF: set_deepsleep_pin_config(); POWER_EnterDeepPowerDown(EXCLUDE_FROM_DEEP_POWERDOWN); break; ``` And to actually make use of this state, users had to do this kind of abominations: ```c pm_state_force(0u, &(struct pm_state_info){ PM_STATE_SOFT_OFF, 0, 0 }); /* Now we need to go sleep. This will let the idle thread runs and * the pm subsystem will use the forced state. To confirm that the * forced state is used, lets set the same timeout used previously. */ k_sleep(K_SECONDS(SLEEP_S)); printk("ERROR: System off failed\n"); while (true) { /* spin to avoid fall-off behavior */ } ``` Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
2023-07-20 17:46:41 +08:00
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/irq.h>
#include <zephyr/sys/poweroff.h>
void sys_poweroff(void)
{
(void)irq_lock();
z_sys_poweroff();
}