1
2
3
4
5
6
7#ifndef INTEL_WAKEREF_H
8#define INTEL_WAKEREF_H
9
10#include <linux/atomic.h>
11#include <linux/mutex.h>
12#include <linux/refcount.h>
13#include <linux/stackdepot.h>
14#include <linux/timer.h>
15
16struct intel_runtime_pm;
17
18typedef depot_stack_handle_t intel_wakeref_t;
19
20struct intel_wakeref {
21 atomic_t count;
22 struct mutex mutex;
23 intel_wakeref_t wakeref;
24};
25
26void __intel_wakeref_init(struct intel_wakeref *wf,
27 struct lock_class_key *key);
28#define intel_wakeref_init(wf) do { \
29 static struct lock_class_key __key; \
30 \
31 __intel_wakeref_init((wf), &__key); \
32} while (0)
33
34int __intel_wakeref_get_first(struct intel_runtime_pm *rpm,
35 struct intel_wakeref *wf,
36 int (*fn)(struct intel_wakeref *wf));
37int __intel_wakeref_put_last(struct intel_runtime_pm *rpm,
38 struct intel_wakeref *wf,
39 int (*fn)(struct intel_wakeref *wf));
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57static inline int
58intel_wakeref_get(struct intel_runtime_pm *rpm,
59 struct intel_wakeref *wf,
60 int (*fn)(struct intel_wakeref *wf))
61{
62 if (unlikely(!atomic_inc_not_zero(&wf->count)))
63 return __intel_wakeref_get_first(rpm, wf, fn);
64
65 return 0;
66}
67
68
69
70
71
72
73
74
75
76
77static inline bool
78intel_wakeref_get_if_active(struct intel_wakeref *wf)
79{
80 return atomic_inc_not_zero(&wf->count);
81}
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99static inline int
100intel_wakeref_put(struct intel_runtime_pm *rpm,
101 struct intel_wakeref *wf,
102 int (*fn)(struct intel_wakeref *wf))
103{
104 if (atomic_dec_and_mutex_lock(&wf->count, &wf->mutex))
105 return __intel_wakeref_put_last(rpm, wf, fn);
106
107 return 0;
108}
109
110
111
112
113
114
115
116
117
118static inline void
119intel_wakeref_lock(struct intel_wakeref *wf)
120 __acquires(wf->mutex)
121{
122 mutex_lock(&wf->mutex);
123}
124
125
126
127
128
129
130
131static inline void
132intel_wakeref_unlock(struct intel_wakeref *wf)
133 __releases(wf->mutex)
134{
135 mutex_unlock(&wf->mutex);
136}
137
138
139
140
141
142
143
144static inline bool
145intel_wakeref_active(struct intel_wakeref *wf)
146{
147 return READ_ONCE(wf->wakeref);
148}
149
150struct intel_wakeref_auto {
151 struct intel_runtime_pm *rpm;
152 struct timer_list timer;
153 intel_wakeref_t wakeref;
154 spinlock_t lock;
155 refcount_t count;
156};
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173void intel_wakeref_auto(struct intel_wakeref_auto *wf, unsigned long timeout);
174
175void intel_wakeref_auto_init(struct intel_wakeref_auto *wf,
176 struct intel_runtime_pm *rpm);
177void intel_wakeref_auto_fini(struct intel_wakeref_auto *wf);
178
179#endif
180