2 * SPDX-License-Identifier: MIT
4 * Copyright © 2019 Intel Corporation
7 #ifndef INTEL_WAKEREF_H
8 #define INTEL_WAKEREF_H
10 #include <linux/atomic.h>
11 #include <linux/mutex.h>
12 #include <linux/stackdepot.h>
14 struct drm_i915_private;
16 typedef depot_stack_handle_t intel_wakeref_t;
18 struct intel_wakeref {
21 intel_wakeref_t wakeref;
24 void __intel_wakeref_init(struct intel_wakeref *wf,
25 struct lock_class_key *key);
26 #define intel_wakeref_init(wf) do { \
27 static struct lock_class_key __key; \
29 __intel_wakeref_init((wf), &__key); \
32 int __intel_wakeref_get_first(struct drm_i915_private *i915,
33 struct intel_wakeref *wf,
34 int (*fn)(struct intel_wakeref *wf));
35 int __intel_wakeref_put_last(struct drm_i915_private *i915,
36 struct intel_wakeref *wf,
37 int (*fn)(struct intel_wakeref *wf));
40 * intel_wakeref_get: Acquire the wakeref
41 * @i915: the drm_i915_private device
43 * @fn: callback for acquired the wakeref, called only on first acquire.
45 * Acquire a hold on the wakeref. The first user to do so, will acquire
46 * the runtime pm wakeref and then call the @fn underneath the wakeref
49 * Note that @fn is allowed to fail, in which case the runtime-pm wakeref
50 * will be released and the acquisition unwound, and an error reported.
52 * Returns: 0 if the wakeref was acquired successfully, or a negative error
56 intel_wakeref_get(struct drm_i915_private *i915,
57 struct intel_wakeref *wf,
58 int (*fn)(struct intel_wakeref *wf))
60 if (unlikely(!atomic_inc_not_zero(&wf->count)))
61 return __intel_wakeref_get_first(i915, wf, fn);
67 * intel_wakeref_put: Release the wakeref
68 * @i915: the drm_i915_private device
70 * @fn: callback for releasing the wakeref, called only on final release.
72 * Release our hold on the wakeref. When there are no more users,
73 * the runtime pm wakeref will be released after the @fn callback is called
74 * underneath the wakeref mutex.
76 * Note that @fn is allowed to fail, in which case the runtime-pm wakeref
77 * is retained and an error reported.
79 * Returns: 0 if the wakeref was released successfully, or a negative error
83 intel_wakeref_put(struct drm_i915_private *i915,
84 struct intel_wakeref *wf,
85 int (*fn)(struct intel_wakeref *wf))
87 if (atomic_dec_and_mutex_lock(&wf->count, &wf->mutex))
88 return __intel_wakeref_put_last(i915, wf, fn);
94 * intel_wakeref_lock: Lock the wakeref (mutex)
97 * Locks the wakeref to prevent it being acquired or released. New users
98 * can still adjust the counter, but the wakeref itself (and callback)
99 * cannot be acquired or released.
102 intel_wakeref_lock(struct intel_wakeref *wf)
103 __acquires(wf->mutex)
105 mutex_lock(&wf->mutex);
109 * intel_wakeref_unlock: Unlock the wakeref
112 * Releases a previously acquired intel_wakeref_lock().
115 intel_wakeref_unlock(struct intel_wakeref *wf)
116 __releases(wf->mutex)
118 mutex_unlock(&wf->mutex);
122 * intel_wakeref_active: Query whether the wakeref is currently held
125 * Returns: true if the wakeref is currently held.
128 intel_wakeref_active(struct intel_wakeref *wf)
130 return READ_ONCE(wf->wakeref);
133 #endif /* INTEL_WAKEREF_H */