/* * Copyright (c) 2024 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include LOG_MODULE_DECLARE(pm_device, CONFIG_PM_DEVICE_LOG_LEVEL); #define DT_PM_DEVICE_ENABLED(node_id) \ COND_CODE_1(DT_PROP(node_id, zephyr_pm_device_disabled), \ (), (1 +)) #define DT_PM_DEVICE_NEEDED \ (DT_FOREACH_STATUS_OKAY(zephyr_power_state, DT_PM_DEVICE_ENABLED) 0) #if DT_PM_DEVICE_NEEDED TYPE_SECTION_START_EXTERN(const struct device *, pm_device_slots); /* Number of devices successfully suspended. */ static size_t num_susp; bool pm_suspend_devices(void) { const struct device *devs; size_t devc; devc = z_device_get_all_static(&devs); num_susp = 0; for (const struct device *dev = devs + devc - 1; dev >= devs; dev--) { int ret; /* * Ignore uninitialized devices, busy devices, wake up sources, and * devices with runtime PM enabled. */ if (!device_is_ready(dev) || pm_device_is_busy(dev) || pm_device_wakeup_is_enabled(dev) || pm_device_runtime_is_enabled(dev)) { continue; } ret = pm_device_action_run(dev, PM_DEVICE_ACTION_SUSPEND); /* ignore devices not supporting or already at the given state */ if ((ret == -ENOSYS) || (ret == -ENOTSUP) || (ret == -EALREADY)) { continue; } else if (ret < 0) { LOG_ERR("Device %s did not enter %s state (%d)", dev->name, pm_device_state_str(PM_DEVICE_STATE_SUSPENDED), ret); return false; } TYPE_SECTION_START(pm_device_slots)[num_susp] = dev; num_susp++; } return true; } void pm_resume_devices(void) { for (int i = (num_susp - 1); i >= 0; i--) { pm_device_action_run(TYPE_SECTION_START(pm_device_slots)[i], PM_DEVICE_ACTION_RESUME); } num_susp = 0; } #else /* !DT_PM_DEVICE_NEEDED */ void pm_resume_devices(void) { } bool pm_suspend_devices(void) { return true; } #endif