1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include "extcon.h"
18
19static int devm_extcon_dev_match(struct device *dev, void *res, void *data)
20{
21 struct extcon_dev **r = res;
22
23 if (WARN_ON(!r || !*r))
24 return 0;
25
26 return *r == data;
27}
28
29static void devm_extcon_dev_release(struct device *dev, void *res)
30{
31 extcon_dev_free(*(struct extcon_dev **)res);
32}
33
34
35static void devm_extcon_dev_unreg(struct device *dev, void *res)
36{
37 extcon_dev_unregister(*(struct extcon_dev **)res);
38}
39
40struct extcon_dev_notifier_devres {
41 struct extcon_dev *edev;
42 unsigned int id;
43 struct notifier_block *nb;
44};
45
46static void devm_extcon_dev_notifier_unreg(struct device *dev, void *res)
47{
48 struct extcon_dev_notifier_devres *this = res;
49
50 extcon_unregister_notifier(this->edev, this->id, this->nb);
51}
52
53static void devm_extcon_dev_notifier_all_unreg(struct device *dev, void *res)
54{
55 struct extcon_dev_notifier_devres *this = res;
56
57 extcon_unregister_notifier_all(this->edev, this->nb);
58}
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73struct extcon_dev *devm_extcon_dev_allocate(struct device *dev,
74 const unsigned int *supported_cable)
75{
76 struct extcon_dev **ptr, *edev;
77
78 ptr = devres_alloc(devm_extcon_dev_release, sizeof(*ptr), GFP_KERNEL);
79 if (!ptr)
80 return ERR_PTR(-ENOMEM);
81
82 edev = extcon_dev_allocate(supported_cable);
83 if (IS_ERR(edev)) {
84 devres_free(ptr);
85 return edev;
86 }
87
88 edev->dev.parent = dev;
89
90 *ptr = edev;
91 devres_add(dev, ptr);
92
93 return edev;
94}
95EXPORT_SYMBOL_GPL(devm_extcon_dev_allocate);
96
97
98
99
100
101
102
103
104
105void devm_extcon_dev_free(struct device *dev, struct extcon_dev *edev)
106{
107 WARN_ON(devres_release(dev, devm_extcon_dev_release,
108 devm_extcon_dev_match, edev));
109}
110EXPORT_SYMBOL_GPL(devm_extcon_dev_free);
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126int devm_extcon_dev_register(struct device *dev, struct extcon_dev *edev)
127{
128 struct extcon_dev **ptr;
129 int ret;
130
131 ptr = devres_alloc(devm_extcon_dev_unreg, sizeof(*ptr), GFP_KERNEL);
132 if (!ptr)
133 return -ENOMEM;
134
135 ret = extcon_dev_register(edev);
136 if (ret) {
137 devres_free(ptr);
138 return ret;
139 }
140
141 *ptr = edev;
142 devres_add(dev, ptr);
143
144 return 0;
145}
146EXPORT_SYMBOL_GPL(devm_extcon_dev_register);
147
148
149
150
151
152
153
154
155
156void devm_extcon_dev_unregister(struct device *dev, struct extcon_dev *edev)
157{
158 WARN_ON(devres_release(dev, devm_extcon_dev_unreg,
159 devm_extcon_dev_match, edev));
160}
161EXPORT_SYMBOL_GPL(devm_extcon_dev_unregister);
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180int devm_extcon_register_notifier(struct device *dev, struct extcon_dev *edev,
181 unsigned int id, struct notifier_block *nb)
182{
183 struct extcon_dev_notifier_devres *ptr;
184 int ret;
185
186 ptr = devres_alloc(devm_extcon_dev_notifier_unreg, sizeof(*ptr),
187 GFP_KERNEL);
188 if (!ptr)
189 return -ENOMEM;
190
191 ret = extcon_register_notifier(edev, id, nb);
192 if (ret) {
193 devres_free(ptr);
194 return ret;
195 }
196
197 ptr->edev = edev;
198 ptr->id = id;
199 ptr->nb = nb;
200 devres_add(dev, ptr);
201
202 return 0;
203}
204EXPORT_SYMBOL(devm_extcon_register_notifier);
205
206
207
208
209
210
211
212
213
214void devm_extcon_unregister_notifier(struct device *dev,
215 struct extcon_dev *edev, unsigned int id,
216 struct notifier_block *nb)
217{
218 WARN_ON(devres_release(dev, devm_extcon_dev_notifier_unreg,
219 devm_extcon_dev_match, edev));
220}
221EXPORT_SYMBOL(devm_extcon_unregister_notifier);
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236int devm_extcon_register_notifier_all(struct device *dev, struct extcon_dev *edev,
237 struct notifier_block *nb)
238{
239 struct extcon_dev_notifier_devres *ptr;
240 int ret;
241
242 ptr = devres_alloc(devm_extcon_dev_notifier_all_unreg, sizeof(*ptr),
243 GFP_KERNEL);
244 if (!ptr)
245 return -ENOMEM;
246
247 ret = extcon_register_notifier_all(edev, nb);
248 if (ret) {
249 devres_free(ptr);
250 return ret;
251 }
252
253 ptr->edev = edev;
254 ptr->nb = nb;
255 devres_add(dev, ptr);
256
257 return 0;
258}
259EXPORT_SYMBOL(devm_extcon_register_notifier_all);
260
261
262
263
264
265
266
267
268void devm_extcon_unregister_notifier_all(struct device *dev,
269 struct extcon_dev *edev,
270 struct notifier_block *nb)
271{
272 WARN_ON(devres_release(dev, devm_extcon_dev_notifier_all_unreg,
273 devm_extcon_dev_match, edev));
274}
275EXPORT_SYMBOL(devm_extcon_unregister_notifier_all);
276