qdf_threads.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
  3. *
  4. * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  5. *
  6. *
  7. * Permission to use, copy, modify, and/or distribute this software for
  8. * any purpose with or without fee is hereby granted, provided that the
  9. * above copyright notice and this permission notice appear in all
  10. * copies.
  11. *
  12. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  13. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  14. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  15. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  16. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  17. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  18. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  19. * PERFORMANCE OF THIS SOFTWARE.
  20. */
  21. /*
  22. * This file was originally distributed by Qualcomm Atheros, Inc.
  23. * under proprietary terms before Copyright ownership was assigned
  24. * to the Linux Foundation.
  25. */
  26. /**
  27. * DOC: qdf_threads
  28. * QCA driver framework (QDF) thread APIs
  29. */
  30. /* Include Files */
  31. #include <qdf_threads.h>
  32. #include <qdf_types.h>
  33. #include <qdf_trace.h>
  34. #include <linux/jiffies.h>
  35. #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
  36. #include <linux/sched.h>
  37. #else
  38. #include <linux/sched/signal.h>
  39. #endif /* KERNEL_VERSION(4, 11, 0) */
  40. #include <linux/delay.h>
  41. #include <linux/interrupt.h>
  42. #include <linux/export.h>
  43. #include <linux/kthread.h>
  44. #include <linux/stacktrace.h>
  45. #include <qdf_defer.h>
  46. /* Function declarations and documenation */
  47. /**
  48. * qdf_sleep() - sleep
  49. * @ms_interval : Number of milliseconds to suspend the current thread.
  50. * A value of 0 may or may not cause the current thread to yield.
  51. *
  52. * This function suspends the execution of the current thread
  53. * until the specified time out interval elapses.
  54. *
  55. * Return: none
  56. */
  57. void qdf_sleep(uint32_t ms_interval)
  58. {
  59. if (in_interrupt()) {
  60. QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
  61. "%s cannot be called from interrupt context!!!",
  62. __func__);
  63. return;
  64. }
  65. msleep_interruptible(ms_interval);
  66. }
  67. EXPORT_SYMBOL(qdf_sleep);
  68. /**
  69. * qdf_sleep_us() - sleep
  70. * @us_interval : Number of microseconds to suspend the current thread.
  71. * A value of 0 may or may not cause the current thread to yield.
  72. *
  73. * This function suspends the execution of the current thread
  74. * until the specified time out interval elapses.
  75. *
  76. * Return : none
  77. */
  78. void qdf_sleep_us(uint32_t us_interval)
  79. {
  80. unsigned long timeout = usecs_to_jiffies(us_interval) + 1;
  81. if (in_interrupt()) {
  82. QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
  83. "%s cannot be called from interrupt context!!!",
  84. __func__);
  85. return;
  86. }
  87. while (timeout && !signal_pending(current))
  88. timeout = schedule_timeout_interruptible(timeout);
  89. }
  90. EXPORT_SYMBOL(qdf_sleep_us);
  91. /**
  92. * qdf_busy_wait() - busy wait
  93. * @us_interval : Number of microseconds to busy wait.
  94. *
  95. * This function places the current thread in busy wait until the specified
  96. * time out interval elapses. If the interval is greater than 50us on WM, the
  97. * behaviour is undefined.
  98. *
  99. * Return : none
  100. */
  101. void qdf_busy_wait(uint32_t us_interval)
  102. {
  103. udelay(us_interval);
  104. }
  105. EXPORT_SYMBOL(qdf_busy_wait);
  106. void qdf_set_user_nice(qdf_thread_t *thread, long nice)
  107. {
  108. set_user_nice(thread, nice);
  109. }
  110. EXPORT_SYMBOL(qdf_set_user_nice);
  111. qdf_thread_t *qdf_create_thread(int (*thread_handler)(void *data), void *data,
  112. const char thread_name[])
  113. {
  114. return kthread_create(thread_handler, data, thread_name);
  115. }
  116. EXPORT_SYMBOL(qdf_create_thread);
  117. int qdf_wake_up_process(qdf_thread_t *thread)
  118. {
  119. return wake_up_process(thread);
  120. }
  121. EXPORT_SYMBOL(qdf_wake_up_process);
  122. #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) || \
  123. defined(BACKPORTED_EXPORT_SAVE_STACK_TRACE_TSK_ARM)
  124. #define QDF_PRINT_TRACE_COUNT 32
  125. void qdf_print_thread_trace(qdf_thread_t *thread)
  126. {
  127. const int spaces = 4;
  128. struct task_struct *task = thread;
  129. unsigned long entries[QDF_PRINT_TRACE_COUNT] = {0};
  130. struct stack_trace trace = {
  131. .nr_entries = 0,
  132. .skip = 0,
  133. .entries = &entries[0],
  134. .max_entries = QDF_PRINT_TRACE_COUNT,
  135. };
  136. save_stack_trace_tsk(task, &trace);
  137. print_stack_trace(&trace, spaces);
  138. }
  139. #else
  140. void qdf_print_thread_trace(qdf_thread_t *thread) { }
  141. #endif /* KERNEL_VERSION(4, 14, 0) */
  142. EXPORT_SYMBOL(qdf_print_thread_trace);
  143. qdf_thread_t *qdf_get_current_task(void)
  144. {
  145. return current;
  146. }
  147. EXPORT_SYMBOL(qdf_get_current_task);