1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <linux/module.h>
18#include <linux/err.h>
19#include <linux/gpio.h>
20#include <linux/gpio/consumer.h>
21#include <linux/device.h>
22#include <linux/gfp.h>
23
24static void devm_gpiod_release(struct device *dev, void *res)
25{
26 struct gpio_desc **desc = res;
27
28 gpiod_put(*desc);
29}
30
31static int devm_gpiod_match(struct device *dev, void *res, void *data)
32{
33 struct gpio_desc **this = res, **gpio = data;
34
35 return *this == *gpio;
36}
37
38static void devm_gpiod_release_array(struct device *dev, void *res)
39{
40 struct gpio_descs **descs = res;
41
42 gpiod_put_array(*descs);
43}
44
45static int devm_gpiod_match_array(struct device *dev, void *res, void *data)
46{
47 struct gpio_descs **this = res, **gpios = data;
48
49 return *this == *gpios;
50}
51
52
53
54
55
56
57
58
59
60
61
62struct gpio_desc *__must_check devm_gpiod_get(struct device *dev,
63 const char *con_id,
64 enum gpiod_flags flags)
65{
66 return devm_gpiod_get_index(dev, con_id, 0, flags);
67}
68EXPORT_SYMBOL(devm_gpiod_get);
69
70
71
72
73
74
75
76
77
78
79
80struct gpio_desc *__must_check devm_gpiod_get_optional(struct device *dev,
81 const char *con_id,
82 enum gpiod_flags flags)
83{
84 return devm_gpiod_get_index_optional(dev, con_id, 0, flags);
85}
86EXPORT_SYMBOL(devm_gpiod_get_optional);
87
88
89
90
91
92
93
94
95
96
97
98
99struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
100 const char *con_id,
101 unsigned int idx,
102 enum gpiod_flags flags)
103{
104 struct gpio_desc **dr;
105 struct gpio_desc *desc;
106
107 dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *),
108 GFP_KERNEL);
109 if (!dr)
110 return ERR_PTR(-ENOMEM);
111
112 desc = gpiod_get_index(dev, con_id, idx, flags);
113 if (IS_ERR(desc)) {
114 devres_free(dr);
115 return desc;
116 }
117
118 *dr = desc;
119 devres_add(dev, dr);
120
121 return desc;
122}
123EXPORT_SYMBOL(devm_gpiod_get_index);
124
125
126
127
128
129
130
131
132
133
134struct gpio_desc *devm_get_gpiod_from_child(struct device *dev,
135 const char *con_id,
136 struct fwnode_handle *child)
137{
138 static const char * const suffixes[] = { "gpios", "gpio" };
139 char prop_name[32];
140 struct gpio_desc **dr;
141 struct gpio_desc *desc;
142 unsigned int i;
143
144 dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *),
145 GFP_KERNEL);
146 if (!dr)
147 return ERR_PTR(-ENOMEM);
148
149 for (i = 0; i < ARRAY_SIZE(suffixes); i++) {
150 if (con_id)
151 snprintf(prop_name, sizeof(prop_name), "%s-%s",
152 con_id, suffixes[i]);
153 else
154 snprintf(prop_name, sizeof(prop_name), "%s",
155 suffixes[i]);
156
157 desc = fwnode_get_named_gpiod(child, prop_name);
158 if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT))
159 break;
160 }
161 if (IS_ERR(desc)) {
162 devres_free(dr);
163 return desc;
164 }
165
166 *dr = desc;
167 devres_add(dev, dr);
168
169 return desc;
170}
171EXPORT_SYMBOL(devm_get_gpiod_from_child);
172
173
174
175
176
177
178
179
180
181
182
183
184
185struct gpio_desc *__must_check devm_gpiod_get_index_optional(struct device *dev,
186 const char *con_id,
187 unsigned int index,
188 enum gpiod_flags flags)
189{
190 struct gpio_desc *desc;
191
192 desc = devm_gpiod_get_index(dev, con_id, index, flags);
193 if (IS_ERR(desc)) {
194 if (PTR_ERR(desc) == -ENOENT)
195 return NULL;
196 }
197
198 return desc;
199}
200EXPORT_SYMBOL(devm_gpiod_get_index_optional);
201
202
203
204
205
206
207
208
209
210
211
212struct gpio_descs *__must_check devm_gpiod_get_array(struct device *dev,
213 const char *con_id,
214 enum gpiod_flags flags)
215{
216 struct gpio_descs **dr;
217 struct gpio_descs *descs;
218
219 dr = devres_alloc(devm_gpiod_release_array,
220 sizeof(struct gpio_descs *), GFP_KERNEL);
221 if (!dr)
222 return ERR_PTR(-ENOMEM);
223
224 descs = gpiod_get_array(dev, con_id, flags);
225 if (IS_ERR(descs)) {
226 devres_free(dr);
227 return descs;
228 }
229
230 *dr = descs;
231 devres_add(dev, dr);
232
233 return descs;
234}
235EXPORT_SYMBOL(devm_gpiod_get_array);
236
237
238
239
240
241
242
243
244
245
246
247
248struct gpio_descs *__must_check
249devm_gpiod_get_array_optional(struct device *dev, const char *con_id,
250 enum gpiod_flags flags)
251{
252 struct gpio_descs *descs;
253
254 descs = devm_gpiod_get_array(dev, con_id, flags);
255 if (IS_ERR(descs) && (PTR_ERR(descs) == -ENOENT))
256 return NULL;
257
258 return descs;
259}
260EXPORT_SYMBOL(devm_gpiod_get_array_optional);
261
262
263
264
265
266
267
268
269
270void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
271{
272 WARN_ON(devres_release(dev, devm_gpiod_release, devm_gpiod_match,
273 &desc));
274}
275EXPORT_SYMBOL(devm_gpiod_put);
276
277
278
279
280
281
282
283
284
285void devm_gpiod_put_array(struct device *dev, struct gpio_descs *descs)
286{
287 WARN_ON(devres_release(dev, devm_gpiod_release_array,
288 devm_gpiod_match_array, &descs));
289}
290EXPORT_SYMBOL(devm_gpiod_put_array);
291
292
293
294
295static void devm_gpio_release(struct device *dev, void *res)
296{
297 unsigned *gpio = res;
298
299 gpio_free(*gpio);
300}
301
302static int devm_gpio_match(struct device *dev, void *res, void *data)
303{
304 unsigned *this = res, *gpio = data;
305
306 return *this == *gpio;
307}
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324int devm_gpio_request(struct device *dev, unsigned gpio, const char *label)
325{
326 unsigned *dr;
327 int rc;
328
329 dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL);
330 if (!dr)
331 return -ENOMEM;
332
333 rc = gpio_request(gpio, label);
334 if (rc) {
335 devres_free(dr);
336 return rc;
337 }
338
339 *dr = gpio;
340 devres_add(dev, dr);
341
342 return 0;
343}
344EXPORT_SYMBOL(devm_gpio_request);
345
346
347
348
349
350
351
352
353int devm_gpio_request_one(struct device *dev, unsigned gpio,
354 unsigned long flags, const char *label)
355{
356 unsigned *dr;
357 int rc;
358
359 dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL);
360 if (!dr)
361 return -ENOMEM;
362
363 rc = gpio_request_one(gpio, flags, label);
364 if (rc) {
365 devres_free(dr);
366 return rc;
367 }
368
369 *dr = gpio;
370 devres_add(dev, dr);
371
372 return 0;
373}
374EXPORT_SYMBOL(devm_gpio_request_one);
375
376
377
378
379
380
381
382
383
384
385
386void devm_gpio_free(struct device *dev, unsigned int gpio)
387{
388
389 WARN_ON(devres_release(dev, devm_gpio_release, devm_gpio_match,
390 &gpio));
391}
392EXPORT_SYMBOL(devm_gpio_free);
393