163 lines
4.0 KiB
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
|
|
|