1/* 2 * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. 3 * Copyright (c) 2020, 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 "linux/wakelock.h" 33#include "los_spinlock.h" 34 35 36#define SET_BIT(bitmap, pos) ((bitmap) |= (1u << (pos))) 37#define CLEAR_BIT(bitmap, pos) ((bitmap) &= ~(1u << (pos))) 38#define CHECK_BIT(bitmap, pos) (((bitmap) & (1u << (pos))) ? 1 : 0) 39 40#define WAKELOCK_BITMAP_CNT 32 41 42/* spinlock for wake lock module only available on SMP mode */ 43LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_wakeLockSpin); 44 45typedef struct { 46 UINT32 lock; /* Indicate which bit is locked */ 47 UINT32 used; /* Indicate used bit */ 48} WakeLockBitmap; 49 50STATIC WakeLockBitmap g_wlBitmap; 51 52STATIC INT32 FindEmptyBit(UINT32 bitmap) 53{ 54 UINT32 t = 1; 55 INT32 i; 56 for (i = 0; i < WAKELOCK_BITMAP_CNT; i++) { 57 if (!(t & bitmap)) { 58 break; 59 } else { 60 t <<= 1; 61 } 62 } 63 64 if (i == WAKELOCK_BITMAP_CNT) { 65 return -1; 66 } 67 return i; 68} 69 70/* 71 * Initial a wakelock 72 * Attention: DO NOT init more than 32 wakelock! 73 */ 74void linux_wake_lock_init(struct wake_lock *lock, int type, const char *name) 75{ 76 UINT32 intSave; 77 INT32 pos; 78 (VOID)type; 79 80 if (lock == NULL) { 81 PRINT_ERR("%s : invalid parameter!\n", __FUNCTION__); 82 return; 83 } 84 85 lock->ws.name = name; 86 87 LOS_SpinLockSave(&g_wakeLockSpin, &intSave); 88 pos = FindEmptyBit(g_wlBitmap.used); 89 if (pos != -1) { 90 lock->bitmap_pos = (UINT32)pos; 91 SET_BIT(g_wlBitmap.used, lock->bitmap_pos); 92 CLEAR_BIT(g_wlBitmap.lock, lock->bitmap_pos); 93 } else { 94 LOS_SpinUnlockRestore(&g_wakeLockSpin, intSave); 95 PRINT_ERR("%s : wakelock count exceeds 32!\n", __FUNCTION__); 96 return; 97 } 98 99 LOS_SpinUnlockRestore(&g_wakeLockSpin, intSave); 100} 101 102void linux_wake_lock(struct wake_lock *lock) 103{ 104 UINT32 intSave; 105 if (lock == NULL) { 106 return; 107 } 108 109 LOS_SpinLockSave(&g_wakeLockSpin, &intSave); 110 SET_BIT(g_wlBitmap.lock, lock->bitmap_pos); 111 LOS_SpinUnlockRestore(&g_wakeLockSpin, intSave); 112} 113 114void linux_wake_unlock(struct wake_lock *lock) 115{ 116 UINT32 intSave; 117 if (lock == NULL) { 118 return; 119 } 120 121 LOS_SpinLockSave(&g_wakeLockSpin, &intSave); 122 CLEAR_BIT(g_wlBitmap.lock, lock->bitmap_pos); 123 LOS_SpinUnlockRestore(&g_wakeLockSpin, intSave); 124} 125 126/* Judge whether the wake lock is active or not */ 127int linux_wake_lock_active(struct wake_lock *lock) 128{ 129 INT32 ret; 130 UINT32 intSave; 131 if (lock == NULL) { 132 return -1; 133 } 134 LOS_SpinLockSave(&g_wakeLockSpin, &intSave); 135 ret = CHECK_BIT(g_wlBitmap.lock, lock->bitmap_pos); 136 LOS_SpinUnlockRestore(&g_wakeLockSpin, intSave); 137 return ret; 138} 139 140void linux_wake_lock_destroy(struct wake_lock *lock) 141{ 142 UINT32 intSave; 143 if (lock == NULL) { 144 return; 145 } 146 LOS_SpinLockSave(&g_wakeLockSpin, &intSave); 147 CLEAR_BIT(g_wlBitmap.used, lock->bitmap_pos); 148 CLEAR_BIT(g_wlBitmap.lock, lock->bitmap_pos); 149 LOS_SpinUnlockRestore(&g_wakeLockSpin, intSave); 150} 151 152