feat: 支持L1 低功耗框架
方案描述: 和L0保持一致,上层通过proc文件系统操作: power_mode 支持的低功耗模式,通过对该文件进行write操作可以设置低功耗模式 power_count powermanager模块通过对该文件操作,和内核进行交互,简要流程如下: while (1) { open // 打开该文件 read // 使powermanager低功耗任务常阻塞,当系统无任何模块持锁时,会唤醒该任务 write // 进行低功耗流程 close // 关闭该文件 } power_lock write该文件,持锁 power_unlock writw该文件,释放锁 Close #I4JSO Change-Id: I73fcdeeb5e2039484b3351a81b46a0892b349fe9 Signed-off-by: zhushengle <zhushengle@huawei.com>
This commit is contained in:
parent
3e7cfaa520
commit
64e49aba7c
|
@ -76,22 +76,33 @@ static int PowerModeWrite(struct ProcFile *pf, const char *buf, size_t count, lo
|
||||||
(void)count;
|
(void)count;
|
||||||
(void)ppos;
|
(void)ppos;
|
||||||
|
|
||||||
|
LOS_SysSleepEnum mode;
|
||||||
|
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(buf, "normal") != 0) {
|
if (strcmp(buf, "normal") == 0) {
|
||||||
return LOS_NOK;
|
mode = LOS_SYS_NORMAL_SLEEP;
|
||||||
|
} else if (strcmp(buf, "light") == 0) {
|
||||||
|
mode = LOS_SYS_LIGHT_SLEEP;
|
||||||
|
} else if (strcmp(buf, "deep") == 0) {
|
||||||
|
mode = LOS_SYS_DEEP_SLEEP;
|
||||||
|
} else if (strcmp(buf, "shutdown") == 0) {
|
||||||
|
mode = LOS_SYS_SHUTDOWN;
|
||||||
|
} else {
|
||||||
|
PRINT_ERR("Unsupported hibernation mode: %s\n", buf);
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return -LOS_PmModeSet(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int PowerModeRead(struct SeqBuf *m, void *v)
|
static int PowerModeRead(struct SeqBuf *m, void *v)
|
||||||
{
|
{
|
||||||
(void)v;
|
(void)v;
|
||||||
|
|
||||||
LosBufPrintf(m, "normal \n");
|
LosBufPrintf(m, "normal light deep shutdown\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,14 +114,30 @@ static const struct ProcFileOperations PowerMode = {
|
||||||
static int PowerCountRead(struct SeqBuf *m, void *v)
|
static int PowerCountRead(struct SeqBuf *m, void *v)
|
||||||
{
|
{
|
||||||
(void)v;
|
(void)v;
|
||||||
UINT32 count = LOS_PmLockCountGet();
|
UINT32 count = LOS_PmReadLock();
|
||||||
|
|
||||||
LosBufPrintf(m, "%u\n", count);
|
LosBufPrintf(m, "%u\n", count);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int PowerCountWrite(struct ProcFile *pf, const char *buf, size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
(void)pf;
|
||||||
|
(void)count;
|
||||||
|
(void)ppos;
|
||||||
|
|
||||||
|
int weakCount;
|
||||||
|
|
||||||
|
if (buf == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
weakCount = atoi(buf);
|
||||||
|
return -LOS_PmSuspend(weakCount);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct ProcFileOperations PowerCount = {
|
static const struct ProcFileOperations PowerCount = {
|
||||||
.write = NULL,
|
.write = PowerCountWrite,
|
||||||
.read = PowerCountRead,
|
.read = PowerCountRead,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -78,10 +78,6 @@ LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_taskSpin);
|
||||||
STATIC VOID OsConsoleIDSetHook(UINT32 param1,
|
STATIC VOID OsConsoleIDSetHook(UINT32 param1,
|
||||||
UINT32 param2) __attribute__((weakref("OsSetConsoleID")));
|
UINT32 param2) __attribute__((weakref("OsSetConsoleID")));
|
||||||
|
|
||||||
#define OS_CHECK_TASK_BLOCK (OS_TASK_STATUS_DELAY | \
|
|
||||||
OS_TASK_STATUS_PENDING | \
|
|
||||||
OS_TASK_STATUS_SUSPENDED)
|
|
||||||
|
|
||||||
/* temp task blocks for booting procedure */
|
/* temp task blocks for booting procedure */
|
||||||
LITE_OS_SEC_BSS STATIC LosTaskCB g_mainTask[LOSCFG_KERNEL_CORE_NUM];
|
LITE_OS_SEC_BSS STATIC LosTaskCB g_mainTask[LOSCFG_KERNEL_CORE_NUM];
|
||||||
|
|
||||||
|
@ -736,7 +732,6 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID)
|
||||||
UINT32 intSave;
|
UINT32 intSave;
|
||||||
UINT32 errRet;
|
UINT32 errRet;
|
||||||
LosTaskCB *taskCB = NULL;
|
LosTaskCB *taskCB = NULL;
|
||||||
BOOL needSched = FALSE;
|
|
||||||
|
|
||||||
if (OS_TID_CHECK_INVALID(taskID)) {
|
if (OS_TID_CHECK_INVALID(taskID)) {
|
||||||
return LOS_ERRNO_TSK_ID_INVALID;
|
return LOS_ERRNO_TSK_ID_INVALID;
|
||||||
|
@ -756,17 +751,11 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID)
|
||||||
OS_GOTO_ERREND();
|
OS_GOTO_ERREND();
|
||||||
}
|
}
|
||||||
|
|
||||||
taskCB->taskStatus &= ~OS_TASK_STATUS_SUSPENDED;
|
BOOL needSched = OsSchedResume(taskCB);
|
||||||
if (!(taskCB->taskStatus & OS_CHECK_TASK_BLOCK)) {
|
|
||||||
OsSchedTaskEnQueue(taskCB);
|
|
||||||
if (OS_SCHEDULER_ACTIVE) {
|
|
||||||
needSched = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SCHEDULER_UNLOCK(intSave);
|
SCHEDULER_UNLOCK(intSave);
|
||||||
|
|
||||||
LOS_MpSchedule(OS_MP_CPU_ALL);
|
LOS_MpSchedule(OS_MP_CPU_ALL);
|
||||||
if (needSched) {
|
if (OS_SCHEDULER_ACTIVE && needSched) {
|
||||||
LOS_Schedule();
|
LOS_Schedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -834,16 +823,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsTaskSuspend(LosTaskCB *taskCB)
|
||||||
return errRet;
|
return errRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tempStatus & OS_TASK_STATUS_READY) {
|
OsSchedSuspend(taskCB);
|
||||||
OsSchedTaskDeQueue(taskCB);
|
|
||||||
}
|
|
||||||
|
|
||||||
taskCB->taskStatus |= OS_TASK_STATUS_SUSPENDED;
|
|
||||||
OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTOSUSPENDEDLIST, taskCB);
|
|
||||||
if (taskCB == OsCurrTaskGet()) {
|
|
||||||
OsSchedResched();
|
|
||||||
}
|
|
||||||
|
|
||||||
return LOS_OK;
|
return LOS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -162,6 +162,8 @@ extern VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask);
|
||||||
|
|
||||||
extern UINT32 OsSchedSwtmrScanRegister(SchedScan func);
|
extern UINT32 OsSchedSwtmrScanRegister(SchedScan func);
|
||||||
|
|
||||||
|
extern VOID OsSchedResetSchedResponseTime(UINT64 responseTime);
|
||||||
|
|
||||||
extern VOID OsSchedUpdateExpireTime(UINT64 startTime);
|
extern VOID OsSchedUpdateExpireTime(UINT64 startTime);
|
||||||
|
|
||||||
extern VOID OsSchedToUserReleaseLock(VOID);
|
extern VOID OsSchedToUserReleaseLock(VOID);
|
||||||
|
@ -178,6 +180,10 @@ extern BOOL OsSchedModifyTaskSchedParam(LosTaskCB *taskCB, UINT16 policy, UINT16
|
||||||
|
|
||||||
extern BOOL OsSchedModifyProcessSchedParam(LosProcessCB *processCB, UINT16 policy, UINT16 priority);
|
extern BOOL OsSchedModifyProcessSchedParam(LosProcessCB *processCB, UINT16 policy, UINT16 priority);
|
||||||
|
|
||||||
|
extern VOID OsSchedSuspend(LosTaskCB *taskCB);
|
||||||
|
|
||||||
|
extern BOOL OsSchedResume(LosTaskCB *taskCB);
|
||||||
|
|
||||||
extern VOID OsSchedDelay(LosTaskCB *runTask, UINT32 tick);
|
extern VOID OsSchedDelay(LosTaskCB *runTask, UINT32 tick);
|
||||||
|
|
||||||
extern VOID OsSchedYield(VOID);
|
extern VOID OsSchedYield(VOID);
|
||||||
|
|
|
@ -210,6 +210,14 @@ extern SPIN_LOCK_S g_taskSpin;
|
||||||
*/
|
*/
|
||||||
#define OS_TASK_FLAG_EXIT_KILL 0x4000U
|
#define OS_TASK_FLAG_EXIT_KILL 0x4000U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup los_task
|
||||||
|
* Flag that indicates the task or task control block status.
|
||||||
|
*
|
||||||
|
* The delayed operation of this task is frozen.
|
||||||
|
*/
|
||||||
|
#define OS_TASK_FLAG_FREEZE 0x8000U
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup los_task
|
* @ingroup los_task
|
||||||
* Flag that indicates the task property.
|
* Flag that indicates the task property.
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#ifdef LOSCFG_SCHED_DEBUG
|
#ifdef LOSCFG_SCHED_DEBUG
|
||||||
#include "los_stat_pri.h"
|
#include "los_stat_pri.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "los_pm_pri.h"
|
||||||
|
|
||||||
#define OS_32BIT_MAX 0xFFFFFFFFUL
|
#define OS_32BIT_MAX 0xFFFFFFFFUL
|
||||||
#define OS_SCHED_FIFO_TIMEOUT 0x7FFFFFFF
|
#define OS_SCHED_FIFO_TIMEOUT 0x7FFFFFFF
|
||||||
|
@ -58,6 +59,8 @@
|
||||||
#define OS_SCHED_READY_MAX 30
|
#define OS_SCHED_READY_MAX 30
|
||||||
#define OS_TIME_SLICE_MIN (INT32)((50 * OS_SYS_NS_PER_US) / OS_NS_PER_CYCLE) /* 50us */
|
#define OS_TIME_SLICE_MIN (INT32)((50 * OS_SYS_NS_PER_US) / OS_NS_PER_CYCLE) /* 50us */
|
||||||
|
|
||||||
|
#define OS_CHECK_TASK_BLOCK (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PENDING | OS_TASK_STATUS_SUSPENDED)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
LOS_DL_LIST priQueueList[OS_PRIORITY_QUEUE_NUM];
|
LOS_DL_LIST priQueueList[OS_PRIORITY_QUEUE_NUM];
|
||||||
UINT32 readyTasks[OS_PRIORITY_QUEUE_NUM];
|
UINT32 readyTasks[OS_PRIORITY_QUEUE_NUM];
|
||||||
|
@ -760,6 +763,81 @@ BOOL OsSchedModifyProcessSchedParam(LosProcessCB *processCB, UINT16 policy, UINT
|
||||||
return needSched;
|
return needSched;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC VOID OsSchedFreezeTask(LosTaskCB *taskCB)
|
||||||
|
{
|
||||||
|
UINT64 responseTime;
|
||||||
|
|
||||||
|
if (!OsIsPmMode()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(taskCB->taskStatus & (OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
responseTime = GET_SORTLIST_VALUE(&taskCB->sortList);
|
||||||
|
OsDeleteSortLink(&taskCB->sortList, OS_SORT_LINK_TASK);
|
||||||
|
SET_SORTLIST_VALUE(&taskCB->sortList, responseTime);
|
||||||
|
taskCB->taskStatus |= OS_TASK_FLAG_FREEZE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC VOID OsSchedUnfreezeTask(LosTaskCB *taskCB)
|
||||||
|
{
|
||||||
|
UINT64 currTime, responseTime;
|
||||||
|
UINT32 remainTick;
|
||||||
|
|
||||||
|
if (!(taskCB->taskStatus & OS_TASK_FLAG_FREEZE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
taskCB->taskStatus &= ~OS_TASK_FLAG_FREEZE;
|
||||||
|
currTime = OsGetCurrSchedTimeCycle();
|
||||||
|
responseTime = GET_SORTLIST_VALUE(&taskCB->sortList);
|
||||||
|
if (responseTime > currTime) {
|
||||||
|
remainTick = ((responseTime - currTime) + OS_CYCLE_PER_TICK - 1) / OS_CYCLE_PER_TICK;
|
||||||
|
OsAdd2SortLink(&taskCB->sortList, currTime, remainTick, OS_SORT_LINK_TASK);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SET_SORTLIST_VALUE(&taskCB->sortList, OS_SORT_LINK_INVALID_TIME);
|
||||||
|
if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) {
|
||||||
|
LOS_ListDelete(&taskCB->pendList);
|
||||||
|
}
|
||||||
|
taskCB->taskStatus &= ~(OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_PENDING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID OsSchedSuspend(LosTaskCB *taskCB)
|
||||||
|
{
|
||||||
|
if (taskCB->taskStatus & OS_TASK_STATUS_READY) {
|
||||||
|
OsSchedTaskDeQueue(taskCB);
|
||||||
|
}
|
||||||
|
|
||||||
|
OsSchedFreezeTask(taskCB);
|
||||||
|
|
||||||
|
taskCB->taskStatus |= OS_TASK_STATUS_SUSPENDED;
|
||||||
|
OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTOSUSPENDEDLIST, taskCB);
|
||||||
|
if (taskCB == OsCurrTaskGet()) {
|
||||||
|
OsSchedResched();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL OsSchedResume(LosTaskCB *taskCB)
|
||||||
|
{
|
||||||
|
BOOL needSched = FALSE;
|
||||||
|
|
||||||
|
OsSchedUnfreezeTask(taskCB);
|
||||||
|
|
||||||
|
taskCB->taskStatus &= ~OS_TASK_STATUS_SUSPENDED;
|
||||||
|
if (!(taskCB->taskStatus & OS_CHECK_TASK_BLOCK)) {
|
||||||
|
OsSchedTaskEnQueue(taskCB);
|
||||||
|
needSched = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return needSched;
|
||||||
|
}
|
||||||
|
|
||||||
VOID OsSchedTick(VOID)
|
VOID OsSchedTick(VOID)
|
||||||
{
|
{
|
||||||
Sched *sched = g_sched;
|
Sched *sched = g_sched;
|
||||||
|
@ -792,6 +870,12 @@ VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask)
|
||||||
OsSchedTaskEnQueue(idleTask);
|
OsSchedTaskEnQueue(idleTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID OsSchedResetSchedResponseTime(UINT64 responseTime)
|
||||||
|
{
|
||||||
|
Percpu *cpu = OsPercpuGet();
|
||||||
|
cpu->responseTime = responseTime;
|
||||||
|
}
|
||||||
|
|
||||||
UINT32 OsSchedSwtmrScanRegister(SchedScan func)
|
UINT32 OsSchedSwtmrScanRegister(SchedScan func)
|
||||||
{
|
{
|
||||||
if (func == NULL) {
|
if (func == NULL) {
|
||||||
|
|
|
@ -61,5 +61,6 @@ config("public") {
|
||||||
"vdso:public",
|
"vdso:public",
|
||||||
"perf:public",
|
"perf:public",
|
||||||
"lms:public",
|
"lms:public",
|
||||||
|
"power:public",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,3 +34,7 @@ module_name = get_path_info(rebase_path("."), "name")
|
||||||
kernel_module(module_name) {
|
kernel_module(module_name) {
|
||||||
sources = [ "los_pm.c" ]
|
sources = [ "los_pm.c" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config("public") {
|
||||||
|
include_dirs = [ "." ]
|
||||||
|
}
|
||||||
|
|
|
@ -35,8 +35,11 @@
|
||||||
#include "los_init.h"
|
#include "los_init.h"
|
||||||
#include "los_memory.h"
|
#include "los_memory.h"
|
||||||
#include "los_spinlock.h"
|
#include "los_spinlock.h"
|
||||||
|
#include "los_swtmr.h"
|
||||||
#include "los_mp.h"
|
#include "los_mp.h"
|
||||||
|
|
||||||
|
#define OS_MS_PER_TICK (OS_SYS_MS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND)
|
||||||
|
|
||||||
#ifdef LOSCFG_KERNEL_PM
|
#ifdef LOSCFG_KERNEL_PM
|
||||||
#define PM_INFO_SHOW(seqBuf, arg...) do { \
|
#define PM_INFO_SHOW(seqBuf, arg...) do { \
|
||||||
if (seqBuf != NULL) { \
|
if (seqBuf != NULL) { \
|
||||||
|
@ -46,38 +49,342 @@
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define OS_PM_LOCK_MAX 0xFFFFU
|
#define OS_PM_LOCK_MAX 0xFFFFU
|
||||||
#define OS_PM_LOCK_NAME_MAX 28
|
#define OS_PM_LOCK_NAME_MAX 28
|
||||||
|
#define OS_PM_SYS_EARLY 1
|
||||||
|
#define OS_PM_SYS_DEVICE_EARLY 2
|
||||||
|
|
||||||
typedef UINT32 (*Suspend)(VOID);
|
typedef UINT32 (*SysSuspend)(VOID);
|
||||||
|
typedef UINT32 (*Suspend)(UINT32 mode);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
CHAR name[OS_PM_LOCK_NAME_MAX];
|
CHAR name[OS_PM_LOCK_NAME_MAX];
|
||||||
UINT32 count;
|
UINT32 count;
|
||||||
|
UINT32 swtmrID;
|
||||||
LOS_DL_LIST list;
|
LOS_DL_LIST list;
|
||||||
} OsPmLockCB;
|
} OsPmLockCB;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
LOS_SysSleepEnum mode;
|
LOS_SysSleepEnum pmMode;
|
||||||
|
LOS_SysSleepEnum sysMode;
|
||||||
UINT16 lock;
|
UINT16 lock;
|
||||||
|
BOOL isWake;
|
||||||
|
LosPmDevice *device;
|
||||||
|
LosPmSysctrl *sysctrl;
|
||||||
|
UINT64 enterSleepTime;
|
||||||
LOS_DL_LIST lockList;
|
LOS_DL_LIST lockList;
|
||||||
} LosPmCB;
|
} LosPmCB;
|
||||||
|
|
||||||
|
#define PM_EVENT_LOCK_MASK 0xF
|
||||||
|
#define PM_EVENT_LOCK_RELEASE 0x1
|
||||||
|
STATIC EVENT_CB_S g_pmEvent;
|
||||||
STATIC LosPmCB g_pmCB;
|
STATIC LosPmCB g_pmCB;
|
||||||
STATIC SPIN_LOCK_INIT(g_pmSpin);
|
STATIC SPIN_LOCK_INIT(g_pmSpin);
|
||||||
|
|
||||||
|
STATIC VOID OsPmTickTimerStart(LosPmCB *pm)
|
||||||
|
{
|
||||||
|
(VOID)pm;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC BOOL OsPmTickTimerStop(LosPmCB *pm)
|
||||||
|
{
|
||||||
|
(VOID)pm;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC VOID OsPmCpuResume(LosPmCB *pm)
|
||||||
|
{
|
||||||
|
if ((pm->sysMode == LOS_SYS_NORMAL_SLEEP) && (pm->sysctrl->normalResume != NULL)) {
|
||||||
|
pm->sysctrl->normalResume();
|
||||||
|
} else if ((pm->sysMode == LOS_SYS_LIGHT_SLEEP) && (pm->sysctrl->lightResume != NULL)) {
|
||||||
|
pm->sysctrl->lightResume();
|
||||||
|
} else if ((pm->sysMode == LOS_SYS_DEEP_SLEEP) && (pm->sysctrl->deepResume != NULL)) {
|
||||||
|
pm->sysctrl->deepResume();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC SysSuspend OsPmCpuSuspend(LosPmCB *pm)
|
||||||
|
{
|
||||||
|
SysSuspend sysSuspend = NULL;
|
||||||
|
|
||||||
|
/* cpu enter low power mode */
|
||||||
|
LOS_ASSERT(pm->sysctrl != NULL);
|
||||||
|
|
||||||
|
if (pm->sysMode == LOS_SYS_NORMAL_SLEEP) {
|
||||||
|
sysSuspend = pm->sysctrl->normalSuspend;
|
||||||
|
} else if (pm->sysMode == LOS_SYS_LIGHT_SLEEP) {
|
||||||
|
sysSuspend = pm->sysctrl->lightSuspend;
|
||||||
|
} else if (pm->sysMode == LOS_SYS_DEEP_SLEEP) {
|
||||||
|
sysSuspend = pm->sysctrl->deepSuspend;
|
||||||
|
} else {
|
||||||
|
sysSuspend = pm->sysctrl->shutdownSuspend;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOS_ASSERT(sysSuspend != NULL);
|
||||||
|
|
||||||
|
return sysSuspend;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC VOID OsPmResumePrepare(LosPmCB *pm, UINT32 mode, UINT32 prepare)
|
||||||
|
{
|
||||||
|
if ((prepare == 0) && (pm->device->resume != NULL)) {
|
||||||
|
pm->device->resume(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((prepare == 0) || (prepare == OS_PM_SYS_DEVICE_EARLY)) && (pm->sysctrl->late != NULL)) {
|
||||||
|
pm->sysctrl->late(mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC UINT32 OsPmSuspendPrepare(Suspend sysSuspendEarly, Suspend deviceSuspend, UINT32 mode, UINT32 *prepare)
|
||||||
|
{
|
||||||
|
UINT32 ret;
|
||||||
|
|
||||||
|
if (sysSuspendEarly != NULL) {
|
||||||
|
ret = sysSuspendEarly(mode);
|
||||||
|
if (ret != LOS_OK) {
|
||||||
|
*prepare = OS_PM_SYS_EARLY;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deviceSuspend != NULL) {
|
||||||
|
ret = deviceSuspend(mode);
|
||||||
|
if (ret != LOS_OK) {
|
||||||
|
*prepare = OS_PM_SYS_DEVICE_EARLY;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return LOS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC UINT32 OsPmSuspendCheck(LosPmCB *pm, Suspend *sysSuspendEarly, Suspend *deviceSuspend, LOS_SysSleepEnum *mode)
|
||||||
|
{
|
||||||
|
LOS_SpinLock(&g_pmSpin);
|
||||||
|
pm->sysMode = pm->pmMode;
|
||||||
|
if (pm->lock > 0) {
|
||||||
|
pm->sysMode = LOS_SYS_NORMAL_SLEEP;
|
||||||
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
|
return LOS_NOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
pm->isWake = FALSE;
|
||||||
|
*mode = pm->sysMode;
|
||||||
|
*sysSuspendEarly = pm->sysctrl->early;
|
||||||
|
*deviceSuspend = pm->device->suspend;
|
||||||
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
|
return LOS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC UINT32 OsPmSuspendSleep(LosPmCB *pm)
|
||||||
|
{
|
||||||
|
UINT32 ret, intSave;
|
||||||
|
Suspend sysSuspendEarly, deviceSuspend;
|
||||||
|
LOS_SysSleepEnum mode;
|
||||||
|
UINT32 prepare = 0;
|
||||||
|
BOOL tickTimerStop = FALSE;
|
||||||
|
SysSuspend sysSuspend;
|
||||||
|
UINT64 currTime;
|
||||||
|
|
||||||
|
ret = OsPmSuspendCheck(pm, &sysSuspendEarly, &deviceSuspend, &mode);
|
||||||
|
if (ret != LOS_OK) {
|
||||||
|
PRINT_ERR("Pm suspend mode is normal sleep! lock count %d\n", pm->lock);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = OsPmSuspendPrepare(sysSuspendEarly, deviceSuspend, (UINT32)mode, &prepare);
|
||||||
|
if (ret != LOS_OK) {
|
||||||
|
LOS_SpinLockSave(&g_pmSpin, &intSave);
|
||||||
|
LOS_TaskLock();
|
||||||
|
goto EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOS_SpinLockSave(&g_pmSpin, &intSave);
|
||||||
|
LOS_TaskLock();
|
||||||
|
if (pm->isWake || (pm->lock > 0)) {
|
||||||
|
goto EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
tickTimerStop = OsPmTickTimerStop(pm);
|
||||||
|
if (!tickTimerStop) {
|
||||||
|
currTime = OsGetCurrSchedTimeCycle();
|
||||||
|
OsSchedResetSchedResponseTime(0);
|
||||||
|
OsSchedUpdateExpireTime(currTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
sysSuspend = OsPmCpuSuspend(pm);
|
||||||
|
LOS_SpinUnlockRestore(&g_pmSpin, intSave);
|
||||||
|
|
||||||
|
if (!pm->isWake) {
|
||||||
|
ret = sysSuspend();
|
||||||
|
}
|
||||||
|
|
||||||
|
LOS_SpinLockSave(&g_pmSpin, &intSave);
|
||||||
|
|
||||||
|
OsPmCpuResume(pm);
|
||||||
|
|
||||||
|
OsPmTickTimerStart(pm);
|
||||||
|
|
||||||
|
EXIT:
|
||||||
|
pm->sysMode = LOS_SYS_NORMAL_SLEEP;
|
||||||
|
OsPmResumePrepare(pm, (UINT32)mode, prepare);
|
||||||
|
LOS_SpinUnlockRestore(&g_pmSpin, intSave);
|
||||||
|
|
||||||
|
LOS_TaskUnlock();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC UINT32 OsPmDeviceRegister(LosPmCB *pm, LosPmDevice *device)
|
||||||
|
{
|
||||||
|
if ((device->suspend == NULL) || (device->resume == NULL)) {
|
||||||
|
return LOS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOS_SpinLock(&g_pmSpin);
|
||||||
|
pm->device = device;
|
||||||
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
|
|
||||||
|
return LOS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC UINT32 OsPmSysctrlRegister(LosPmCB *pm, LosPmSysctrl *sysctrl)
|
||||||
|
{
|
||||||
|
LOS_SpinLock(&g_pmSpin);
|
||||||
|
pm->sysctrl = sysctrl;
|
||||||
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
|
|
||||||
|
return LOS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 LOS_PmRegister(LOS_PmNodeType type, VOID *node)
|
||||||
|
{
|
||||||
|
LosPmCB *pm = &g_pmCB;
|
||||||
|
|
||||||
|
if (node == NULL) {
|
||||||
|
return LOS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case LOS_PM_TYPE_DEVICE:
|
||||||
|
return OsPmDeviceRegister(pm, (LosPmDevice *)node);
|
||||||
|
case LOS_PM_TYPE_TICK_TIMER:
|
||||||
|
PRINT_ERR("Pm, %d is an unsupported type\n", type);
|
||||||
|
return LOS_EINVAL;
|
||||||
|
case LOS_PM_TYPE_SYSCTRL:
|
||||||
|
return OsPmSysctrlRegister(pm, (LosPmSysctrl *)node);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return LOS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC UINT32 OsPmDeviceUnregister(LosPmCB *pm, LosPmDevice *device)
|
||||||
|
{
|
||||||
|
LOS_SpinLock(&g_pmSpin);
|
||||||
|
if (pm->device == device) {
|
||||||
|
pm->device = NULL;
|
||||||
|
pm->pmMode = LOS_SYS_NORMAL_SLEEP;
|
||||||
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
|
return LOS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
|
return LOS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC UINT32 OsPmSysctrlUnregister(LosPmCB *pm, LosPmSysctrl *sysctrl)
|
||||||
|
{
|
||||||
|
LOS_SpinLock(&g_pmSpin);
|
||||||
|
pm->sysctrl = NULL;
|
||||||
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
|
|
||||||
|
return LOS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 LOS_PmUnregister(LOS_PmNodeType type, VOID *node)
|
||||||
|
{
|
||||||
|
LosPmCB *pm = &g_pmCB;
|
||||||
|
|
||||||
|
if (node == NULL) {
|
||||||
|
return LOS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case LOS_PM_TYPE_DEVICE:
|
||||||
|
return OsPmDeviceUnregister(pm, (LosPmDevice *)node);
|
||||||
|
case LOS_PM_TYPE_TICK_TIMER:
|
||||||
|
PRINT_ERR("Pm, %d is an unsupported type\n", type);
|
||||||
|
return LOS_EINVAL;
|
||||||
|
case LOS_PM_TYPE_SYSCTRL:
|
||||||
|
return OsPmSysctrlUnregister(pm, (LosPmSysctrl *)node);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return LOS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID LOS_PmWakeSet(VOID)
|
||||||
|
{
|
||||||
|
LosPmCB *pm = &g_pmCB;
|
||||||
|
|
||||||
|
LOS_SpinLock(&g_pmSpin);
|
||||||
|
pm->isWake = TRUE;
|
||||||
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
LOS_SysSleepEnum LOS_PmModeGet(VOID)
|
LOS_SysSleepEnum LOS_PmModeGet(VOID)
|
||||||
{
|
{
|
||||||
LOS_SysSleepEnum mode;
|
LOS_SysSleepEnum mode;
|
||||||
LosPmCB *pm = &g_pmCB;
|
LosPmCB *pm = &g_pmCB;
|
||||||
|
|
||||||
LOS_SpinLock(&g_pmSpin);
|
LOS_SpinLock(&g_pmSpin);
|
||||||
mode = pm->mode;
|
mode = pm->pmMode;
|
||||||
LOS_SpinUnlock(&g_pmSpin);
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
|
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT32 LOS_PmModeSet(LOS_SysSleepEnum mode)
|
||||||
|
{
|
||||||
|
LosPmCB *pm = &g_pmCB;
|
||||||
|
INT32 sleepMode = (INT32)mode;
|
||||||
|
|
||||||
|
if ((sleepMode < 0) || (sleepMode > LOS_SYS_SHUTDOWN)) {
|
||||||
|
return LOS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOS_SpinLock(&g_pmSpin);
|
||||||
|
if ((mode != LOS_SYS_NORMAL_SLEEP) && (pm->device == NULL)) {
|
||||||
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
|
return LOS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mode == LOS_SYS_LIGHT_SLEEP) && (pm->sysctrl->lightSuspend == NULL)) {
|
||||||
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
|
return LOS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mode == LOS_SYS_DEEP_SLEEP) && (pm->sysctrl->deepSuspend == NULL)) {
|
||||||
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
|
return LOS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mode == LOS_SYS_SHUTDOWN) && (pm->sysctrl->shutdownSuspend == NULL)) {
|
||||||
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
|
return LOS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pm->pmMode = mode;
|
||||||
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
|
|
||||||
|
return LOS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
UINT32 LOS_PmLockCountGet(VOID)
|
UINT32 LOS_PmLockCountGet(VOID)
|
||||||
{
|
{
|
||||||
UINT16 count;
|
UINT16 count;
|
||||||
|
@ -92,43 +399,38 @@ UINT32 LOS_PmLockCountGet(VOID)
|
||||||
|
|
||||||
VOID LOS_PmLockInfoShow(struct SeqBuf *m)
|
VOID LOS_PmLockInfoShow(struct SeqBuf *m)
|
||||||
{
|
{
|
||||||
UINT32 intSave;
|
|
||||||
LosPmCB *pm = &g_pmCB;
|
LosPmCB *pm = &g_pmCB;
|
||||||
OsPmLockCB *lock = NULL;
|
OsPmLockCB *lock = NULL;
|
||||||
LOS_DL_LIST *head = &pm->lockList;
|
LOS_DL_LIST *head = &pm->lockList;
|
||||||
LOS_DL_LIST *list = head->pstNext;
|
LOS_DL_LIST *list = head->pstNext;
|
||||||
|
|
||||||
intSave = LOS_IntLock();
|
LOS_SpinLock(&g_pmSpin);
|
||||||
while (list != head) {
|
while (list != head) {
|
||||||
lock = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
|
lock = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
|
||||||
PM_INFO_SHOW(m, "%-30s%5u\n\r", lock->name, lock->count);
|
PM_INFO_SHOW(m, "%-30s%5u\n\r", lock->name, lock->count);
|
||||||
list = list->pstNext;
|
list = list->pstNext;
|
||||||
}
|
}
|
||||||
LOS_IntRestore(intSave);
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT32 LOS_PmLockRequest(const CHAR *name)
|
UINT32 OsPmLockRequest(const CHAR *name, UINT32 swtmrID)
|
||||||
{
|
{
|
||||||
INT32 len;
|
INT32 len;
|
||||||
errno_t err;
|
errno_t err;
|
||||||
|
UINT32 ret = LOS_EINVAL;
|
||||||
LosPmCB *pm = &g_pmCB;
|
LosPmCB *pm = &g_pmCB;
|
||||||
OsPmLockCB *listNode = NULL;
|
|
||||||
OsPmLockCB *lock = NULL;
|
OsPmLockCB *lock = NULL;
|
||||||
LOS_DL_LIST *head = &pm->lockList;
|
LOS_DL_LIST *head = &pm->lockList;
|
||||||
LOS_DL_LIST *list = head->pstNext;
|
LOS_DL_LIST *list = head->pstNext;
|
||||||
|
|
||||||
if (name == NULL) {
|
|
||||||
return LOS_EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OS_INT_ACTIVE) {
|
if (OS_INT_ACTIVE) {
|
||||||
return LOS_EINTR;
|
return LOS_EINTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = strlen(name);
|
len = strlen(name);
|
||||||
if (len == 0) {
|
if (len <= 0) {
|
||||||
return LOS_EINVAL;
|
return LOS_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +441,7 @@ UINT32 LOS_PmLockRequest(const CHAR *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (list != head) {
|
while (list != head) {
|
||||||
listNode = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
|
OsPmLockCB *listNode = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
|
||||||
if (strcmp(name, listNode->name) == 0) {
|
if (strcmp(name, listNode->name) == 0) {
|
||||||
lock = listNode;
|
lock = listNode;
|
||||||
break;
|
break;
|
||||||
|
@ -154,33 +456,53 @@ UINT32 LOS_PmLockRequest(const CHAR *name)
|
||||||
LOS_SpinUnlock(&g_pmSpin);
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
return LOS_ENOMEM;
|
return LOS_ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = memcpy_s(lock->name, OS_PM_LOCK_NAME_MAX, name, len + 1);
|
err = memcpy_s(lock->name, OS_PM_LOCK_NAME_MAX, name, len + 1);
|
||||||
if (err != EOK) {
|
if (err != EOK) {
|
||||||
LOS_SpinUnlock(&g_pmSpin);
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
(VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, lock);
|
(VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, lock);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
lock->count = 1;
|
lock->count = 1;
|
||||||
|
lock->swtmrID = swtmrID;
|
||||||
LOS_ListTailInsert(head, &lock->list);
|
LOS_ListTailInsert(head, &lock->list);
|
||||||
} else if (lock->count < OS_PM_LOCK_MAX) {
|
} else if (lock->count < OS_PM_LOCK_MAX) {
|
||||||
lock->count++;
|
lock->count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
pm->lock++;
|
if ((lock->swtmrID != OS_INVALID) && (lock->count > 1)) {
|
||||||
|
lock->count--;
|
||||||
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
|
return LOS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pm->lock < OS_PM_LOCK_MAX) {
|
||||||
|
pm->lock++;
|
||||||
|
ret = LOS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
LOS_SpinUnlock(&g_pmSpin);
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
return LOS_OK;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 LOS_PmLockRequest(const CHAR *name)
|
||||||
|
{
|
||||||
|
if (name == NULL) {
|
||||||
|
return LOS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OsPmLockRequest(name, OS_INVALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT32 LOS_PmLockRelease(const CHAR *name)
|
UINT32 LOS_PmLockRelease(const CHAR *name)
|
||||||
{
|
{
|
||||||
|
UINT32 ret = LOS_EINVAL;
|
||||||
LosPmCB *pm = &g_pmCB;
|
LosPmCB *pm = &g_pmCB;
|
||||||
OsPmLockCB *lock = NULL;
|
OsPmLockCB *lock = NULL;
|
||||||
OsPmLockCB *listNode = NULL;
|
|
||||||
LOS_DL_LIST *head = &pm->lockList;
|
LOS_DL_LIST *head = &pm->lockList;
|
||||||
LOS_DL_LIST *list = head->pstNext;
|
LOS_DL_LIST *list = head->pstNext;
|
||||||
VOID *lockFree = NULL;
|
OsPmLockCB *lockFree = NULL;
|
||||||
|
BOOL isRelease = FALSE;
|
||||||
|
UINT32 mode;
|
||||||
|
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
return LOS_EINVAL;
|
return LOS_EINVAL;
|
||||||
|
@ -196,8 +518,9 @@ UINT32 LOS_PmLockRelease(const CHAR *name)
|
||||||
return LOS_EINVAL;
|
return LOS_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mode = (UINT32)pm->pmMode;
|
||||||
while (list != head) {
|
while (list != head) {
|
||||||
listNode = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
|
OsPmLockCB *listNode = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
|
||||||
if (strcmp(name, listNode->name) == 0) {
|
if (strcmp(name, listNode->name) == 0) {
|
||||||
lock = listNode;
|
lock = listNode;
|
||||||
break;
|
break;
|
||||||
|
@ -208,7 +531,7 @@ UINT32 LOS_PmLockRelease(const CHAR *name)
|
||||||
|
|
||||||
if (lock == NULL) {
|
if (lock == NULL) {
|
||||||
LOS_SpinUnlock(&g_pmSpin);
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
return LOS_EACCES;
|
return LOS_EINVAL;
|
||||||
} else if (lock->count > 0) {
|
} else if (lock->count > 0) {
|
||||||
lock->count--;
|
lock->count--;
|
||||||
if (lock->count == 0) {
|
if (lock->count == 0) {
|
||||||
|
@ -216,21 +539,111 @@ UINT32 LOS_PmLockRelease(const CHAR *name)
|
||||||
lockFree = lock;
|
lockFree = lock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pm->lock--;
|
|
||||||
|
if (pm->lock > 0) {
|
||||||
|
pm->lock--;
|
||||||
|
if (pm->lock == 0) {
|
||||||
|
isRelease = TRUE;
|
||||||
|
}
|
||||||
|
ret = LOS_OK;
|
||||||
|
}
|
||||||
LOS_SpinUnlock(&g_pmSpin);
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
|
|
||||||
(VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, lockFree);
|
if (lockFree != NULL) {
|
||||||
|
(VOID)LOS_SwtmrDelete(lockFree->swtmrID);
|
||||||
|
(VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, lockFree);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isRelease && (mode > LOS_SYS_NORMAL_SLEEP)) {
|
||||||
|
(VOID)LOS_EventWrite(&g_pmEvent, PM_EVENT_LOCK_RELEASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC VOID OsPmSwtmrHandler(UINT32 arg)
|
||||||
|
{
|
||||||
|
const CHAR *name = (const CHAR *)arg;
|
||||||
|
UINT32 ret = LOS_PmLockRelease(name);
|
||||||
|
if (ret != LOS_OK) {
|
||||||
|
PRINT_ERR("Pm delay lock %s release faled! : 0x%x\n", name, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 LOS_PmTimeLockRequest(const CHAR *name, UINT64 millisecond)
|
||||||
|
{
|
||||||
|
UINT32 ticks;
|
||||||
|
UINT16 swtmrID;
|
||||||
|
UINT32 ret;
|
||||||
|
|
||||||
|
if ((name == NULL) || !millisecond) {
|
||||||
|
return LOS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ticks = (UINT32)((millisecond + OS_MS_PER_TICK - 1) / OS_MS_PER_TICK);
|
||||||
|
#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1)
|
||||||
|
ret = LOS_SwtmrCreate(ticks, LOS_SWTMR_MODE_ONCE, OsPmSwtmrHandler, &swtmrID, (UINT32)(UINTPTR)name,
|
||||||
|
OS_SWTMR_ROUSES_ALLOW, OS_SWTMR_ALIGN_INSENSITIVE);
|
||||||
|
#else
|
||||||
|
ret = LOS_SwtmrCreate(ticks, LOS_SWTMR_MODE_ONCE, OsPmSwtmrHandler, &swtmrID, (UINT32)(UINTPTR)name);
|
||||||
|
#endif
|
||||||
|
if (ret != LOS_OK) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = OsPmLockRequest(name, swtmrID);
|
||||||
|
if (ret != LOS_OK) {
|
||||||
|
(VOID)LOS_SwtmrDelete(swtmrID);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = LOS_SwtmrStart(swtmrID);
|
||||||
|
if (ret != LOS_OK) {
|
||||||
|
(VOID)LOS_PmLockRelease(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 LOS_PmReadLock(VOID)
|
||||||
|
{
|
||||||
|
UINT32 ret = LOS_EventRead(&g_pmEvent, PM_EVENT_LOCK_MASK, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER);
|
||||||
|
if (ret > PM_EVENT_LOCK_MASK) {
|
||||||
|
PRINT_ERR("%s event read failed! ERROR: 0x%x\n", __FUNCTION__, ret);
|
||||||
|
}
|
||||||
|
|
||||||
return LOS_OK;
|
return LOS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT32 LOS_PmSuspend(UINT32 wakeCount)
|
||||||
|
{
|
||||||
|
(VOID)wakeCount;
|
||||||
|
return OsPmSuspendSleep(&g_pmCB);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL OsIsPmMode(VOID)
|
||||||
|
{
|
||||||
|
LosPmCB *pm = &g_pmCB;
|
||||||
|
|
||||||
|
LOS_SpinLock(&g_pmSpin);
|
||||||
|
if ((pm->sysMode != LOS_SYS_NORMAL_SLEEP) && (pm->lock == 0)) {
|
||||||
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
LOS_SpinUnlock(&g_pmSpin);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
UINT32 OsPmInit(VOID)
|
UINT32 OsPmInit(VOID)
|
||||||
{
|
{
|
||||||
LosPmCB *pm = &g_pmCB;
|
LosPmCB *pm = &g_pmCB;
|
||||||
|
|
||||||
(VOID)memset_s(pm, sizeof(LosPmCB), 0, sizeof(LosPmCB));
|
(VOID)memset_s(pm, sizeof(LosPmCB), 0, sizeof(LosPmCB));
|
||||||
|
|
||||||
pm->mode = LOS_SYS_NORMAL_SLEEP;
|
pm->pmMode = LOS_SYS_NORMAL_SLEEP;
|
||||||
LOS_ListInit(&pm->lockList);
|
LOS_ListInit(&pm->lockList);
|
||||||
|
(VOID)LOS_EventInit(&g_pmEvent);
|
||||||
|
|
||||||
return LOS_OK;
|
return LOS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
||||||
|
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LOS_PM_PRI_H
|
||||||
|
#define _LOS_PM_PRI_H
|
||||||
|
|
||||||
|
#include "los_config.h"
|
||||||
|
#include "los_typedef.h"
|
||||||
|
|
||||||
|
#ifdef LOSCFG_KERNEL_PM
|
||||||
|
|
||||||
|
BOOL OsIsPmMode(VOID);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
STATIC INLINE BOOL OsIsPmMode(VOID)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
|
@ -144,6 +144,7 @@ enum LOS_MOUDLE_ID {
|
||||||
LOS_MOD_CPUP = 0x1e,
|
LOS_MOD_CPUP = 0x1e,
|
||||||
LOS_MOD_HOOK = 0x1f,
|
LOS_MOD_HOOK = 0x1f,
|
||||||
LOS_MOD_PERF = 0x20,
|
LOS_MOD_PERF = 0x20,
|
||||||
|
LOS_MOD_PM = 0x21,
|
||||||
LOS_MOD_SHELL = 0x31,
|
LOS_MOD_SHELL = 0x31,
|
||||||
LOS_MOD_DRIVER = 0x41,
|
LOS_MOD_DRIVER = 0x41,
|
||||||
LOS_MOD_BUTT
|
LOS_MOD_BUTT
|
||||||
|
|
|
@ -45,6 +45,118 @@ typedef enum {
|
||||||
LOS_SYS_SHUTDOWN,
|
LOS_SYS_SHUTDOWN,
|
||||||
} LOS_SysSleepEnum;
|
} LOS_SysSleepEnum;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
LOS_PM_TYPE_DEVICE = 0,
|
||||||
|
LOS_PM_TYPE_TICK_TIMER, /* reserved */
|
||||||
|
LOS_PM_TYPE_SYSCTRL,
|
||||||
|
} LOS_PmNodeType;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UINT32 (*suspend)(UINT32 mode); /* The device enters low power consumption, Unlocked task scheduling. */
|
||||||
|
VOID (*resume)(UINT32 mode); /* The device exits from low power consumption, Unlocked task scheduling. */
|
||||||
|
} LosPmDevice;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/* Preparations before the CPU enters low power consumption.
|
||||||
|
* All modes except normal mode are invoked.
|
||||||
|
* Unlocked task scheduling.
|
||||||
|
*/
|
||||||
|
UINT32 (*early)(UINT32 mode);
|
||||||
|
/* The system performs low-power recovery.
|
||||||
|
* All modes except normal mode are invoked.
|
||||||
|
* Unlocked task scheduling.
|
||||||
|
*/
|
||||||
|
VOID (*late)(UINT32 mode);
|
||||||
|
/* The system enters the Normal sleep mode.
|
||||||
|
* In normal mode, the value cannot be NULL.
|
||||||
|
*/
|
||||||
|
UINT32 (*normalSuspend)(VOID);
|
||||||
|
/* The system recovers from normal sleep.
|
||||||
|
* The value can be NULL.
|
||||||
|
*/
|
||||||
|
VOID (*normalResume)(VOID);
|
||||||
|
/* The system enters the light sleep mode.
|
||||||
|
* In light sleep mode, the value cannot be NULL.
|
||||||
|
*/
|
||||||
|
UINT32 (*lightSuspend)(VOID);
|
||||||
|
/* The system recovers from light sleep.
|
||||||
|
* The value can be NULL.
|
||||||
|
*/
|
||||||
|
VOID (*lightResume)(VOID);
|
||||||
|
/* The system enters the deep sleep mode.
|
||||||
|
* In deep sleep mode, the value cannot be NULL.
|
||||||
|
*/
|
||||||
|
UINT32 (*deepSuspend)(VOID);
|
||||||
|
/* The system recovers from deep sleep.
|
||||||
|
* The value can be NULL.
|
||||||
|
*/
|
||||||
|
VOID (*deepResume)(VOID);
|
||||||
|
/* The system enters the shutdown mode.
|
||||||
|
* In shutdown mode, the value cannot be NULL.
|
||||||
|
*/
|
||||||
|
UINT32 (*shutdownSuspend)(VOID);
|
||||||
|
/* The system recovers from shutdown.
|
||||||
|
* In shutdown mode, the value cannot be NULL.
|
||||||
|
*/
|
||||||
|
VOID (*shutdownResume)(VOID);
|
||||||
|
} LosPmSysctrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup los_pm
|
||||||
|
* @brief Register a power management node.
|
||||||
|
*
|
||||||
|
* @par Description:
|
||||||
|
* This API is used to register a power management node.
|
||||||
|
*
|
||||||
|
* @attention None.
|
||||||
|
*
|
||||||
|
* @param type [IN] The types supported by the PM module.
|
||||||
|
* @param node [IN] power management node.
|
||||||
|
*
|
||||||
|
* @retval error code, LOS_OK means success.
|
||||||
|
* @par Dependency:
|
||||||
|
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||||
|
* @see LOS_PmUnregister
|
||||||
|
*/
|
||||||
|
UINT32 LOS_PmRegister(LOS_PmNodeType type, VOID *node);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup los_pm
|
||||||
|
* @brief Unregister a power management node.
|
||||||
|
*
|
||||||
|
* @par Description:
|
||||||
|
* This API is used to unregister a power management node.
|
||||||
|
*
|
||||||
|
* @attention None.
|
||||||
|
*
|
||||||
|
* @param type [IN] The types supported by the PM module.
|
||||||
|
* @param node [IN] power management node.
|
||||||
|
*
|
||||||
|
* @retval error code, LOS_OK means success.
|
||||||
|
* @par Dependency:
|
||||||
|
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||||
|
* @see LOS_PmRegister
|
||||||
|
*/
|
||||||
|
UINT32 LOS_PmUnregister(LOS_PmNodeType type, VOID *node);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup los_pm
|
||||||
|
* @brief Set the system wake up flag.
|
||||||
|
*
|
||||||
|
* @par Description:
|
||||||
|
* This API is used to set the system wake-up flag.
|
||||||
|
*
|
||||||
|
* @attention None.
|
||||||
|
*
|
||||||
|
* @param None.
|
||||||
|
*
|
||||||
|
* @retval None.
|
||||||
|
* @par Dependency:
|
||||||
|
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
VOID LOS_PmWakeSet(VOID);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup los_pm
|
* @ingroup los_pm
|
||||||
* @brief Get the low power mode of the current system.
|
* @brief Get the low power mode of the current system.
|
||||||
|
@ -63,6 +175,24 @@ typedef enum {
|
||||||
*/
|
*/
|
||||||
LOS_SysSleepEnum LOS_PmModeGet(VOID);
|
LOS_SysSleepEnum LOS_PmModeGet(VOID);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup los_pm
|
||||||
|
* @brief Set low power mode.
|
||||||
|
*
|
||||||
|
* @par Description:
|
||||||
|
* This API is used to set low power mode.
|
||||||
|
*
|
||||||
|
* @attention None.
|
||||||
|
*
|
||||||
|
* @param mode [IN] low power mode.
|
||||||
|
*
|
||||||
|
* @retval error code, LOS_OK means success.
|
||||||
|
* @par Dependency:
|
||||||
|
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||||
|
* @see LOS_PmModeGet
|
||||||
|
*/
|
||||||
|
UINT32 LOS_PmModeSet(LOS_SysSleepEnum mode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup los_pm
|
* @ingroup los_pm
|
||||||
* @brief Get the low power mode of the current system.
|
* @brief Get the low power mode of the current system.
|
||||||
|
@ -100,6 +230,27 @@ UINT32 LOS_PmLockCountGet(VOID);
|
||||||
*/
|
*/
|
||||||
UINT32 LOS_PmLockRequest(const CHAR *name);
|
UINT32 LOS_PmLockRequest(const CHAR *name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup los_pm
|
||||||
|
* @brief Request to obtain the lock in current mode, so that the system will not enter
|
||||||
|
* this mode when it enters the idle task next time. After the specified interval, the
|
||||||
|
* lock is automatically released.
|
||||||
|
*
|
||||||
|
* @par Description:
|
||||||
|
* This API is used to obtain the delay lock in current mode.
|
||||||
|
*
|
||||||
|
* @attention None.
|
||||||
|
*
|
||||||
|
* @param name [IN] Who requests the lock.
|
||||||
|
* @param millisecond [IN] Specifies the time to automatically release the lock.
|
||||||
|
*
|
||||||
|
* @retval error code, LOS_OK means success.
|
||||||
|
* @par Dependency:
|
||||||
|
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||||
|
* @see LOS_PmLockRelease
|
||||||
|
*/
|
||||||
|
UINT32 LOS_PmTimeLockRequest(const CHAR *name, UINT64 millisecond);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup los_pm
|
* @ingroup los_pm
|
||||||
* @brief Release the lock in current mode so that the next time the system enters
|
* @brief Release the lock in current mode so that the next time the system enters
|
||||||
|
@ -119,6 +270,42 @@ UINT32 LOS_PmLockRequest(const CHAR *name);
|
||||||
*/
|
*/
|
||||||
UINT32 LOS_PmLockRelease(const CHAR *name);
|
UINT32 LOS_PmLockRelease(const CHAR *name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup los_pm
|
||||||
|
* @brief Gets the current PM lock status.
|
||||||
|
*
|
||||||
|
* @par Description:
|
||||||
|
* This API is used to Get the current PM lock status.
|
||||||
|
*
|
||||||
|
* @attention None.
|
||||||
|
*
|
||||||
|
* @param None.
|
||||||
|
*
|
||||||
|
* @retval Number of awakening sources of the device.
|
||||||
|
* @par Dependency:
|
||||||
|
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
UINT32 LOS_PmReadLock(VOID);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup los_pm
|
||||||
|
* @brief The system enters the low-power flow.
|
||||||
|
*
|
||||||
|
* @par Description:
|
||||||
|
* This API is used to enter the system into a low-power process.
|
||||||
|
*
|
||||||
|
* @attention None.
|
||||||
|
*
|
||||||
|
* @param wakeCount [IN] Number of wake sources.
|
||||||
|
*
|
||||||
|
* @retval error code, LOS_OK means success.
|
||||||
|
* @par Dependency:
|
||||||
|
* <ul><li>los_pm.h: the header file that contains the API declaration.</li></ul>
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
UINT32 LOS_PmSuspend(UINT32 wakeCount);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup los_pm
|
* @ingroup los_pm
|
||||||
* @brief Output the locking information of the pm lock.
|
* @brief Output the locking information of the pm lock.
|
||||||
|
|
|
@ -184,7 +184,7 @@ endif
|
||||||
ifeq ($(LOSCFG_KERNEL_PM), y)
|
ifeq ($(LOSCFG_KERNEL_PM), y)
|
||||||
LITEOS_BASELIB += -lpower
|
LITEOS_BASELIB += -lpower
|
||||||
LIB_SUBDIRS += kernel/extended/power
|
LIB_SUBDIRS += kernel/extended/power
|
||||||
LITEOS_PIPE_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/power
|
LITEOS_PM_INCLUDE = -I $(LITEOSTOPDIR)/kernel/extended/power
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(LOSCFG_KERNEL_SYSCALL), y)
|
ifeq ($(LOSCFG_KERNEL_SYSCALL), y)
|
||||||
|
@ -513,7 +513,8 @@ LITEOS_EXTKERNEL_INCLUDE := $(LITEOS_CPPSUPPORT_INCLUDE) $(LITEOS_DYNLOAD_INCL
|
||||||
$(LITEOS_TICKLESS_INCLUDE) $(LITEOS_HOOK_INCLUDE)\
|
$(LITEOS_TICKLESS_INCLUDE) $(LITEOS_HOOK_INCLUDE)\
|
||||||
$(LITEOS_VDSO_INCLUDE) $(LITEOS_LITEIPC_INCLUDE) \
|
$(LITEOS_VDSO_INCLUDE) $(LITEOS_LITEIPC_INCLUDE) \
|
||||||
$(LITEOS_PIPE_INCLUDE) $(LITEOS_CPUP_INCLUDE) \
|
$(LITEOS_PIPE_INCLUDE) $(LITEOS_CPUP_INCLUDE) \
|
||||||
$(LITEOS_PERF_INCLUDE) $(LITEOS_LMS_INCLUDE)
|
$(LITEOS_PERF_INCLUDE) $(LITEOS_LMS_INCLUDE) \
|
||||||
|
$(LITEOS_PM_INCLUDE)
|
||||||
LITEOS_COMPAT_INCLUDE := $(LITEOS_POSIX_INCLUDE) $(LITEOS_LINUX_INCLUDE) \
|
LITEOS_COMPAT_INCLUDE := $(LITEOS_POSIX_INCLUDE) $(LITEOS_LINUX_INCLUDE) \
|
||||||
$(LITEOS_BSD_INCLUDE)
|
$(LITEOS_BSD_INCLUDE)
|
||||||
LITEOS_FS_INCLUDE := $(LITEOS_VFS_INCLUDE) $(LITEOS_FAT_CACHE_INCLUDE) \
|
LITEOS_FS_INCLUDE := $(LITEOS_VFS_INCLUDE) $(LITEOS_FAT_CACHE_INCLUDE) \
|
||||||
|
|
Loading…
Reference in New Issue