1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "los_pm.h"
33 #include "securec.h"
34 #include "los_sched_pri.h"
35 #include "los_init.h"
36 #include "los_memory.h"
37 #include "los_spinlock.h"
38 #include "los_swtmr.h"
39 #include "los_mp.h"
40
41 #define OS_MS_PER_TICK (OS_SYS_MS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND)
42
43 #ifdef LOSCFG_KERNEL_PM
44 #define PM_INFO_SHOW(seqBuf, arg...) do { \
45 if (seqBuf != NULL) { \
46 (void)LosBufPrintf((struct SeqBuf *)seqBuf, ##arg); \
47 } else { \
48 PRINTK(arg); \
49 } \
50 } while (0)
51
52 #define OS_PM_LOCK_MAX 0xFFFFU
53 #define OS_PM_LOCK_NAME_MAX 28
54 #define OS_PM_SYS_EARLY 1
55 #define OS_PM_SYS_DEVICE_EARLY 2
56
57 typedef UINT32 (*Suspend)(UINT32 mode);
58
59 typedef struct {
60 CHAR name[OS_PM_LOCK_NAME_MAX];
61 UINT32 count;
62 UINT32 swtmrID;
63 LOS_DL_LIST list;
64 } OsPmLockCB;
65
66 typedef struct {
67 LOS_SysSleepEnum pmMode;
68 LOS_SysSleepEnum sysMode;
69 UINT16 lock;
70 BOOL isWake;
71 LosPmDevice *device;
72 LosPmSysctrl *sysctrl;
73 UINT64 enterSleepTime;
74 LOS_DL_LIST lockList;
75 } LosPmCB;
76
77 #define PM_EVENT_LOCK_MASK 0xF
78 #define PM_EVENT_LOCK_RELEASE 0x1
79 STATIC EVENT_CB_S g_pmEvent;
80 STATIC LosPmCB g_pmCB;
81 STATIC SPIN_LOCK_INIT(g_pmSpin);
82 STATIC LosPmSysctrl g_sysctrl;
83
84 STATIC VOID OsPmSysctrlInit(VOID);
85
OsPmTickTimerStart(LosPmCB *pm)86 STATIC VOID OsPmTickTimerStart(LosPmCB *pm)
87 {
88 (VOID)pm;
89 return;
90 }
91
OsPmTickTimerStop(LosPmCB *pm)92 STATIC BOOL OsPmTickTimerStop(LosPmCB *pm)
93 {
94 (VOID)pm;
95 return FALSE;
96 }
97
OsPmCpuResume(LosPmCB *pm)98 STATIC VOID OsPmCpuResume(LosPmCB *pm)
99 {
100 if ((pm->sysMode == LOS_SYS_NORMAL_SLEEP) && (pm->sysctrl->normalResume != NULL)) {
101 pm->sysctrl->normalResume();
102 } else if ((pm->sysMode == LOS_SYS_LIGHT_SLEEP) && (pm->sysctrl->lightResume != NULL)) {
103 pm->sysctrl->lightResume();
104 } else if ((pm->sysMode == LOS_SYS_DEEP_SLEEP) && (pm->sysctrl->deepResume != NULL)) {
105 pm->sysctrl->deepResume();
106 }
107 }
108
OsPmCpuSuspend(LosPmCB *pm)109 VOID OsPmCpuSuspend(LosPmCB *pm)
110 {
111 /* cpu enter low power mode */
112 LOS_ASSERT(pm->sysctrl != NULL);
113
114 if (pm->sysMode == LOS_SYS_NORMAL_SLEEP) {
115 pm->sysctrl->normalSuspend();
116 } else if (pm->sysMode == LOS_SYS_LIGHT_SLEEP) {
117 pm->sysctrl->lightSuspend();
118 } else if (pm->sysMode == LOS_SYS_DEEP_SLEEP) {
119 pm->sysctrl->deepSuspend();
120 } else {
121 pm->sysctrl->shutdownSuspend();
122 }
123 }
124
OsPmResumePrepare(LosPmCB *pm, UINT32 mode, UINT32 prepare)125 STATIC VOID OsPmResumePrepare(LosPmCB *pm, UINT32 mode, UINT32 prepare)
126 {
127 if ((prepare == 0) && (pm->device != NULL) && (pm->device->resume != NULL)) {
128 pm->device->resume(mode);
129 }
130
131 if (((prepare == 0) || (prepare == OS_PM_SYS_DEVICE_EARLY)) && (pm->sysctrl->late != NULL)) {
132 pm->sysctrl->late(mode);
133 }
134 }
135
OsPmSuspendPrepare(Suspend sysSuspendEarly, Suspend deviceSuspend, UINT32 mode, UINT32 *prepare)136 STATIC UINT32 OsPmSuspendPrepare(Suspend sysSuspendEarly, Suspend deviceSuspend, UINT32 mode, UINT32 *prepare)
137 {
138 UINT32 ret;
139
140 if (sysSuspendEarly != NULL) {
141 ret = sysSuspendEarly(mode);
142 if (ret != LOS_OK) {
143 *prepare = OS_PM_SYS_EARLY;
144 return ret;
145 }
146 }
147
148 if (deviceSuspend != NULL) {
149 ret = deviceSuspend(mode);
150 if (ret != LOS_OK) {
151 *prepare = OS_PM_SYS_DEVICE_EARLY;
152 return ret;
153 }
154 }
155
156 return LOS_OK;
157 }
158
OsPmSuspendCheck(LosPmCB *pm, Suspend *sysSuspendEarly, Suspend *deviceSuspend, LOS_SysSleepEnum *mode)159 STATIC UINT32 OsPmSuspendCheck(LosPmCB *pm, Suspend *sysSuspendEarly, Suspend *deviceSuspend, LOS_SysSleepEnum *mode)
160 {
161 LOS_SpinLock(&g_pmSpin);
162 pm->sysMode = pm->pmMode;
163 if (pm->lock > 0) {
164 pm->sysMode = LOS_SYS_NORMAL_SLEEP;
165 LOS_SpinUnlock(&g_pmSpin);
166 return LOS_NOK;
167 }
168
169 pm->isWake = FALSE;
170 *mode = pm->sysMode;
171 *sysSuspendEarly = pm->sysctrl->early;
172 if (pm->device != NULL) {
173 *deviceSuspend = pm->device->suspend;
174 } else {
175 *deviceSuspend = NULL;
176 }
177 LOS_SpinUnlock(&g_pmSpin);
178 return LOS_OK;
179 }
180
OsPmSuspendSleep(LosPmCB *pm)181 STATIC UINT32 OsPmSuspendSleep(LosPmCB *pm)
182 {
183 UINT32 ret, intSave;
184 Suspend sysSuspendEarly, deviceSuspend;
185 LOS_SysSleepEnum mode;
186 UINT32 prepare = 0;
187 BOOL tickTimerStop = FALSE;
188
189 ret = OsPmSuspendCheck(pm, &sysSuspendEarly, &deviceSuspend, &mode);
190 if (ret != LOS_OK) {
191 PRINT_ERR("Pm suspend mode is normal sleep! lock count %d\n", pm->lock);
192 return ret;
193 }
194
195 ret = OsPmSuspendPrepare(sysSuspendEarly, deviceSuspend, (UINT32)mode, &prepare);
196 if (ret != LOS_OK) {
197 LOS_SpinLockSave(&g_pmSpin, &intSave);
198 LOS_TaskLock();
199 goto EXIT;
200 }
201
202 LOS_SpinLockSave(&g_pmSpin, &intSave);
203 LOS_TaskLock();
204 if (pm->isWake || (pm->lock > 0)) {
205 goto EXIT;
206 }
207
208 tickTimerStop = OsPmTickTimerStop(pm);
209 if (!tickTimerStop) {
210 OsSchedResponseTimeReset(0);
211 OsSchedExpireTimeUpdate();
212 }
213
214 OsPmCpuSuspend(pm);
215
216 OsPmCpuResume(pm);
217
218 OsPmTickTimerStart(pm);
219
220 EXIT:
221 pm->sysMode = LOS_SYS_NORMAL_SLEEP;
222 OsPmResumePrepare(pm, (UINT32)mode, prepare);
223
224 LOS_SpinUnlockRestore(&g_pmSpin, intSave);
225 LOS_TaskUnlock();
226 return ret;
227 }
228
OsPmDeviceRegister(LosPmCB *pm, LosPmDevice *device)229 STATIC UINT32 OsPmDeviceRegister(LosPmCB *pm, LosPmDevice *device)
230 {
231 if ((device->suspend == NULL) || (device->resume == NULL)) {
232 return LOS_EINVAL;
233 }
234
235 LOS_SpinLock(&g_pmSpin);
236 pm->device = device;
237 LOS_SpinUnlock(&g_pmSpin);
238
239 return LOS_OK;
240 }
241
OsPmSysctrlRegister(LosPmCB *pm, LosPmSysctrl *sysctrl)242 STATIC UINT32 OsPmSysctrlRegister(LosPmCB *pm, LosPmSysctrl *sysctrl)
243 {
244 LOS_SpinLock(&g_pmSpin);
245 if (sysctrl->early != NULL) {
246 pm->sysctrl->early = sysctrl->early;
247 }
248 if (sysctrl->late != NULL) {
249 pm->sysctrl->late = sysctrl->late;
250 }
251 if (sysctrl->normalSuspend != NULL) {
252 pm->sysctrl->normalSuspend = sysctrl->normalSuspend;
253 }
254 if (sysctrl->normalResume != NULL) {
255 pm->sysctrl->normalResume = sysctrl->normalResume;
256 }
257 if (sysctrl->lightSuspend != NULL) {
258 pm->sysctrl->lightSuspend = sysctrl->lightSuspend;
259 }
260 if (sysctrl->lightResume != NULL) {
261 pm->sysctrl->lightResume = sysctrl->lightResume;
262 }
263 if (sysctrl->deepSuspend != NULL) {
264 pm->sysctrl->deepSuspend = sysctrl->deepSuspend;
265 }
266 if (sysctrl->deepResume != NULL) {
267 pm->sysctrl->deepResume = sysctrl->deepResume;
268 }
269 if (sysctrl->shutdownSuspend != NULL) {
270 pm->sysctrl->shutdownSuspend = sysctrl->shutdownSuspend;
271 }
272 if (sysctrl->shutdownResume != NULL) {
273 pm->sysctrl->shutdownResume = sysctrl->shutdownResume;
274 }
275 LOS_SpinUnlock(&g_pmSpin);
276
277 return LOS_OK;
278 }
279
LOS_PmRegister(LOS_PmNodeType type, VOID *node)280 UINT32 LOS_PmRegister(LOS_PmNodeType type, VOID *node)
281 {
282 LosPmCB *pm = &g_pmCB;
283
284 if (node == NULL) {
285 return LOS_EINVAL;
286 }
287
288 switch (type) {
289 case LOS_PM_TYPE_DEVICE:
290 return OsPmDeviceRegister(pm, (LosPmDevice *)node);
291 case LOS_PM_TYPE_TICK_TIMER:
292 PRINT_ERR("Pm, %d is an unsupported type\n", type);
293 return LOS_EINVAL;
294 case LOS_PM_TYPE_SYSCTRL:
295 return OsPmSysctrlRegister(pm, (LosPmSysctrl *)node);
296 default:
297 break;
298 }
299
300 return LOS_EINVAL;
301 }
302
OsPmDeviceUnregister(LosPmCB *pm, const LosPmDevice *device)303 STATIC UINT32 OsPmDeviceUnregister(LosPmCB *pm, const LosPmDevice *device)
304 {
305 LOS_SpinLock(&g_pmSpin);
306 if (pm->device == device) {
307 pm->device = NULL;
308 pm->pmMode = LOS_SYS_NORMAL_SLEEP;
309 LOS_SpinUnlock(&g_pmSpin);
310 return LOS_OK;
311 }
312
313 LOS_SpinUnlock(&g_pmSpin);
314 return LOS_EINVAL;
315 }
316
OsPmSysctrlUnregister(LosPmCB *pm, LosPmSysctrl *sysctrl)317 STATIC UINT32 OsPmSysctrlUnregister(LosPmCB *pm, LosPmSysctrl *sysctrl)
318 {
319 (VOID)sysctrl;
320 LOS_SpinLock(&g_pmSpin);
321 OsPmSysctrlInit();
322 pm->pmMode = LOS_SYS_NORMAL_SLEEP;
323 LOS_SpinUnlock(&g_pmSpin);
324
325 return LOS_OK;
326 }
327
LOS_PmUnregister(LOS_PmNodeType type, VOID *node)328 UINT32 LOS_PmUnregister(LOS_PmNodeType type, VOID *node)
329 {
330 LosPmCB *pm = &g_pmCB;
331
332 if (node == NULL) {
333 return LOS_EINVAL;
334 }
335
336 switch (type) {
337 case LOS_PM_TYPE_DEVICE:
338 return OsPmDeviceUnregister(pm, (LosPmDevice *)node);
339 case LOS_PM_TYPE_TICK_TIMER:
340 PRINT_ERR("Pm, %d is an unsupported type\n", type);
341 return LOS_EINVAL;
342 case LOS_PM_TYPE_SYSCTRL:
343 return OsPmSysctrlUnregister(pm, (LosPmSysctrl *)node);
344 default:
345 break;
346 }
347
348 return LOS_EINVAL;
349 }
350
LOS_PmWakeSetnull351 VOID LOS_PmWakeSet(VOID)
352 {
353 LosPmCB *pm = &g_pmCB;
354
355 LOS_SpinLock(&g_pmSpin);
356 pm->isWake = TRUE;
357 LOS_SpinUnlock(&g_pmSpin);
358 return;
359 }
360
LOS_PmModeGetnull361 LOS_SysSleepEnum LOS_PmModeGet(VOID)
362 {
363 LOS_SysSleepEnum mode;
364 LosPmCB *pm = &g_pmCB;
365
366 LOS_SpinLock(&g_pmSpin);
367 mode = pm->pmMode;
368 LOS_SpinUnlock(&g_pmSpin);
369
370 return mode;
371 }
372
LOS_PmModeSet(LOS_SysSleepEnum mode)373 UINT32 LOS_PmModeSet(LOS_SysSleepEnum mode)
374 {
375 LosPmCB *pm = &g_pmCB;
376 INT32 sleepMode = (INT32)mode;
377
378 if ((sleepMode < 0) || (sleepMode > LOS_SYS_SHUTDOWN)) {
379 return LOS_EINVAL;
380 }
381
382 LOS_SpinLock(&g_pmSpin);
383 if ((mode == LOS_SYS_LIGHT_SLEEP) && (pm->sysctrl->lightSuspend == NULL)) {
384 LOS_SpinUnlock(&g_pmSpin);
385 return LOS_EINVAL;
386 }
387
388 if ((mode == LOS_SYS_DEEP_SLEEP) && (pm->sysctrl->deepSuspend == NULL)) {
389 LOS_SpinUnlock(&g_pmSpin);
390 return LOS_EINVAL;
391 }
392
393 if ((mode == LOS_SYS_SHUTDOWN) && (pm->sysctrl->shutdownSuspend == NULL)) {
394 LOS_SpinUnlock(&g_pmSpin);
395 return LOS_EINVAL;
396 }
397
398 pm->pmMode = mode;
399 LOS_SpinUnlock(&g_pmSpin);
400
401 return LOS_OK;
402 }
403
LOS_PmLockCountGetnull404 UINT32 LOS_PmLockCountGet(VOID)
405 {
406 UINT16 count;
407 LosPmCB *pm = &g_pmCB;
408
409 LOS_SpinLock(&g_pmSpin);
410 count = pm->lock;
411 LOS_SpinUnlock(&g_pmSpin);
412
413 return (UINT32)count;
414 }
415
LOS_PmLockInfoShow(struct SeqBuf *m)416 VOID LOS_PmLockInfoShow(struct SeqBuf *m)
417 {
418 LosPmCB *pm = &g_pmCB;
419 OsPmLockCB *lock = NULL;
420 LOS_DL_LIST *head = &pm->lockList;
421 LOS_DL_LIST *list = head->pstNext;
422
423 LOS_SpinLock(&g_pmSpin);
424 while (list != head) {
425 lock = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
426 PM_INFO_SHOW(m, "%-30s%5u\n\r", lock->name, lock->count);
427 list = list->pstNext;
428 }
429 LOS_SpinUnlock(&g_pmSpin);
430
431 return;
432 }
433
OsPmLockRequest(const CHAR *name, UINT32 swtmrID)434 UINT32 OsPmLockRequest(const CHAR *name, UINT32 swtmrID)
435 {
436 INT32 len;
437 errno_t err;
438 UINT32 ret = LOS_EINVAL;
439 LosPmCB *pm = &g_pmCB;
440 OsPmLockCB *lock = NULL;
441 LOS_DL_LIST *head = &pm->lockList;
442 LOS_DL_LIST *list = head->pstNext;
443
444 if (OS_INT_ACTIVE) {
445 return LOS_EINTR;
446 }
447
448 len = strlen(name);
449 if (len <= 0) {
450 return LOS_EINVAL;
451 }
452
453 LOS_SpinLock(&g_pmSpin);
454 if (pm->lock >= OS_PM_LOCK_MAX) {
455 LOS_SpinUnlock(&g_pmSpin);
456 return LOS_EINVAL;
457 }
458
459 while (list != head) {
460 OsPmLockCB *listNode = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
461 if (strcmp(name, listNode->name) == 0) {
462 lock = listNode;
463 break;
464 }
465
466 list = list->pstNext;
467 }
468
469 if (lock == NULL) {
470 lock = LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(OsPmLockCB));
471 if (lock == NULL) {
472 LOS_SpinUnlock(&g_pmSpin);
473 return LOS_ENOMEM;
474 }
475 err = memcpy_s(lock->name, OS_PM_LOCK_NAME_MAX, name, len + 1);
476 if (err != EOK) {
477 LOS_SpinUnlock(&g_pmSpin);
478 (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, lock);
479 return err;
480 }
481 lock->count = 1;
482 lock->swtmrID = swtmrID;
483 LOS_ListTailInsert(head, &lock->list);
484 } else if (lock->count < OS_PM_LOCK_MAX) {
485 lock->count++;
486 }
487
488 if ((lock->swtmrID != OS_INVALID) && (lock->count > 1)) {
489 lock->count--;
490 LOS_SpinUnlock(&g_pmSpin);
491 return LOS_EINVAL;
492 }
493
494 if (pm->lock < OS_PM_LOCK_MAX) {
495 pm->lock++;
496 ret = LOS_OK;
497 }
498
499 LOS_SpinUnlock(&g_pmSpin);
500 return ret;
501 }
502
LOS_PmLockRequest(const CHAR *name)503 UINT32 LOS_PmLockRequest(const CHAR *name)
504 {
505 if (name == NULL) {
506 return LOS_EINVAL;
507 }
508
509 return OsPmLockRequest(name, OS_INVALID);
510 }
511
LOS_PmLockRelease(const CHAR *name)512 UINT32 LOS_PmLockRelease(const CHAR *name)
513 {
514 UINT32 ret = LOS_EINVAL;
515 LosPmCB *pm = &g_pmCB;
516 OsPmLockCB *lock = NULL;
517 LOS_DL_LIST *head = &pm->lockList;
518 LOS_DL_LIST *list = head->pstNext;
519 OsPmLockCB *lockFree = NULL;
520 BOOL isRelease = FALSE;
521 UINT32 mode;
522
523 if (name == NULL) {
524 return LOS_EINVAL;
525 }
526
527 if (OS_INT_ACTIVE) {
528 return LOS_EINTR;
529 }
530
531 LOS_SpinLock(&g_pmSpin);
532 if (pm->lock == 0) {
533 LOS_SpinUnlock(&g_pmSpin);
534 return LOS_EINVAL;
535 }
536
537 mode = (UINT32)pm->pmMode;
538 while (list != head) {
539 OsPmLockCB *listNode = LOS_DL_LIST_ENTRY(list, OsPmLockCB, list);
540 if (strcmp(name, listNode->name) == 0) {
541 lock = listNode;
542 break;
543 }
544
545 list = list->pstNext;
546 }
547
548 if (lock == NULL) {
549 LOS_SpinUnlock(&g_pmSpin);
550 return LOS_EINVAL;
551 } else if (lock->count > 0) {
552 lock->count--;
553 if (lock->count == 0) {
554 LOS_ListDelete(&lock->list);
555 lockFree = lock;
556 }
557 }
558
559 if (pm->lock > 0) {
560 pm->lock--;
561 if (pm->lock == 0) {
562 isRelease = TRUE;
563 }
564 ret = LOS_OK;
565 }
566 LOS_SpinUnlock(&g_pmSpin);
567
568 if (lockFree != NULL) {
569 (VOID)LOS_SwtmrDelete(lockFree->swtmrID);
570 (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, lockFree);
571 }
572
573 if (isRelease && (mode > LOS_SYS_NORMAL_SLEEP)) {
574 (VOID)LOS_EventWrite(&g_pmEvent, PM_EVENT_LOCK_RELEASE);
575 }
576
577 return ret;
578 }
579
OsPmSwtmrHandler(UINT32 arg)580 STATIC VOID OsPmSwtmrHandler(UINT32 arg)
581 {
582 const CHAR *name = (const CHAR *)arg;
583 UINT32 ret = LOS_PmLockRelease(name);
584 if (ret != LOS_OK) {
585 PRINT_ERR("Pm delay lock %s release faled! : 0x%x\n", name, ret);
586 }
587 }
588
LOS_PmTimeLockRequest(const CHAR *name, UINT64 millisecond)589 UINT32 LOS_PmTimeLockRequest(const CHAR *name, UINT64 millisecond)
590 {
591 UINT32 ticks;
592 UINT16 swtmrID;
593 UINT32 ret;
594
595 if ((name == NULL) || !millisecond) {
596 return LOS_EINVAL;
597 }
598
599 ticks = (UINT32)((millisecond + OS_MS_PER_TICK - 1) / OS_MS_PER_TICK);
600 #if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1)
601 ret = LOS_SwtmrCreate(ticks, LOS_SWTMR_MODE_ONCE, OsPmSwtmrHandler, &swtmrID, (UINT32)(UINTPTR)name,
602 OS_SWTMR_ROUSES_ALLOW, OS_SWTMR_ALIGN_INSENSITIVE);
603 #else
604 ret = LOS_SwtmrCreate(ticks, LOS_SWTMR_MODE_ONCE, OsPmSwtmrHandler, &swtmrID, (UINT32)(UINTPTR)name);
605 #endif
606 if (ret != LOS_OK) {
607 return ret;
608 }
609
610 ret = OsPmLockRequest(name, swtmrID);
611 if (ret != LOS_OK) {
612 (VOID)LOS_SwtmrDelete(swtmrID);
613 return ret;
614 }
615
616 ret = LOS_SwtmrStart(swtmrID);
617 if (ret != LOS_OK) {
618 (VOID)LOS_PmLockRelease(name);
619 }
620
621 return ret;
622 }
623
LOS_PmReadLocknull624 UINT32 LOS_PmReadLock(VOID)
625 {
626 UINT32 ret = LOS_EventRead(&g_pmEvent, PM_EVENT_LOCK_MASK, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER);
627 if (ret > PM_EVENT_LOCK_MASK) {
628 PRINT_ERR("%s event read failed! ERROR: 0x%x\n", __FUNCTION__, ret);
629 }
630
631 return LOS_OK;
632 }
633
LOS_PmSuspend(UINT32 wakeCount)634 UINT32 LOS_PmSuspend(UINT32 wakeCount)
635 {
636 (VOID)wakeCount;
637 return OsPmSuspendSleep(&g_pmCB);
638 }
639
OsIsPmModenull640 BOOL OsIsPmMode(VOID)
641 {
642 LosPmCB *pm = &g_pmCB;
643
644 LOS_SpinLock(&g_pmSpin);
645 if ((pm->sysMode != LOS_SYS_NORMAL_SLEEP) && (pm->lock == 0)) {
646 LOS_SpinUnlock(&g_pmSpin);
647 return TRUE;
648 }
649 LOS_SpinUnlock(&g_pmSpin);
650 return FALSE;
651 }
652
OsPmSuspendDefaultHandlernull653 STATIC UINT32 OsPmSuspendDefaultHandler(VOID)
654 {
655 PRINTK("Enter pm default handler!!!\n");
656 WFI;
657 return LOS_OK;
658 }
659
OsPmSysctrlInitnull660 STATIC VOID OsPmSysctrlInit(VOID)
661 {
662 /* Default handler functions, which are implemented by the product */
663 g_sysctrl.early = NULL;
664 g_sysctrl.late = NULL;
665 g_sysctrl.normalSuspend = OsPmSuspendDefaultHandler;
666 g_sysctrl.normalResume = NULL;
667 g_sysctrl.lightSuspend = OsPmSuspendDefaultHandler;
668 g_sysctrl.lightResume = NULL;
669 g_sysctrl.deepSuspend = OsPmSuspendDefaultHandler;
670 g_sysctrl.deepResume = NULL;
671 g_sysctrl.shutdownSuspend = NULL;
672 g_sysctrl.shutdownResume = NULL;
673 }
674
OsPmInitnull675 UINT32 OsPmInit(VOID)
676 {
677 LosPmCB *pm = &g_pmCB;
678
679 (VOID)memset_s(pm, sizeof(LosPmCB), 0, sizeof(LosPmCB));
680
681 pm->pmMode = LOS_SYS_NORMAL_SLEEP;
682 LOS_ListInit(&pm->lockList);
683 (VOID)LOS_EventInit(&g_pmEvent);
684
685 OsPmSysctrlInit();
686 pm->sysctrl = &g_sysctrl;
687 return LOS_OK;
688 }
689
690 LOS_MODULE_INIT(OsPmInit, LOS_INIT_LEVEL_KMOD_EXTENDED);
691 #endif
692