tobudos-kernel/pm/tos_pm.c

163 lines
4.0 KiB
C

/*----------------------------------------------------------------------------
* Tencent is pleased to support the open source community by making TencentOS
* available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
* If you have downloaded a copy of the TencentOS binary from Tencent, please
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
*
* If you have downloaded a copy of the TencentOS source code from Tencent,
* please note that TencentOS source code is licensed under the BSD 3-Clause
* License, except for the third-party components listed below which are
* subject to different license terms. Your integration of TencentOS into your
* own projects may require compliance with the BSD 3-Clause License, as well
* as the other licenses applicable to the third-party components included
* within TencentOS.
*---------------------------------------------------------------------------*/
#include "tos_k.h"
#if TOS_CFG_PWR_MGR_EN > 0u
#if TOS_CFG_TICKLESS_EN > 0u
__API__ k_err_t tos_pm_cpu_lpwr_mode_set(k_cpu_lpwr_mode_t cpu_lpwr_mode)
{
TOS_CPU_CPSR_ALLOC();
if (cpu_lpwr_mode != TOS_LOW_POWER_MODE_NONE &&
!tickless_wkup_alarm_is_installed(cpu_lpwr_mode)) {
return K_ERR_PM_WKUP_SOURCE_NOT_INSTALL;
}
TOS_CPU_INT_DISABLE();
k_cpu_lpwr_mode = cpu_lpwr_mode;
TOS_CPU_INT_ENABLE();
return K_ERR_NONE;
}
#endif
__STATIC__ int pm_device_is_registered(k_pm_device_t *device)
{
uint8_t i = 0;
for (i = 0; i < k_pm_device_ctl.count; ++i) {
if (strcmp(k_pm_device_ctl.mgr[i]->name, device->name) == 0) {
return 1;
}
}
return 0;
}
__API__ k_err_t tos_pm_device_register(k_pm_device_t *device)
{
TOS_PTR_SANITY_CHECK(device);
if (pm_device_is_registered(device)) {
return K_ERR_PM_DEVICE_ALREADY_REG;
}
if (k_pm_device_ctl.count >= K_PM_DEVICE_MAX_COUNT) {
return K_ERR_PM_DEVICE_OVERFLOW;
}
k_pm_device_ctl.mgr[k_pm_device_ctl.count++] = device;
return K_ERR_NONE;
}
__KNL__ void pm_init(void)
{
memset(&k_pm_device_ctl, 0, sizeof(k_pm_device_ctl));
k_pm_device_ctl.count = 0u;
}
__STATIC_INLINE__ void pm_cpu_sleep_mode_enter(void)
{
cpu_sleep_mode_enter();
}
__STATIC_INLINE__ void pm_cpu_stop_mode_enter(void)
{
cpu_stop_mode_enter();
}
__STATIC_INLINE__ void pm_cpu_standby_mode_enter(void)
{
cpu_standby_mode_enter();
}
__KNL__ void pm_cpu_lpwr_mode_enter(k_cpu_lpwr_mode_t lpwr_mode)
{
if (TOS_LOW_POWER_MODE_SLEEP == lpwr_mode) {
pm_cpu_sleep_mode_enter();
} else if (TOS_LOW_POWER_MODE_STOP == lpwr_mode) {
pm_device_suspend();
pm_cpu_stop_mode_enter();
pm_device_resume();
} else if (TOS_LOW_POWER_MODE_STANDBY == lpwr_mode) {
pm_device_suspend();
pm_cpu_standby_mode_enter();
pm_device_resume();
}
}
__KNL__ k_cpu_lpwr_mode_t pm_cpu_lpwr_mode_get(void)
{
return k_cpu_lpwr_mode;
}
__KNL__ void pm_idle_pwr_mgr_mode_set(idle_pwrmgr_mode_t idle_pwrmgr_mode)
{
k_idle_pwr_mgr_mode = idle_pwrmgr_mode;
}
__KNL__ int pm_idle_pwr_mgr_mode_is_sleep(void)
{
return k_idle_pwr_mgr_mode == IDLE_POWER_MANAGER_MODE_SLEEP;
}
__KNL__ int pm_idle_pwr_mgr_mode_is_tickless(void)
{
return k_idle_pwr_mgr_mode == IDLE_POWER_MANAGER_MODE_TICKLESS;
}
__KNL__ void pm_power_manager(void)
{
if (pm_idle_pwr_mgr_mode_is_sleep()) {
pm_cpu_sleep_mode_enter();
}
#if TOS_CFG_TICKLESS_EN > 0u
else if (pm_idle_pwr_mgr_mode_is_tickless()) {
tickless_proc();
}
#endif
}
__KNL__ int pm_device_suspend(void)
{
uint8_t i = 0;
for (i = 0; i < k_pm_device_ctl.count; ++i) {
if (*k_pm_device_ctl.mgr[i]->suspend) {
(*k_pm_device_ctl.mgr[i]->suspend)();
}
}
return 0;
}
__KNL__ int pm_device_resume(void)
{
uint8_t i = 0;
for (i = 0; i < k_pm_device_ctl.count; ++i) {
if (*k_pm_device_ctl.mgr[i]->resume) {
(*k_pm_device_ctl.mgr[i]->resume)();
}
}
return 0;
}
#endif