1 /* 2 * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: qdf_lock.h 22 * This file abstracts locking operations. 23 */ 24 25 #ifndef _QDF_LOCK_H 26 #define _QDF_LOCK_H 27 28 #include <qdf_types.h> 29 #include <qdf_mem.h> 30 #include <qdf_time.h> 31 #include <i_qdf_trace.h> 32 33 #ifndef QDF_LOCK_STATS 34 #define QDF_LOCK_STATS 0 35 #endif 36 #ifndef QDF_LOCK_STATS_DESTROY_PRINT 37 #define QDF_LOCK_STATS_DESTROY_PRINT 0 38 #endif 39 #ifndef QDF_LOCK_STATS_BUG_ON 40 #define QDF_LOCK_STATS_BUG_ON 0 41 #endif 42 #ifndef QDF_LOCK_STATS_LIST 43 #define QDF_LOCK_STATS_LIST 0 44 #endif 45 46 /* Max hold time in micro seconds, 0 to disable detection*/ 47 #ifdef VCPU_TIMESTOLEN 48 #define QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK_IRQ 400000 49 #else 50 #define QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK_IRQ 10000 51 #endif 52 #define QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK 0 53 54 #if QDF_LOCK_STATS 55 #define QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK_BH 2000000 56 #else 57 #define QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK_BH 1000000 58 #endif 59 60 #if !QDF_LOCK_STATS 61 struct lock_stats {}; 62 #define BEFORE_LOCK(x...) do {} while (0) 63 #define AFTER_LOCK(x...) do {} while (0) 64 #define BEFORE_TRYLOCK(x...) do {} while (0) 65 #define AFTER_TRYLOCK(x...) do {} while (0) 66 #define BEFORE_UNLOCK(x...) do {} while (0) 67 #define qdf_lock_stats_create(x...) do {} while (0) 68 #define qdf_lock_stats_destroy(x...) do {} while (0) 69 #define qdf_lock_stats_init(x...) do {} while (0) 70 #define qdf_lock_stats_deinit(x...) do {} while (0) 71 #else 72 void qdf_lock_stats_init(void); 73 void qdf_lock_stats_deinit(void); 74 struct qdf_lock_cookie; 75 struct lock_stats { 76 const char *initialization_fn; 77 const char *acquired_by; 78 int line; 79 int acquired; 80 int contended; 81 uint64_t contention_time; 82 uint64_t non_contention_time; 83 uint64_t held_time; 84 uint64_t last_acquired; 85 uint64_t max_contention_wait; 86 uint64_t max_held_time; 87 int num_large_contentions; 88 int num_large_holds; 89 struct qdf_lock_cookie *cookie; 90 }; 91 #define LARGE_CONTENTION QDF_LOG_TIMESTAMP_CYCLES_PER_10_US 92 93 #define BEFORE_LOCK(lock, was_locked) \ 94 do { \ 95 uint64_t BEFORE_LOCK_time; \ 96 uint64_t AFTER_LOCK_time; \ 97 bool BEFORE_LOCK_is_locked = was_locked; \ 98 BEFORE_LOCK_time = qdf_get_log_timestamp_lightweight(); \ 99 do {} while (0) 100 101 102 #define AFTER_LOCK(lock, func) \ 103 lock->stats.acquired_by = func; \ 104 AFTER_LOCK_time = qdf_get_log_timestamp_lightweight(); \ 105 lock->stats.acquired++; \ 106 lock->stats.last_acquired = AFTER_LOCK_time; \ 107 if (BEFORE_LOCK_is_locked) { \ 108 lock->stats.contended++; \ 109 lock->stats.contention_time += \ 110 (AFTER_LOCK_time - BEFORE_LOCK_time); \ 111 } else { \ 112 lock->stats.non_contention_time += \ 113 (AFTER_LOCK_time - BEFORE_LOCK_time); \ 114 } \ 115 \ 116 if (AFTER_LOCK_time - BEFORE_LOCK_time > LARGE_CONTENTION) \ 117 lock->stats.num_large_contentions++; \ 118 \ 119 if (AFTER_LOCK_time - BEFORE_LOCK_time > \ 120 lock->stats.max_contention_wait) \ 121 lock->stats.max_contention_wait = \ 122 AFTER_LOCK_time - BEFORE_LOCK_time; \ 123 } while (0) 124 125 #define BEFORE_TRYLOCK(lock) \ 126 do { \ 127 uint64_t BEFORE_LOCK_time; \ 128 uint64_t AFTER_LOCK_time; \ 129 BEFORE_LOCK_time = qdf_get_log_timestamp_lightweight(); \ 130 do {} while (0) 131 132 #define AFTER_TRYLOCK(lock, trylock_return, func) \ 133 AFTER_LOCK_time = qdf_get_log_timestamp_lightweight(); \ 134 if (trylock_return) { \ 135 lock->stats.acquired++; \ 136 lock->stats.last_acquired = AFTER_LOCK_time; \ 137 lock->stats.non_contention_time += \ 138 (AFTER_LOCK_time - BEFORE_LOCK_time); \ 139 lock->stats.acquired_by = func; \ 140 } \ 141 } while (0) 142 143 /* max_hold_time in US */ 144 #define BEFORE_UNLOCK(lock, max_hold_time) \ 145 do {\ 146 uint64_t BEFORE_UNLOCK_time; \ 147 uint64_t held_time; \ 148 BEFORE_UNLOCK_time = qdf_get_log_timestamp_lightweight(); \ 149 \ 150 if (unlikely(BEFORE_UNLOCK_time < lock->stats.last_acquired)) \ 151 held_time = 0; \ 152 else \ 153 held_time = BEFORE_UNLOCK_time - lock->stats.last_acquired; \ 154 \ 155 lock->stats.held_time += held_time; \ 156 \ 157 if (held_time > lock->stats.max_held_time) \ 158 lock->stats.max_held_time = held_time; \ 159 \ 160 if (held_time > LARGE_CONTENTION) \ 161 lock->stats.num_large_holds++; \ 162 if (QDF_LOCK_STATS_BUG_ON && max_hold_time && \ 163 held_time > qdf_usecs_to_log_timestamp(max_hold_time)) { \ 164 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, \ 165 "BEFORE_UNLOCK: lock held too long (%lluus)", \ 166 qdf_log_timestamp_to_usecs(held_time)); \ 167 QDF_BUG(0); \ 168 } \ 169 lock->stats.acquired_by = NULL; \ 170 } while (0) 171 172 void qdf_lock_stats_cookie_destroy(struct lock_stats *stats); 173 void qdf_lock_stats_cookie_create(struct lock_stats *stats, 174 const char *func, int line); 175 qdf_lock_stats_destroy(struct lock_stats * stats)176 static inline void qdf_lock_stats_destroy(struct lock_stats *stats) 177 { 178 if (QDF_LOCK_STATS_DESTROY_PRINT) { 179 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG, 180 "%s: lock: %s %d \t" 181 "acquired:\t%d\tcontended:\t%d\t" 182 "contention_time\t%llu\tmax_contention_wait:\t%llu\t" 183 "non_contention_time\t%llu\t" 184 "held_time\t%llu\tmax_held:\t%llu" 185 , __func__, stats->initialization_fn, stats->line, 186 stats->acquired, stats->contended, 187 qdf_log_timestamp_to_usecs(stats->contention_time), 188 qdf_log_timestamp_to_usecs(stats->max_contention_wait), 189 qdf_log_timestamp_to_usecs(stats->non_contention_time), 190 qdf_log_timestamp_to_usecs(stats->held_time), 191 qdf_log_timestamp_to_usecs(stats->max_held_time)); 192 } 193 194 if (QDF_LOCK_STATS_LIST) 195 qdf_lock_stats_cookie_destroy(stats); 196 } 197 198 #ifndef MEMORY_DEBUG 199 #define qdf_mem_malloc_debug(x, y, z) qdf_mem_malloc(x) 200 #endif 201 202 /** 203 * qdf_lock_stats_create() - initialize the lock stats structure 204 * @stats: stats to initialize 205 * @func: calling function 206 * @line: calling line number 207 */ qdf_lock_stats_create(struct lock_stats * stats,const char * func,int line)208 static inline void qdf_lock_stats_create(struct lock_stats *stats, 209 const char *func, int line) 210 { 211 qdf_mem_zero(stats, sizeof(*stats)); 212 stats->initialization_fn = func; 213 stats->line = line; 214 215 if (QDF_LOCK_STATS_LIST) 216 qdf_lock_stats_cookie_create(stats, func, line); 217 } 218 #endif 219 220 #include <i_qdf_lock.h> 221 222 #define WIFI_POWER_EVENT_DEFAULT_WAKELOCK_TIMEOUT 0 223 #define WIFI_POWER_EVENT_WAKELOCK_TAKEN 0 224 #define WIFI_POWER_EVENT_WAKELOCK_RELEASED 1 225 226 /** 227 * qdf_semaphore_acquire_timeout() - Take the semaphore before timeout 228 * @m: semaphore to take 229 * @timeout: maximum time to try to take the semaphore 230 * 231 * Return: int 232 */ qdf_semaphore_acquire_timeout(struct semaphore * m,unsigned long timeout)233 static inline int qdf_semaphore_acquire_timeout(struct semaphore *m, 234 unsigned long timeout) 235 { 236 return __qdf_semaphore_acquire_timeout(m, timeout); 237 } 238 239 struct qdf_spinlock { 240 __qdf_spinlock_t lock; 241 struct lock_stats stats; 242 }; 243 244 /** 245 * typedef qdf_spinlock_t - Abstracted spinlock object 246 * 247 * Abstracted object. Clients must not make any assumptions about the 248 * composition of this object 249 */ 250 typedef struct qdf_spinlock qdf_spinlock_t; 251 252 /** 253 * typedef qdf_semaphore_t - Abstracted semaphore object 254 * 255 * Abstracted object. Clients must not make any assumptions about the 256 * composition of this object 257 */ 258 typedef __qdf_semaphore_t qdf_semaphore_t; 259 260 /** 261 * typedef qdf_mutex_t - Abstracted mutex object 262 * 263 * Abstracted object. Clients must not make any assumptions about the 264 * composition of this object 265 */ 266 typedef __qdf_mutex_t qdf_mutex_t; 267 268 QDF_STATUS qdf_mutex_create(qdf_mutex_t *lock, const char *func, int line); 269 270 /** 271 * qdf_mutex_create() - Initialize a mutex 272 * @lock: pointer to the qdf_mutex_t mutex to initialize 273 * 274 * Return: QDF_STATUS_SUCCESS on success, else QDF_STATUS failure 275 */ 276 #define qdf_mutex_create(lock) qdf_mutex_create(lock, __func__, __LINE__) 277 278 /** 279 * qdf_mutex_acquire() - acquire a QDF lock 280 * @lock: Pointer to the opaque lock object to acquire 281 * 282 * A lock object is acquired by calling qdf_mutex_acquire(). If the lock 283 * is already locked, the calling thread shall block until the lock becomes 284 * available. This operation shall return with the lock object referenced by 285 * lock in the locked state with the calling thread as its owner. 286 * 287 * Return: 288 * QDF_STATUS_SUCCESS if lock was successfully initialized 289 * QDF failure reason codes if lock is not initialized and can't be used 290 */ 291 QDF_STATUS qdf_mutex_acquire(qdf_mutex_t *lock); 292 293 /** 294 * qdf_mutex_release() - release a QDF lock 295 * @lock: Pointer to the opaque lock object to be released 296 * 297 * qdf_mutex_release() function shall release the lock object 298 * referenced by 'lock'. 299 * 300 * If a thread attempts to release a lock that it unlocked or is not 301 * initialized, an error is returned. 302 * 303 * Return: 304 * QDF_STATUS_SUCCESS if lock was successfully initialized 305 * QDF failure reason codes if lock is not initialized and can't be used 306 */ 307 QDF_STATUS qdf_mutex_release(qdf_mutex_t *lock); 308 309 /** 310 * qdf_mutex_destroy() - destroy a QDF lock 311 * @lock: Pointer to the opaque lock object to be destroyed 312 * 313 * function shall destroy the lock object referenced by lock. After a 314 * successful return from qdf_mutex_destroy() 315 * the lock object becomes, in effect, uninitialized. 316 * 317 * A destroyed lock object can be reinitialized using qdf_mutex_create(); 318 * the results of otherwise referencing the object after it has been destroyed 319 * are undefined. Calls to QDF lock functions to manipulate the lock such 320 * as qdf_mutex_acquire() will fail if the lock is destroyed. Therefore, 321 * don't use the lock after it has been destroyed until it has 322 * been re-initialized. 323 * 324 * Return: 325 * QDF_STATUS_SUCCESS if lock was successfully initialized 326 * QDF failure reason codes if lock is not initialized and can't be used 327 */ 328 QDF_STATUS qdf_mutex_destroy(qdf_mutex_t *lock); 329 qdf_spinlock_create(qdf_spinlock_t * lock,const char * func,int line)330 static inline void qdf_spinlock_create(qdf_spinlock_t *lock, const char *func, 331 int line) 332 { 333 __qdf_spinlock_create(&lock->lock); 334 335 /* spinlock stats create relies on the spinlock working allread */ 336 qdf_lock_stats_create(&lock->stats, func, line); 337 } 338 339 /** 340 * qdf_spinlock_create() - Initialize a spinlock 341 * @lock: spinlock object pointer 342 * 343 * Return: none 344 */ 345 #define qdf_spinlock_create(lock) qdf_spinlock_create(lock, __func__, __LINE__) 346 347 /** 348 * qdf_spinlock_destroy() - Delete a spinlock 349 * @lock: spinlock object pointer 350 * 351 * Return: none 352 */ qdf_spinlock_destroy(qdf_spinlock_t * lock)353 static inline void qdf_spinlock_destroy(qdf_spinlock_t *lock) 354 { 355 qdf_lock_stats_destroy(&lock->stats); 356 __qdf_spinlock_destroy(&lock->lock); 357 } 358 359 /** 360 * qdf_spin_is_locked() - check if the spinlock is locked 361 * @lock: spinlock object 362 * 363 * Return: nonzero if lock is held. 364 */ qdf_spin_is_locked(qdf_spinlock_t * lock)365 static inline int qdf_spin_is_locked(qdf_spinlock_t *lock) 366 { 367 return __qdf_spin_is_locked(&lock->lock); 368 } 369 qdf_spin_trylock_bh(qdf_spinlock_t * lock,const char * func)370 static inline int qdf_spin_trylock_bh(qdf_spinlock_t *lock, const char *func) 371 { 372 int trylock_return; 373 374 BEFORE_TRYLOCK(lock); 375 trylock_return = __qdf_spin_trylock_bh(&lock->lock); 376 AFTER_TRYLOCK(lock, trylock_return, func); 377 378 return trylock_return; 379 } 380 381 /** 382 * qdf_spin_trylock_bh() - spin trylock bottomhalf 383 * @lock: spinlock object 384 * 385 * Return: nonzero if lock is acquired 386 */ 387 #define qdf_spin_trylock_bh(lock) qdf_spin_trylock_bh(lock, __func__) 388 qdf_spin_trylock(qdf_spinlock_t * lock,const char * func)389 static inline int qdf_spin_trylock(qdf_spinlock_t *lock, const char *func) 390 { 391 int result = 0; 392 393 BEFORE_LOCK(lock, qdf_spin_is_locked(lock)); 394 result = __qdf_spin_trylock(&lock->lock); 395 AFTER_LOCK(lock, func); 396 397 return result; 398 } 399 400 /** 401 * qdf_spin_trylock() - spin trylock 402 * @lock: spinlock object 403 * 404 * Return: nonzero if lock is acquired 405 */ 406 #define qdf_spin_trylock(lock) qdf_spin_trylock(lock, __func__) 407 qdf_spin_lock_bh(qdf_spinlock_t * lock,const char * func)408 static inline void qdf_spin_lock_bh(qdf_spinlock_t *lock, const char *func) 409 { 410 BEFORE_LOCK(lock, qdf_spin_is_locked(lock)); 411 __qdf_spin_lock_bh(&lock->lock); 412 AFTER_LOCK(lock, func); 413 } 414 415 /** 416 * qdf_spin_lock_bh() - locks the spinlock mutex in soft irq context 417 * @lock: spinlock object pointer 418 * 419 * Return: none 420 */ 421 #define qdf_spin_lock_bh(lock) qdf_spin_lock_bh(lock, __func__) 422 423 /** 424 * qdf_spin_unlock_bh() - unlocks the spinlock mutex in soft irq context 425 * @lock: spinlock object pointer 426 * 427 * Return: none 428 */ qdf_spin_unlock_bh(qdf_spinlock_t * lock)429 static inline void qdf_spin_unlock_bh(qdf_spinlock_t *lock) 430 { 431 BEFORE_UNLOCK(lock, QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK_BH); 432 __qdf_spin_unlock_bh(&lock->lock); 433 } 434 435 /** 436 * qdf_spinlock_irq_exec() - Execute the input function with spinlock held 437 * and interrupt disabled. 438 * @hdl: OS handle 439 * @lock: spinlock to be held for the critical region 440 * @func: critical region function that to be executed 441 * @arg: argument of the critical region function 442 * 443 * Return: Boolean status returned by the critical region function 444 */ qdf_spinlock_irq_exec(qdf_handle_t hdl,qdf_spinlock_t * lock,qdf_irqlocked_func_t func,void * arg)445 static inline bool qdf_spinlock_irq_exec(qdf_handle_t hdl, 446 qdf_spinlock_t *lock, 447 qdf_irqlocked_func_t func, void *arg) 448 { 449 return __qdf_spinlock_irq_exec(hdl, &lock->lock, func, arg); 450 } 451 qdf_spin_lock(qdf_spinlock_t * lock,const char * func)452 static inline void qdf_spin_lock(qdf_spinlock_t *lock, const char *func) 453 { 454 BEFORE_LOCK(lock, qdf_spin_is_locked(lock)); 455 __qdf_spin_lock(&lock->lock); 456 AFTER_LOCK(lock, func); 457 } 458 459 /** 460 * qdf_spin_lock() - Acquire a Spinlock(SMP) & disable Preemption (Preemptive) 461 * @lock: Lock object 462 * 463 * Return: none 464 */ 465 #define qdf_spin_lock(lock) qdf_spin_lock(lock, __func__) 466 467 /** 468 * qdf_spin_unlock() - Unlock the spinlock and enables the Preemption 469 * @lock: Lock object 470 * 471 * Return: none 472 */ qdf_spin_unlock(qdf_spinlock_t * lock)473 static inline void qdf_spin_unlock(qdf_spinlock_t *lock) 474 { 475 BEFORE_UNLOCK(lock, QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK); 476 __qdf_spin_unlock(&lock->lock); 477 } 478 qdf_spin_lock_irq(qdf_spinlock_t * lock,unsigned long flags,const char * func)479 static inline void qdf_spin_lock_irq(qdf_spinlock_t *lock, unsigned long flags, 480 const char *func) 481 { 482 BEFORE_LOCK(lock, qdf_spin_is_locked(lock)); 483 __qdf_spin_lock_irq(&lock->lock.spinlock, flags); 484 AFTER_LOCK(lock, func); 485 } 486 487 /** 488 * qdf_spin_lock_irq() - Acquire a Spinlock(SMP) & save the irq state 489 * @lock: Lock object 490 * @flags: flags 491 * 492 * Return: none 493 */ 494 #define qdf_spin_lock_irq(lock, flags) qdf_spin_lock_irq(lock, flags, __func__) 495 qdf_spin_lock_irqsave(qdf_spinlock_t * lock,const char * func)496 static inline void qdf_spin_lock_irqsave(qdf_spinlock_t *lock, const char *func) 497 { 498 BEFORE_LOCK(lock, qdf_spin_is_locked(lock)); 499 __qdf_spin_lock_irqsave(&lock->lock); 500 AFTER_LOCK(lock, func); 501 } 502 503 /** 504 * qdf_spin_lock_irqsave() - Acquire a Spinlock (SMP) & disable Preemption 505 * (Preemptive) and disable IRQs 506 * @lock: Lock object 507 * 508 * Return: none 509 */ 510 #define qdf_spin_lock_irqsave(lock) qdf_spin_lock_irqsave(lock, __func__) 511 512 /** 513 * qdf_spin_unlock_irqrestore() - Unlock the spinlock and enables the 514 * Preemption and enable IRQ 515 * @lock: Lock object 516 * 517 * Return: none 518 */ qdf_spin_unlock_irqrestore(qdf_spinlock_t * lock)519 static inline void qdf_spin_unlock_irqrestore(qdf_spinlock_t *lock) 520 { 521 BEFORE_UNLOCK(lock, QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK_IRQ); 522 __qdf_spin_unlock_irqrestore(&lock->lock); 523 } 524 525 /** 526 * qdf_spin_unlock_irq() - Unlock a Spinlock(SMP) & save the restore state 527 * @lock: Lock object 528 * @flags: flags 529 * 530 * Return: none 531 */ qdf_spin_unlock_irq(qdf_spinlock_t * lock,unsigned long flags)532 static inline void qdf_spin_unlock_irq(qdf_spinlock_t *lock, 533 unsigned long flags) 534 { 535 BEFORE_UNLOCK(lock, QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK_IRQ); 536 __qdf_spin_unlock_irq(&lock->lock.spinlock, flags); 537 } 538 539 /** 540 * qdf_semaphore_init() - initialize a semaphore 541 * @m: Semaphore to initialize 542 * Return: None 543 */ qdf_semaphore_init(qdf_semaphore_t * m)544 static inline void qdf_semaphore_init(qdf_semaphore_t *m) 545 { 546 __qdf_semaphore_init(m); 547 } 548 549 /** 550 * qdf_semaphore_acquire() - take the semaphore 551 * @m: Semaphore to take 552 * 553 * Return: int 554 */ qdf_semaphore_acquire(qdf_semaphore_t * m)555 static inline int qdf_semaphore_acquire(qdf_semaphore_t *m) 556 { 557 return __qdf_semaphore_acquire(m); 558 } 559 560 /** 561 * qdf_semaphore_release() - give the semaphore 562 * @m: Semaphore to give 563 * 564 * Return: None 565 */ qdf_semaphore_release(qdf_semaphore_t * m)566 static inline void qdf_semaphore_release(qdf_semaphore_t *m) 567 { 568 __qdf_semaphore_release(m); 569 } 570 571 /** 572 * qdf_semaphore_acquire_intr() - Take the semaphore, interruptible 573 * @m: mutex to take 574 * 575 * This function allows a user-space process that is waiting on a 576 * semaphore to be interrupted by the user. If the operation is 577 * interrupted, the function returns a nonzero value, and the caller 578 * does not hold the semaphore. Always check the return value and 579 * responding accordingly. 580 * 581 * Return: 0 if the semaphore was acquired, non-zero if not acquired 582 */ qdf_semaphore_acquire_intr(qdf_semaphore_t * m)583 static inline int qdf_semaphore_acquire_intr(qdf_semaphore_t *m) 584 { 585 return __qdf_semaphore_acquire_intr(m); 586 } 587 588 #ifdef WLAN_WAKE_LOCK_DEBUG 589 /** 590 * qdf_wake_lock_check_for_leaks() - assert no wake lock leaks 591 * 592 * Return: None 593 */ 594 void qdf_wake_lock_check_for_leaks(void); 595 596 /** 597 * qdf_wake_lock_feature_init() - global init logic for wake lock 598 * 599 * Return: None 600 */ 601 void qdf_wake_lock_feature_init(void); 602 603 /** 604 * qdf_wake_lock_feature_deinit() - global de-init logic for wake lock 605 * 606 * Return: None 607 */ 608 void qdf_wake_lock_feature_deinit(void); 609 #else qdf_wake_lock_check_for_leaks(void)610 static inline void qdf_wake_lock_check_for_leaks(void) { } qdf_wake_lock_feature_init(void)611 static inline void qdf_wake_lock_feature_init(void) { } qdf_wake_lock_feature_deinit(void)612 static inline void qdf_wake_lock_feature_deinit(void) { } 613 #endif /* WLAN_WAKE_LOCK_DEBUG */ 614 615 /** 616 * __qdf_wake_lock_create() - initialize a wake lock 617 * @lock: The wake lock to initialize 618 * @name: Name of wake lock 619 * @func: caller function 620 * @line: caller line 621 * Return: 622 * QDF status success if wake lock is initialized 623 * QDF status failure if wake lock was not initialized 624 */ 625 QDF_STATUS __qdf_wake_lock_create(qdf_wake_lock_t *lock, const char *name, 626 const char *func, uint32_t line); 627 628 /** 629 * qdf_wake_lock_create() - initialized a wakeup source lock 630 * @lock: the wakeup source lock to initialize 631 * @name: the name of wakeup source lock 632 * 633 * Return: QDF_STATUS 634 */ 635 #define qdf_wake_lock_create(lock, name) \ 636 __qdf_wake_lock_create(lock, name, __func__, __LINE__) 637 638 /** 639 * qdf_wake_lock_acquire() - acquires a wake lock 640 * @lock: The wake lock to acquire 641 * @reason: Reason for wakelock 642 * 643 * Return: 644 * QDF status success if wake lock is acquired 645 * QDF status failure if wake lock was not acquired 646 */ 647 QDF_STATUS qdf_wake_lock_acquire(qdf_wake_lock_t *lock, uint32_t reason); 648 649 /** 650 * qdf_wake_lock_name() - This function returns the name of the wakelock 651 * @lock: Pointer to the wakelock 652 * 653 * This function returns the name of the wakelock 654 * 655 * Return: Pointer to the name if it is valid or a default string 656 */ 657 const char *qdf_wake_lock_name(qdf_wake_lock_t *lock); 658 659 /** 660 * qdf_wake_lock_timeout_acquire() - acquires a wake lock with a timeout 661 * @lock: The wake lock to acquire 662 * @msec: timeout in ms (0 for no timeout) 663 * 664 * Return: 665 * QDF status success if wake lock is acquired 666 * QDF status failure if wake lock was not acquired 667 */ 668 QDF_STATUS qdf_wake_lock_timeout_acquire(qdf_wake_lock_t *lock, 669 uint32_t msec); 670 671 /** 672 * qdf_wake_lock_release() - releases a wake lock 673 * @lock: the wake lock to release 674 * @reason: Reason for wakelock 675 * 676 * Return: 677 * QDF status success if wake lock is acquired 678 * QDF status failure if wake lock was not acquired 679 */ 680 QDF_STATUS qdf_wake_lock_release(qdf_wake_lock_t *lock, uint32_t reason); 681 682 /** 683 * __qdf_wake_lock_destroy() - destroy a wake lock 684 * @lock: The wake lock to destroy 685 * @func: caller function 686 * @line: caller line 687 * 688 * Return: None 689 */ 690 void __qdf_wake_lock_destroy(qdf_wake_lock_t *lock, 691 const char *func, uint32_t line); 692 693 /** 694 * qdf_wake_lock_destroy() - deinitialize a wakeup source lock 695 * @lock: the wakeup source lock to de-initialize 696 * 697 * Return: None 698 */ 699 #define qdf_wake_lock_destroy(lock) \ 700 __qdf_wake_lock_destroy(lock, __func__, __LINE__) 701 702 /** 703 * qdf_pm_system_wakeup() - wakeup system 704 * 705 * Return: None 706 */ 707 void qdf_pm_system_wakeup(void); 708 709 /** 710 * qdf_spinlock_acquire() - acquires a spin lock 711 * @lock: Spin lock to acquire 712 * 713 * Return: QDF status success if wake lock is acquired 714 */ 715 QDF_STATUS qdf_spinlock_acquire(qdf_spinlock_t *lock); 716 717 /** 718 * qdf_spinlock_release() - release a spin lock 719 * @lock: Spin lock to release 720 * 721 * Return: QDF status success if wake lock is acquired 722 */ 723 QDF_STATUS qdf_spinlock_release(qdf_spinlock_t *lock); 724 725 /** 726 * enum qdf_rtpm_call_type - Get and Put calls types 727 * @QDF_RTPM_GET: Increment usage count and when system is suspended 728 * schedule resume process, return depends on pm state. 729 * @QDF_RTPM_GET_FORCE: Increment usage count and when system is suspended 730 * schedule resume process, returns success irrespective of 731 * pm_state. 732 * @QDF_RTPM_GET_SYNC: Increment usage count and when system is suspended, 733 * wait till process is resumed. 734 * @QDF_RTPM_GET_NORESUME: Only increments usage count. 735 * @QDF_RTPM_PUT: Decrements usage count and puts system in idle state. 736 * @QDF_RTPM_PUT_SYNC_SUSPEND: Decrements usage count and puts system in 737 * suspended state. 738 * @QDF_RTPM_PUT_NOIDLE: Decrements usage count. 739 */ 740 enum qdf_rtpm_call_type { 741 QDF_RTPM_GET, 742 QDF_RTPM_GET_FORCE, 743 QDF_RTPM_GET_SYNC, 744 QDF_RTPM_GET_NORESUME, 745 QDF_RTPM_PUT, 746 QDF_RTPM_PUT_SYNC_SUSPEND, 747 QDF_RTPM_PUT_NOIDLE, 748 }; 749 750 /** 751 * enum qdf_rtpm_client_id - modules registered with runtime pm module 752 * @QDF_RTPM_ID_RESERVED: Reserved ID 753 * @QDF_RTPM_ID_PM_QOS_NOTIFY: PM QOS context 754 * @QDF_RTPM_ID_WIPHY_SUSPEND: APSS Bus suspend context 755 * @QDF_RTPM_ID_MAX: Max id 756 */ 757 enum qdf_rtpm_client_id { 758 QDF_RTPM_ID_RESERVED, 759 QDF_RTPM_ID_PM_QOS_NOTIFY, 760 QDF_RTPM_ID_WIPHY_SUSPEND, 761 QDF_RTPM_ID_MAX 762 }; 763 764 /** 765 * qdf_runtime_lock_init() - initialize runtime lock 766 * @lock: the lock to initialize 767 * 768 * Initialize a runtime pm lock. This lock can be used 769 * to prevent the runtime pm system from putting the bus 770 * to sleep. 771 * 772 * Return: Success if lock initialized 773 */ 774 #define qdf_runtime_lock_init(lock) __qdf_runtime_lock_init(lock, #lock) 775 776 #ifdef FEATURE_RUNTIME_PM 777 /** 778 * qdf_rtpm_register() - QDF wrapper to register a module with runtime PM. 779 * @id: ID of the module which needs to be registered 780 * @hif_rpm_cbk: callback to be called when get was called in suspended state. 781 * 782 * Return: success status if registered 783 */ 784 QDF_STATUS qdf_rtpm_register(uint32_t id, void (*hif_rpm_cbk)(void)); 785 786 /** 787 * qdf_rtpm_deregister() - QDF wrapper to deregister the module 788 * @id: ID of the module which needs to be de-registered 789 * 790 * Return: success status if successfully de-registered 791 */ 792 QDF_STATUS qdf_rtpm_deregister(uint32_t id); 793 794 /** 795 * __qdf_runtime_lock_init() - initialize runtime lock 796 * @lock: the lock to initialize 797 * @name: name of the runtime lock 798 * 799 * Initialize a runtime pm lock. This lock can be used 800 * to prevent the runtime pm system from putting the bus 801 * to sleep. 802 * 803 * Return: Success if lock initialized 804 */ 805 QDF_STATUS __qdf_runtime_lock_init(qdf_runtime_lock_t *lock, const char *name); 806 807 /** 808 * qdf_runtime_lock_deinit() - deinitialize runtime pm lock 809 * @lock: the lock to deinitialize 810 * 811 * Ensures the lock is released. Frees the runtime lock. 812 * 813 * Return: void 814 */ 815 void qdf_runtime_lock_deinit(qdf_runtime_lock_t *lock); 816 817 /** 818 * qdf_rtpm_get() - Increment usage_count on the device to avoid suspend. 819 * @type: get call types from hif_rpm_type 820 * @id: ID of the module calling qdf_rtpm_get() 821 * 822 * Return: success if a get has been issued, else error code. 823 */ 824 QDF_STATUS qdf_rtpm_get(uint8_t type, uint32_t id); 825 826 /** 827 * qdf_rtpm_put() - Decrement usage_count on the device to avoid suspend. 828 * @type: put call types from hif_rpm_type 829 * @id: ID of the module calling qdf_rtpm_put() 830 * 831 * Return: success if a put has been issued, else error code. 832 */ 833 QDF_STATUS qdf_rtpm_put(uint8_t type, uint32_t id); 834 835 /** 836 * qdf_runtime_pm_prevent_suspend() - Prevent Runtime suspend 837 * @lock: runtime PM lock 838 * 839 * This function will prevent runtime suspend, by incrementing 840 * device's usage count. 841 * 842 * Return: status 843 */ 844 QDF_STATUS qdf_runtime_pm_prevent_suspend(qdf_runtime_lock_t *lock); 845 846 /** 847 * qdf_runtime_pm_prevent_suspend_sync() - Synchronized Prevent Runtime suspend 848 * @lock: runtime PM lock 849 * 850 * This function will prevent runtime suspend, by incrementing 851 * device's usage count and waits till system is in resumed state. 852 * 853 * Return: status 854 */ 855 QDF_STATUS qdf_runtime_pm_prevent_suspend_sync(qdf_runtime_lock_t *lock); 856 857 /** 858 * qdf_runtime_pm_allow_suspend() - Allow Runtime suspend 859 * @lock: runtime PM lock 860 * 861 * This function will allow runtime suspend, by decrementing 862 * device's usage count. 863 * 864 * Return: status 865 */ 866 QDF_STATUS qdf_runtime_pm_allow_suspend(qdf_runtime_lock_t *lock); 867 868 /** 869 * qdf_rtpm_sync_resume() - Invoke synchronous runtime resume. 870 * 871 * This function will invoke synchronous runtime resume. 872 * 873 * Return: Success if state is ON 874 */ 875 QDF_STATUS qdf_rtpm_sync_resume(void); 876 877 #else 878 static inline qdf_rtpm_register(uint32_t id,void (* hif_rpm_cbk)(void))879 QDF_STATUS qdf_rtpm_register(uint32_t id, void (*hif_rpm_cbk)(void)) 880 { 881 return 0; 882 } 883 884 static inline qdf_rtpm_deregister(uint32_t id)885 QDF_STATUS qdf_rtpm_deregister(uint32_t id) 886 { 887 return QDF_STATUS_SUCCESS; 888 } 889 890 static inline __qdf_runtime_lock_init(qdf_runtime_lock_t * lock,const char * name)891 QDF_STATUS __qdf_runtime_lock_init(qdf_runtime_lock_t *lock, const char *name) 892 { 893 return QDF_STATUS_SUCCESS; 894 } 895 896 static inline qdf_runtime_lock_deinit(qdf_runtime_lock_t * lock)897 void qdf_runtime_lock_deinit(qdf_runtime_lock_t *lock) 898 { 899 } 900 901 static inline qdf_rtpm_get(uint8_t type,uint32_t id)902 QDF_STATUS qdf_rtpm_get(uint8_t type, uint32_t id) 903 { 904 return QDF_STATUS_SUCCESS; 905 } 906 907 static inline qdf_rtpm_put(uint8_t type,uint32_t id)908 QDF_STATUS qdf_rtpm_put(uint8_t type, uint32_t id) 909 { 910 return QDF_STATUS_SUCCESS; 911 } 912 913 static inline qdf_runtime_pm_prevent_suspend(qdf_runtime_lock_t * lock)914 QDF_STATUS qdf_runtime_pm_prevent_suspend(qdf_runtime_lock_t *lock) 915 { 916 return QDF_STATUS_SUCCESS; 917 } 918 919 static inline qdf_runtime_pm_prevent_suspend_sync(qdf_runtime_lock_t * lock)920 QDF_STATUS qdf_runtime_pm_prevent_suspend_sync(qdf_runtime_lock_t *lock) 921 { 922 return QDF_STATUS_SUCCESS; 923 } 924 925 static inline qdf_runtime_pm_allow_suspend(qdf_runtime_lock_t * lock)926 QDF_STATUS qdf_runtime_pm_allow_suspend(qdf_runtime_lock_t *lock) 927 { 928 return QDF_STATUS_SUCCESS; 929 } 930 931 static inline qdf_rtpm_sync_resume(void)932 QDF_STATUS qdf_rtpm_sync_resume(void) 933 { 934 return QDF_STATUS_SUCCESS; 935 } 936 937 #endif /* FEATURE_RUNTIME_PM */ 938 939 #endif /* _QDF_LOCK_H */ 940