2 * SPDX-License-Identifier: MIT
4 * Copyright © 2019 Intel Corporation
8 #include "intel_wakeref.h"
10 static void rpm_get(struct drm_i915_private *i915, struct intel_wakeref *wf)
12 wf->wakeref = intel_runtime_pm_get(i915);
15 static void rpm_put(struct drm_i915_private *i915, struct intel_wakeref *wf)
17 intel_wakeref_t wakeref = fetch_and_zero(&wf->wakeref);
19 intel_runtime_pm_put(i915, wakeref);
23 int __intel_wakeref_get_first(struct drm_i915_private *i915,
24 struct intel_wakeref *wf,
25 int (*fn)(struct intel_wakeref *wf))
28 * Treat get/put as different subclasses, as we may need to run
29 * the put callback from under the shrinker and do not want to
30 * cross-contanimate that callback with any extra work performed
31 * upon acquiring the wakeref.
33 mutex_lock_nested(&wf->mutex, SINGLE_DEPTH_NESTING);
34 if (!atomic_read(&wf->count)) {
42 mutex_unlock(&wf->mutex);
46 smp_mb__before_atomic(); /* release wf->count */
48 atomic_inc(&wf->count);
49 mutex_unlock(&wf->mutex);
54 int __intel_wakeref_put_last(struct drm_i915_private *i915,
55 struct intel_wakeref *wf,
56 int (*fn)(struct intel_wakeref *wf))
64 atomic_inc(&wf->count);
65 mutex_unlock(&wf->mutex);
70 void __intel_wakeref_init(struct intel_wakeref *wf, struct lock_class_key *key)
72 __mutex_init(&wf->mutex, "wakeref", key);
73 atomic_set(&wf->count, 0);