intel_wakeref.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. /*
  2. * SPDX-License-Identifier: MIT
  3. *
  4. * Copyright © 2019 Intel Corporation
  5. */
  6. #ifndef INTEL_WAKEREF_H
  7. #define INTEL_WAKEREF_H
  8. #include <drm/drm_print.h>
  9. #include <linux/atomic.h>
  10. #include <linux/bitfield.h>
  11. #include <linux/bits.h>
  12. #include <linux/lockdep.h>
  13. #include <linux/mutex.h>
  14. #include <linux/refcount.h>
  15. #include <linux/ref_tracker.h>
  16. #include <linux/slab.h>
  17. #include <linux/stackdepot.h>
  18. #include <linux/timer.h>
  19. #include <linux/workqueue.h>
  20. typedef unsigned long intel_wakeref_t;
  21. #define INTEL_REFTRACK_DEAD_COUNT 16
  22. #define INTEL_REFTRACK_PRINT_LIMIT 16
  23. #if IS_ENABLED(CONFIG_DRM_I915_DEBUG)
  24. #define INTEL_WAKEREF_BUG_ON(expr) BUG_ON(expr)
  25. #else
  26. #define INTEL_WAKEREF_BUG_ON(expr) BUILD_BUG_ON_INVALID(expr)
  27. #endif
  28. struct intel_runtime_pm;
  29. struct intel_wakeref;
  30. struct intel_wakeref_ops {
  31. int (*get)(struct intel_wakeref *wf);
  32. int (*put)(struct intel_wakeref *wf);
  33. };
  34. struct intel_wakeref {
  35. atomic_t count;
  36. struct mutex mutex;
  37. intel_wakeref_t wakeref;
  38. struct drm_i915_private *i915;
  39. const struct intel_wakeref_ops *ops;
  40. struct delayed_work work;
  41. #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_WAKEREF)
  42. struct ref_tracker_dir debug;
  43. #endif
  44. };
  45. struct intel_wakeref_lockclass {
  46. struct lock_class_key mutex;
  47. struct lock_class_key work;
  48. };
  49. void __intel_wakeref_init(struct intel_wakeref *wf,
  50. struct drm_i915_private *i915,
  51. const struct intel_wakeref_ops *ops,
  52. struct intel_wakeref_lockclass *key,
  53. const char *name);
  54. #define intel_wakeref_init(wf, i915, ops, name) do { \
  55. static struct intel_wakeref_lockclass __key; \
  56. \
  57. __intel_wakeref_init((wf), (i915), (ops), &__key, name); \
  58. } while (0)
  59. int __intel_wakeref_get_first(struct intel_wakeref *wf);
  60. void __intel_wakeref_put_last(struct intel_wakeref *wf, unsigned long flags);
  61. /**
  62. * intel_wakeref_get: Acquire the wakeref
  63. * @wf: the wakeref
  64. *
  65. * Acquire a hold on the wakeref. The first user to do so, will acquire
  66. * the runtime pm wakeref and then call the intel_wakeref_ops->get()
  67. * underneath the wakeref mutex.
  68. *
  69. * Note that intel_wakeref_ops->get() is allowed to fail, in which case
  70. * the runtime-pm wakeref will be released and the acquisition unwound,
  71. * and an error reported.
  72. *
  73. * Returns: 0 if the wakeref was acquired successfully, or a negative error
  74. * code otherwise.
  75. */
  76. static inline int
  77. intel_wakeref_get(struct intel_wakeref *wf)
  78. {
  79. might_sleep();
  80. if (unlikely(!atomic_inc_not_zero(&wf->count)))
  81. return __intel_wakeref_get_first(wf);
  82. return 0;
  83. }
  84. /**
  85. * __intel_wakeref_get: Acquire the wakeref, again
  86. * @wf: the wakeref
  87. *
  88. * Increment the wakeref counter, only valid if it is already held by
  89. * the caller.
  90. *
  91. * See intel_wakeref_get().
  92. */
  93. static inline void
  94. __intel_wakeref_get(struct intel_wakeref *wf)
  95. {
  96. INTEL_WAKEREF_BUG_ON(atomic_read(&wf->count) <= 0);
  97. atomic_inc(&wf->count);
  98. }
  99. /**
  100. * intel_wakeref_get_if_active: Acquire the wakeref
  101. * @wf: the wakeref
  102. *
  103. * Acquire a hold on the wakeref, but only if the wakeref is already
  104. * active.
  105. *
  106. * Returns: true if the wakeref was acquired, false otherwise.
  107. */
  108. static inline bool
  109. intel_wakeref_get_if_active(struct intel_wakeref *wf)
  110. {
  111. return atomic_inc_not_zero(&wf->count);
  112. }
  113. enum {
  114. INTEL_WAKEREF_PUT_ASYNC_BIT = 0,
  115. __INTEL_WAKEREF_PUT_LAST_BIT__
  116. };
  117. static inline void
  118. intel_wakeref_might_get(struct intel_wakeref *wf)
  119. {
  120. might_lock(&wf->mutex);
  121. }
  122. /**
  123. * __intel_wakeref_put: Release the wakeref
  124. * @wf: the wakeref
  125. * @flags: control flags
  126. *
  127. * Release our hold on the wakeref. When there are no more users,
  128. * the runtime pm wakeref will be released after the intel_wakeref_ops->put()
  129. * callback is called underneath the wakeref mutex.
  130. *
  131. * Note that intel_wakeref_ops->put() is allowed to fail, in which case the
  132. * runtime-pm wakeref is retained.
  133. *
  134. */
  135. static inline void
  136. __intel_wakeref_put(struct intel_wakeref *wf, unsigned long flags)
  137. #define INTEL_WAKEREF_PUT_ASYNC BIT(INTEL_WAKEREF_PUT_ASYNC_BIT)
  138. #define INTEL_WAKEREF_PUT_DELAY \
  139. GENMASK(BITS_PER_LONG - 1, __INTEL_WAKEREF_PUT_LAST_BIT__)
  140. {
  141. INTEL_WAKEREF_BUG_ON(atomic_read(&wf->count) <= 0);
  142. if (unlikely(!atomic_add_unless(&wf->count, -1, 1)))
  143. __intel_wakeref_put_last(wf, flags);
  144. }
  145. static inline void
  146. intel_wakeref_put(struct intel_wakeref *wf)
  147. {
  148. might_sleep();
  149. __intel_wakeref_put(wf, 0);
  150. }
  151. static inline void
  152. intel_wakeref_put_async(struct intel_wakeref *wf)
  153. {
  154. __intel_wakeref_put(wf, INTEL_WAKEREF_PUT_ASYNC);
  155. }
  156. static inline void
  157. intel_wakeref_put_delay(struct intel_wakeref *wf, unsigned long delay)
  158. {
  159. __intel_wakeref_put(wf,
  160. INTEL_WAKEREF_PUT_ASYNC |
  161. FIELD_PREP(INTEL_WAKEREF_PUT_DELAY, delay));
  162. }
  163. static inline void
  164. intel_wakeref_might_put(struct intel_wakeref *wf)
  165. {
  166. might_lock(&wf->mutex);
  167. }
  168. /**
  169. * intel_wakeref_lock: Lock the wakeref (mutex)
  170. * @wf: the wakeref
  171. *
  172. * Locks the wakeref to prevent it being acquired or released. New users
  173. * can still adjust the counter, but the wakeref itself (and callback)
  174. * cannot be acquired or released.
  175. */
  176. static inline void
  177. intel_wakeref_lock(struct intel_wakeref *wf)
  178. __acquires(wf->mutex)
  179. {
  180. mutex_lock(&wf->mutex);
  181. }
  182. /**
  183. * intel_wakeref_unlock: Unlock the wakeref
  184. * @wf: the wakeref
  185. *
  186. * Releases a previously acquired intel_wakeref_lock().
  187. */
  188. static inline void
  189. intel_wakeref_unlock(struct intel_wakeref *wf)
  190. __releases(wf->mutex)
  191. {
  192. mutex_unlock(&wf->mutex);
  193. }
  194. /**
  195. * intel_wakeref_unlock_wait: Wait until the active callback is complete
  196. * @wf: the wakeref
  197. *
  198. * Waits for the active callback (under the @wf->mutex or another CPU) is
  199. * complete.
  200. */
  201. static inline void
  202. intel_wakeref_unlock_wait(struct intel_wakeref *wf)
  203. {
  204. mutex_lock(&wf->mutex);
  205. mutex_unlock(&wf->mutex);
  206. flush_delayed_work(&wf->work);
  207. }
  208. /**
  209. * intel_wakeref_is_active: Query whether the wakeref is currently held
  210. * @wf: the wakeref
  211. *
  212. * Returns: true if the wakeref is currently held.
  213. */
  214. static inline bool
  215. intel_wakeref_is_active(const struct intel_wakeref *wf)
  216. {
  217. return READ_ONCE(wf->wakeref);
  218. }
  219. /**
  220. * __intel_wakeref_defer_park: Defer the current park callback
  221. * @wf: the wakeref
  222. */
  223. static inline void
  224. __intel_wakeref_defer_park(struct intel_wakeref *wf)
  225. {
  226. lockdep_assert_held(&wf->mutex);
  227. INTEL_WAKEREF_BUG_ON(atomic_read(&wf->count));
  228. atomic_set_release(&wf->count, 1);
  229. }
  230. /**
  231. * intel_wakeref_wait_for_idle: Wait until the wakeref is idle
  232. * @wf: the wakeref
  233. *
  234. * Wait for the earlier asynchronous release of the wakeref. Note
  235. * this will wait for any third party as well, so make sure you only wait
  236. * when you have control over the wakeref and trust no one else is acquiring
  237. * it.
  238. *
  239. * Return: 0 on success, error code if killed.
  240. */
  241. int intel_wakeref_wait_for_idle(struct intel_wakeref *wf);
  242. #define INTEL_WAKEREF_DEF ((intel_wakeref_t)(-1))
  243. static inline intel_wakeref_t intel_ref_tracker_alloc(struct ref_tracker_dir *dir)
  244. {
  245. struct ref_tracker *user = NULL;
  246. ref_tracker_alloc(dir, &user, GFP_NOWAIT);
  247. return (intel_wakeref_t)user ?: INTEL_WAKEREF_DEF;
  248. }
  249. static inline void intel_ref_tracker_free(struct ref_tracker_dir *dir,
  250. intel_wakeref_t handle)
  251. {
  252. struct ref_tracker *user;
  253. user = (handle == INTEL_WAKEREF_DEF) ? NULL : (void *)handle;
  254. ref_tracker_free(dir, &user);
  255. }
  256. void intel_ref_tracker_show(struct ref_tracker_dir *dir,
  257. struct drm_printer *p);
  258. #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_WAKEREF)
  259. static inline intel_wakeref_t intel_wakeref_track(struct intel_wakeref *wf)
  260. {
  261. return intel_ref_tracker_alloc(&wf->debug);
  262. }
  263. static inline void intel_wakeref_untrack(struct intel_wakeref *wf,
  264. intel_wakeref_t handle)
  265. {
  266. intel_ref_tracker_free(&wf->debug, handle);
  267. }
  268. #else
  269. static inline intel_wakeref_t intel_wakeref_track(struct intel_wakeref *wf)
  270. {
  271. return -1;
  272. }
  273. static inline void intel_wakeref_untrack(struct intel_wakeref *wf,
  274. intel_wakeref_t handle)
  275. {
  276. }
  277. #endif
  278. struct intel_wakeref_auto {
  279. struct drm_i915_private *i915;
  280. struct timer_list timer;
  281. intel_wakeref_t wakeref;
  282. spinlock_t lock;
  283. refcount_t count;
  284. };
  285. /**
  286. * intel_wakeref_auto: Delay the runtime-pm autosuspend
  287. * @wf: the wakeref
  288. * @timeout: relative timeout in jiffies
  289. *
  290. * The runtime-pm core uses a suspend delay after the last wakeref
  291. * is released before triggering runtime suspend of the device. That
  292. * delay is configurable via sysfs with little regard to the device
  293. * characteristics. Instead, we want to tune the autosuspend based on our
  294. * HW knowledge. intel_wakeref_auto() delays the sleep by the supplied
  295. * timeout.
  296. *
  297. * Pass @timeout = 0 to cancel a previous autosuspend by executing the
  298. * suspend immediately.
  299. */
  300. void intel_wakeref_auto(struct intel_wakeref_auto *wf, unsigned long timeout);
  301. void intel_wakeref_auto_init(struct intel_wakeref_auto *wf,
  302. struct drm_i915_private *i915);
  303. void intel_wakeref_auto_fini(struct intel_wakeref_auto *wf);
  304. #endif /* INTEL_WAKEREF_H */