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