1 /* 2 * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022 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 * @file 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 #define QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK_IRQ 10000 48 #define QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK 0 49 50 #if QDF_LOCK_STATS 51 #define QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK_BH 2000000 52 #else 53 #define QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK_BH 1000000 54 #endif 55 56 #if !QDF_LOCK_STATS 57 struct lock_stats {}; 58 #define BEFORE_LOCK(x...) do {} while (0) 59 #define AFTER_LOCK(x...) do {} while (0) 60 #define BEFORE_TRYLOCK(x...) do {} while (0) 61 #define AFTER_TRYLOCK(x...) do {} while (0) 62 #define BEFORE_UNLOCK(x...) do {} while (0) 63 #define qdf_lock_stats_create(x...) do {} while (0) 64 #define qdf_lock_stats_destroy(x...) do {} while (0) 65 #define qdf_lock_stats_init(x...) do {} while (0) 66 #define qdf_lock_stats_deinit(x...) do {} while (0) 67 #else 68 void qdf_lock_stats_init(void); 69 void qdf_lock_stats_deinit(void); 70 struct qdf_lock_cookie; 71 struct lock_stats { 72 const char *initialization_fn; 73 const char *acquired_by; 74 int line; 75 int acquired; 76 int contended; 77 uint64_t contention_time; 78 uint64_t non_contention_time; 79 uint64_t held_time; 80 uint64_t last_acquired; 81 uint64_t max_contention_wait; 82 uint64_t max_held_time; 83 int num_large_contentions; 84 int num_large_holds; 85 struct qdf_lock_cookie *cookie; 86 }; 87 #define LARGE_CONTENTION QDF_LOG_TIMESTAMP_CYCLES_PER_10_US 88 89 #define BEFORE_LOCK(lock, was_locked) \ 90 do { \ 91 uint64_t BEFORE_LOCK_time; \ 92 uint64_t AFTER_LOCK_time; \ 93 bool BEFORE_LOCK_is_locked = was_locked; \ 94 BEFORE_LOCK_time = qdf_get_log_timestamp_lightweight(); \ 95 do {} while (0) 96 97 98 #define AFTER_LOCK(lock, func) \ 99 lock->stats.acquired_by = func; \ 100 AFTER_LOCK_time = qdf_get_log_timestamp_lightweight(); \ 101 lock->stats.acquired++; \ 102 lock->stats.last_acquired = AFTER_LOCK_time; \ 103 if (BEFORE_LOCK_is_locked) { \ 104 lock->stats.contended++; \ 105 lock->stats.contention_time += \ 106 (AFTER_LOCK_time - BEFORE_LOCK_time); \ 107 } else { \ 108 lock->stats.non_contention_time += \ 109 (AFTER_LOCK_time - BEFORE_LOCK_time); \ 110 } \ 111 \ 112 if (AFTER_LOCK_time - BEFORE_LOCK_time > LARGE_CONTENTION) \ 113 lock->stats.num_large_contentions++; \ 114 \ 115 if (AFTER_LOCK_time - BEFORE_LOCK_time > \ 116 lock->stats.max_contention_wait) \ 117 lock->stats.max_contention_wait = \ 118 AFTER_LOCK_time - BEFORE_LOCK_time; \ 119 } while (0) 120 121 #define BEFORE_TRYLOCK(lock) \ 122 do { \ 123 uint64_t BEFORE_LOCK_time; \ 124 uint64_t AFTER_LOCK_time; \ 125 BEFORE_LOCK_time = qdf_get_log_timestamp_lightweight(); \ 126 do {} while (0) 127 128 #define AFTER_TRYLOCK(lock, trylock_return, func) \ 129 AFTER_LOCK_time = qdf_get_log_timestamp_lightweight(); \ 130 if (trylock_return) { \ 131 lock->stats.acquired++; \ 132 lock->stats.last_acquired = AFTER_LOCK_time; \ 133 lock->stats.non_contention_time += \ 134 (AFTER_LOCK_time - BEFORE_LOCK_time); \ 135 lock->stats.acquired_by = func; \ 136 } \ 137 } while (0) 138 139 /* max_hold_time in US */ 140 #define BEFORE_UNLOCK(lock, max_hold_time) \ 141 do {\ 142 uint64_t BEFORE_UNLOCK_time; \ 143 uint64_t held_time; \ 144 BEFORE_UNLOCK_time = qdf_get_log_timestamp_lightweight(); \ 145 \ 146 if (unlikely(BEFORE_UNLOCK_time < lock->stats.last_acquired)) \ 147 held_time = 0; \ 148 else \ 149 held_time = BEFORE_UNLOCK_time - lock->stats.last_acquired; \ 150 \ 151 lock->stats.held_time += held_time; \ 152 \ 153 if (held_time > lock->stats.max_held_time) \ 154 lock->stats.max_held_time = held_time; \ 155 \ 156 if (held_time > LARGE_CONTENTION) \ 157 lock->stats.num_large_holds++; \ 158 if (QDF_LOCK_STATS_BUG_ON && max_hold_time && \ 159 held_time > qdf_usecs_to_log_timestamp(max_hold_time)) { \ 160 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, \ 161 "BEFORE_UNLOCK: lock held too long (%lluus)", \ 162 qdf_log_timestamp_to_usecs(held_time)); \ 163 QDF_BUG(0); \ 164 } \ 165 lock->stats.acquired_by = NULL; \ 166 } while (0) 167 168 void qdf_lock_stats_cookie_destroy(struct lock_stats *stats); 169 void qdf_lock_stats_cookie_create(struct lock_stats *stats, 170 const char *func, int line); 171 172 static inline void qdf_lock_stats_destroy(struct lock_stats *stats) 173 { 174 if (QDF_LOCK_STATS_DESTROY_PRINT) { 175 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG, 176 "%s: lock: %s %d \t" 177 "acquired:\t%d\tcontended:\t%d\t" 178 "contention_time\t%llu\tmax_contention_wait:\t%llu\t" 179 "non_contention_time\t%llu\t" 180 "held_time\t%llu\tmax_held:\t%llu" 181 , __func__, stats->initialization_fn, stats->line, 182 stats->acquired, stats->contended, 183 qdf_log_timestamp_to_usecs(stats->contention_time), 184 qdf_log_timestamp_to_usecs(stats->max_contention_wait), 185 qdf_log_timestamp_to_usecs(stats->non_contention_time), 186 qdf_log_timestamp_to_usecs(stats->held_time), 187 qdf_log_timestamp_to_usecs(stats->max_held_time)); 188 } 189 190 if (QDF_LOCK_STATS_LIST) 191 qdf_lock_stats_cookie_destroy(stats); 192 } 193 194 #ifndef MEMORY_DEBUG 195 #define qdf_mem_malloc_debug(x, y, z) qdf_mem_malloc(x) 196 #endif 197 198 /* qdf_lock_stats_create() - initialize the lock stats structure 199 * 200 */ 201 static inline void qdf_lock_stats_create(struct lock_stats *stats, 202 const char *func, int line) 203 { 204 qdf_mem_zero(stats, sizeof(*stats)); 205 stats->initialization_fn = func; 206 stats->line = line; 207 208 if (QDF_LOCK_STATS_LIST) 209 qdf_lock_stats_cookie_create(stats, func, line); 210 } 211 #endif 212 213 #include <i_qdf_lock.h> 214 215 #define WIFI_POWER_EVENT_DEFAULT_WAKELOCK_TIMEOUT 0 216 #define WIFI_POWER_EVENT_WAKELOCK_TAKEN 0 217 #define WIFI_POWER_EVENT_WAKELOCK_RELEASED 1 218 219 /** 220 * qdf_semaphore_acquire_timeout() - Take the semaphore before timeout 221 * @m: semaphore to take 222 * @timeout: maximum time to try to take the semaphore 223 * Return: int 224 */ 225 static inline int qdf_semaphore_acquire_timeout(struct semaphore *m, 226 unsigned long timeout) 227 { 228 return __qdf_semaphore_acquire_timeout(m, timeout); 229 } 230 231 struct qdf_spinlock { 232 __qdf_spinlock_t lock; 233 struct lock_stats stats; 234 }; 235 236 /** 237 * @brief Platform spinlock object 238 */ 239 typedef struct qdf_spinlock qdf_spinlock_t; 240 241 242 /** 243 * @brief Platform mutex object 244 */ 245 typedef __qdf_semaphore_t qdf_semaphore_t; 246 typedef __qdf_mutex_t qdf_mutex_t; 247 248 /* function Declaration */ 249 QDF_STATUS qdf_mutex_create(qdf_mutex_t *m, const char *func, int line); 250 #define qdf_mutex_create(m) qdf_mutex_create(m, __func__, __LINE__) 251 252 QDF_STATUS qdf_mutex_acquire(qdf_mutex_t *m); 253 254 QDF_STATUS qdf_mutex_release(qdf_mutex_t *m); 255 256 QDF_STATUS qdf_mutex_destroy(qdf_mutex_t *lock); 257 258 /** 259 * qdf_spinlock_create - Initialize a spinlock 260 * @lock: spinlock object pointer 261 * Return: none 262 */ 263 static inline void qdf_spinlock_create(qdf_spinlock_t *lock, const char *func, 264 int line) 265 { 266 __qdf_spinlock_create(&lock->lock); 267 268 /* spinlock stats create relies on the spinlock working allread */ 269 qdf_lock_stats_create(&lock->stats, func, line); 270 } 271 272 #define qdf_spinlock_create(x) qdf_spinlock_create(x, __func__, __LINE__) 273 274 /** 275 * qdf_spinlock_destroy - Delete a spinlock 276 * @lock: spinlock object pointer 277 * Return: none 278 */ 279 static inline void qdf_spinlock_destroy(qdf_spinlock_t *lock) 280 { 281 qdf_lock_stats_destroy(&lock->stats); 282 __qdf_spinlock_destroy(&lock->lock); 283 } 284 285 /** 286 * qdf_spin_is_locked() - check if the spinlock is locked 287 * @lock: spinlock object 288 * 289 * Return: nonzero if lock is held. 290 */ 291 static inline int qdf_spin_is_locked(qdf_spinlock_t *lock) 292 { 293 return __qdf_spin_is_locked(&lock->lock); 294 } 295 296 /** 297 * qdf_spin_trylock_bh() - spin trylock bottomhalf 298 * @lock: spinlock object 299 * 300 * Return: nonzero if lock is acquired 301 */ 302 static inline int qdf_spin_trylock_bh(qdf_spinlock_t *lock, const char *func) 303 { 304 int trylock_return; 305 306 BEFORE_TRYLOCK(lock); 307 trylock_return = __qdf_spin_trylock_bh(&lock->lock); 308 AFTER_TRYLOCK(lock, trylock_return, func); 309 310 return trylock_return; 311 } 312 #define qdf_spin_trylock_bh(lock) qdf_spin_trylock_bh(lock, __func__) 313 314 /** 315 * qdf_spin_trylock() - spin trylock 316 * @lock: spinlock object 317 * Return: int 318 */ 319 static inline int qdf_spin_trylock(qdf_spinlock_t *lock, const char *func) 320 { 321 int result = 0; 322 323 BEFORE_LOCK(lock, qdf_spin_is_locked(lock)); 324 result = __qdf_spin_trylock(&lock->lock); 325 AFTER_LOCK(lock, func); 326 327 return result; 328 } 329 330 #define qdf_spin_trylock(lock) qdf_spin_trylock(lock, __func__) 331 332 /** 333 * qdf_spin_lock_bh() - locks the spinlock mutex in soft irq context 334 * @lock: spinlock object pointer 335 * Return: none 336 */ 337 static inline void qdf_spin_lock_bh(qdf_spinlock_t *lock, const char *func) 338 { 339 BEFORE_LOCK(lock, qdf_spin_is_locked(lock)); 340 __qdf_spin_lock_bh(&lock->lock); 341 AFTER_LOCK(lock, func); 342 } 343 344 #define qdf_spin_lock_bh(lock) qdf_spin_lock_bh(lock, __func__) 345 346 /** 347 * qdf_spin_unlock_bh() - unlocks the spinlock mutex in soft irq context 348 * @lock: spinlock object pointer 349 * Return: none 350 */ 351 static inline void qdf_spin_unlock_bh(qdf_spinlock_t *lock) 352 { 353 BEFORE_UNLOCK(lock, QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK_BH); 354 __qdf_spin_unlock_bh(&lock->lock); 355 } 356 357 /** 358 * qdf_spinlock_irq_exec - Execute the input function with spinlock held 359 * and interrupt disabled. 360 * @hdl: OS handle 361 * @lock: spinlock to be held for the critical region 362 * @func: critical region function that to be executed 363 * @context: context of the critical region function 364 * Return: Boolean status returned by the critical region function 365 */ 366 static inline bool qdf_spinlock_irq_exec(qdf_handle_t hdl, 367 qdf_spinlock_t *lock, 368 qdf_irqlocked_func_t func, void *arg) 369 { 370 return __qdf_spinlock_irq_exec(hdl, &lock->lock, func, arg); 371 } 372 373 /** 374 * qdf_spin_lock() - Acquire a Spinlock(SMP) & disable Preemption (Preemptive) 375 * @lock: Lock object 376 * 377 * Return: none 378 */ 379 static inline void qdf_spin_lock(qdf_spinlock_t *lock, const char *func) 380 { 381 BEFORE_LOCK(lock, qdf_spin_is_locked(lock)); 382 __qdf_spin_lock(&lock->lock); 383 AFTER_LOCK(lock, func); 384 } 385 #define qdf_spin_lock(lock) qdf_spin_lock(lock, __func__) 386 387 /** 388 * qdf_spin_unlock() - Unlock the spinlock and enables the Preemption 389 * @lock: Lock object 390 * 391 * Return: none 392 */ 393 static inline void qdf_spin_unlock(qdf_spinlock_t *lock) 394 { 395 BEFORE_UNLOCK(lock, QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK); 396 __qdf_spin_unlock(&lock->lock); 397 } 398 399 /** 400 * qdf_spin_lock_irq() - Acquire a Spinlock(SMP) & save the irq state 401 * @lock: Lock object 402 * @flags: flags 403 * 404 * Return: none 405 */ 406 static inline void qdf_spin_lock_irq(qdf_spinlock_t *lock, unsigned long flags, 407 const char *func) 408 { 409 BEFORE_LOCK(lock, qdf_spin_is_locked(lock)); 410 __qdf_spin_lock_irq(&lock->lock.spinlock, flags); 411 AFTER_LOCK(lock, func); 412 } 413 #define qdf_spin_lock_irq(lock, flags) qdf_spin_lock_irq(lock, flags, __func__) 414 415 /** 416 * qdf_spin_lock_irqsave() - Acquire a Spinlock (SMP) & disable Preemption 417 * (Preemptive) and disable IRQs 418 * @lock: Lock object 419 * 420 * Return: none 421 */ 422 static inline void qdf_spin_lock_irqsave(qdf_spinlock_t *lock, const char *func) 423 { 424 BEFORE_LOCK(lock, qdf_spin_is_locked(lock)); 425 __qdf_spin_lock_irqsave(&lock->lock); 426 AFTER_LOCK(lock, func); 427 } 428 #define qdf_spin_lock_irqsave(lock) qdf_spin_lock_irqsave(lock, __func__) 429 430 /** 431 * qdf_spin_unlock_irqrestore() - Unlock the spinlock and enables the 432 * Preemption and enable IRQ 433 * @lock: Lock object 434 * 435 * Return: none 436 */ 437 static inline void qdf_spin_unlock_irqrestore(qdf_spinlock_t *lock) 438 { 439 BEFORE_UNLOCK(lock, QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK_IRQ); 440 __qdf_spin_unlock_irqrestore(&lock->lock); 441 } 442 443 /** 444 * qdf_spin_unlock_irq() - Unlock a Spinlock(SMP) & save the restore state 445 * @lock: Lock object 446 * @flags: flags 447 * 448 * Return: none 449 */ 450 static inline void qdf_spin_unlock_irq(qdf_spinlock_t *lock, 451 unsigned long flags) 452 { 453 BEFORE_UNLOCK(lock, QDF_MAX_HOLD_TIME_ALOWED_SPINLOCK_IRQ); 454 __qdf_spin_unlock_irq(&lock->lock.spinlock, flags); 455 } 456 457 /** 458 * qdf_semaphore_init() - initialize a semaphore 459 * @m: Semaphore to initialize 460 * Return: None 461 */ 462 static inline void qdf_semaphore_init(qdf_semaphore_t *m) 463 { 464 __qdf_semaphore_init(m); 465 } 466 467 /** 468 * qdf_semaphore_acquire() - take the semaphore 469 * @m: Semaphore to take 470 * Return: int 471 */ 472 static inline int qdf_semaphore_acquire(qdf_semaphore_t *m) 473 { 474 return __qdf_semaphore_acquire(m); 475 } 476 477 /** 478 * qdf_semaphore_release() - give the semaphore 479 * @m: Semaphore to give 480 * Return: None 481 */ 482 static inline void qdf_semaphore_release(qdf_semaphore_t *m) 483 { 484 __qdf_semaphore_release(m); 485 } 486 487 /** 488 * qdf_semaphore_acquire_intr - Take the semaphore, interruptible version 489 * @osdev: OS Device 490 * @m: mutex to take 491 * Return: int 492 */ 493 static inline int qdf_semaphore_acquire_intr(qdf_semaphore_t *m) 494 { 495 return __qdf_semaphore_acquire_intr(m); 496 } 497 498 #ifdef WLAN_WAKE_LOCK_DEBUG 499 /** 500 * qdf_wake_lock_check_for_leaks() - assert no wake lock leaks 501 * 502 * Return: None 503 */ 504 void qdf_wake_lock_check_for_leaks(void); 505 506 /** 507 * qdf_wake_lock_feature_init() - global init logic for wake lock 508 * 509 * Return: None 510 */ 511 void qdf_wake_lock_feature_init(void); 512 513 /** 514 * qdf_wake_lock_feature_deinit() - global de-init logic for wake lock 515 * 516 * Return: None 517 */ 518 void qdf_wake_lock_feature_deinit(void); 519 #else 520 static inline void qdf_wake_lock_check_for_leaks(void) { } 521 static inline void qdf_wake_lock_feature_init(void) { } 522 static inline void qdf_wake_lock_feature_deinit(void) { } 523 #endif /* WLAN_WAKE_LOCK_DEBUG */ 524 525 /** 526 * __qdf_wake_lock_create() - initialize a wake lock 527 * @lock: The wake lock to initialize 528 * @name: Name of wake lock 529 * @func: caller function 530 * @line: caller line 531 * Return: 532 * QDF status success: if wake lock is initialized 533 * QDF status failure: if wake lock was not initialized 534 */ 535 QDF_STATUS __qdf_wake_lock_create(qdf_wake_lock_t *lock, const char *name, 536 const char *func, uint32_t line); 537 538 /** 539 * qdf_wake_lock_create() - initialized a wakeup source lock 540 * @lock: the wakeup source lock to initialize 541 * @name: the name of wakeup source lock 542 * 543 * Return: QDF_STATUS 544 */ 545 #define qdf_wake_lock_create(lock, name) \ 546 __qdf_wake_lock_create(lock, name, __func__, __LINE__) 547 548 QDF_STATUS qdf_wake_lock_acquire(qdf_wake_lock_t *lock, uint32_t reason); 549 550 const char *qdf_wake_lock_name(qdf_wake_lock_t *lock); 551 QDF_STATUS qdf_wake_lock_timeout_acquire(qdf_wake_lock_t *lock, 552 uint32_t msec); 553 554 QDF_STATUS qdf_wake_lock_release(qdf_wake_lock_t *lock, uint32_t reason); 555 556 /** 557 * __qdf_wake_lock_destroy() - destroy a wake lock 558 * @lock: The wake lock to destroy 559 * @func: caller function 560 * @line: caller line 561 * 562 * Return: None 563 */ 564 void __qdf_wake_lock_destroy(qdf_wake_lock_t *lock, 565 const char *func, uint32_t line); 566 567 /** 568 * qdf_wake_lock_destroy() - deinitialize a wakeup source lock 569 * @lock: the wakeup source lock to de-initialize 570 * 571 * Return: None 572 */ 573 #define qdf_wake_lock_destroy(lock) \ 574 __qdf_wake_lock_destroy(lock, __func__, __LINE__) 575 576 void qdf_pm_system_wakeup(void); 577 578 QDF_STATUS qdf_spinlock_acquire(qdf_spinlock_t *lock); 579 580 QDF_STATUS qdf_spinlock_release(qdf_spinlock_t *lock); 581 582 /** 583 * enum qdf_rtpm_type - Get and Put calls types 584 * @QDF_RTPM_GET: Increment usage count and when system is suspended 585 * schedule resume process, return depends on pm state. 586 * @QDF_RTPM_GET_FORCE: Increment usage count and when system is suspended 587 * shedule resume process, returns success irrespective of 588 * pm_state. 589 * @QDF_RTPM_GET_SYNC: Increment usage count and when system is suspended, 590 * wait till process is resumed. 591 * @QDF_RTPM_GET_NORESUME: Only increments usage count. 592 * @QDF_RTPM_PUT: Decrements usage count and puts system in idle state. 593 * @QDF_RTPM_PUT_SYNC_SUSPEND: Decrements usage count and puts system in 594 * suspended state. 595 * @QDF_RTPM_PUT_NOIDLE: Decrements usage count. 596 */ 597 enum qdf_rtpm_call_type { 598 QDF_RTPM_GET, 599 QDF_RTPM_GET_FORCE, 600 QDF_RTPM_GET_SYNC, 601 QDF_RTPM_GET_NORESUME, 602 QDF_RTPM_PUT, 603 QDF_RTPM_PUT_SYNC_SUSPEND, 604 QDF_RTPM_PUT_NOIDLE, 605 }; 606 607 /** 608 * enum qdf_rtpm_client_id - modules registered with runtime pm module 609 * @QDF_RTPM_ID_RESERVED: Reserved ID 610 * @QDF_RTPM_ID_PM_QOS_NOTIFY: PM QOS context 611 * @QDF_RTPM_ID_BUS_SUSPEND: APSS Bus suspend context 612 * @QDF_RTPM_ID_MAX: Max id 613 */ 614 enum qdf_rtpm_client_id { 615 QDF_RTPM_ID_RESERVED, 616 QDF_RTPM_ID_PM_QOS_NOTIFY, 617 QDF_RTPM_ID_WIPHY_SUSPEND, 618 QDF_RTPM_ID_MAX 619 }; 620 621 #define qdf_runtime_lock_init(lock) __qdf_runtime_lock_init(lock, #lock) 622 623 #ifdef FEATURE_RUNTIME_PM 624 /** 625 * qdf_rtpm_register() - QDF wrapper to register a module with runtime PM. 626 * @id: ID of the module which needs to be registered 627 * @hif_rpm_cbk: callback to be called when get was called in suspended state. 628 * @prevent_multiple_get: not allow simultaneous get calls or put calls 629 * 630 * Return: success status if registered 631 */ 632 QDF_STATUS qdf_rtpm_register(uint32_t id, void (*hif_rpm_cbk)(void)); 633 634 /** 635 * qdf_rtpm_deregister() - QDF wrapper to deregister the module 636 * @id: ID of the module which needs to be de-registered 637 * 638 * Return: success status if successfully de-registered 639 */ 640 QDF_STATUS qdf_rtpm_deregister(uint32_t id); 641 642 /** 643 * qdf_runtime_lock_init() - initialize runtime lock 644 * @name: name of the runtime lock 645 * 646 * Initialize a runtime pm lock. This lock can be used 647 * to prevent the runtime pm system from putting the bus 648 * to sleep. 649 * 650 * Return: Success if lock initialized 651 */ 652 QDF_STATUS __qdf_runtime_lock_init(qdf_runtime_lock_t *lock, const char *name); 653 654 /** 655 * qdf_runtime_lock_deinit() - deinitialize runtime pm lock 656 * @lock: the lock to deinitialize 657 * 658 * Ensures the lock is released. Frees the runtime lock. 659 * 660 * Return: void 661 */ 662 void qdf_runtime_lock_deinit(qdf_runtime_lock_t *lock); 663 664 /** 665 * qdf_rtpm_get() - Incremeant usage_count on the device to avoid suspend. 666 * @type: get call types from hif_rpm_type 667 * @id: ID of the module calling get() 668 * 669 * Return: success if a get has been issued, else error code. 670 */ 671 QDF_STATUS qdf_rtpm_get(uint8_t type, uint32_t id); 672 673 /** 674 * qdf_rtpm_put() - Decremeant usage_count on the device to avoid suspend. 675 * @type: put call types from hif_rpm_type 676 * @id: ID of the module calling put() 677 * 678 * Return: success if a put has been issued, else error code. 679 */ 680 QDF_STATUS qdf_rtpm_put(uint8_t type, uint32_t id); 681 682 /** 683 * qdf_runtime_pm_allow_suspend() - Prevent Runtime suspend 684 * @data: runtime PM lock 685 * 686 * This function will prevent runtime suspend, by incrementing 687 * device's usage count. 688 * 689 * Return: status 690 */ 691 QDF_STATUS qdf_runtime_pm_prevent_suspend(qdf_runtime_lock_t *lock); 692 693 /** 694 * qdf_runtime_pm_allow_suspend() - Allow Runtime suspend 695 * @data: runtime PM lock 696 * 697 * This function will allow runtime suspend, by decrementing 698 * device's usage count. 699 * 700 * Return: status 701 */ 702 QDF_STATUS qdf_runtime_pm_allow_suspend(qdf_runtime_lock_t *lock); 703 704 /** 705 * qdf_pm_runtime_sync_resume() - Invoke synchronous runtime resume. 706 * 707 * This function will invoke synchronous runtime resume. 708 * 709 * Return: Success if state is ON 710 */ 711 QDF_STATUS qdf_rtpm_sync_resume(void); 712 713 #else 714 static inline 715 QDF_STATUS qdf_rtpm_register(uint32_t id, void (*hif_rpm_cbk)(void)) 716 { 717 return 0; 718 } 719 720 static inline 721 QDF_STATUS qdf_rtpm_deregister(uint32_t id) 722 { 723 return QDF_STATUS_SUCCESS; 724 } 725 726 static inline 727 QDF_STATUS __qdf_runtime_lock_init(qdf_runtime_lock_t *lock, const char *name) 728 { 729 return QDF_STATUS_SUCCESS; 730 } 731 732 static inline 733 void qdf_runtime_lock_deinit(qdf_runtime_lock_t *lock) 734 { 735 } 736 737 static inline 738 QDF_STATUS qdf_rtpm_get(uint8_t type, uint32_t id) 739 { 740 return QDF_STATUS_SUCCESS; 741 } 742 743 static inline 744 QDF_STATUS qdf_rtpm_put(uint8_t type, uint32_t id) 745 { 746 return QDF_STATUS_SUCCESS; 747 } 748 749 static inline 750 QDF_STATUS qdf_runtime_pm_prevent_suspend(qdf_runtime_lock_t *lock) 751 { 752 return QDF_STATUS_SUCCESS; 753 } 754 755 static inline 756 QDF_STATUS qdf_runtime_pm_allow_suspend(qdf_runtime_lock_t *lock) 757 { 758 return QDF_STATUS_SUCCESS; 759 } 760 761 static inline 762 QDF_STATUS qdf_rtpm_sync_resume(void) 763 { 764 return QDF_STATUS_SUCCESS; 765 } 766 767 #endif /* FEATURE_RUNTIME_PM */ 768 769 #endif /* _QDF_LOCK_H */ 770