intel_wakeref.h 8.5 KB

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