Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */
2 : : /*
3 : : * devres.c - managed gpio resources
4 : : * This file is based on kernel/irq/devres.c
5 : : *
6 : : * Copyright (c) 2011 John Crispin <john@phrozen.org>
7 : : */
8 : :
9 : : #include <linux/module.h>
10 : : #include <linux/err.h>
11 : : #include <linux/gpio.h>
12 : : #include <linux/gpio/consumer.h>
13 : : #include <linux/device.h>
14 : : #include <linux/gfp.h>
15 : :
16 : : #include "gpiolib.h"
17 : :
18 : 0 : static void devm_gpiod_release(struct device *dev, void *res)
19 : : {
20 : : struct gpio_desc **desc = res;
21 : :
22 : 0 : gpiod_put(*desc);
23 : 0 : }
24 : :
25 : 0 : static int devm_gpiod_match(struct device *dev, void *res, void *data)
26 : : {
27 : : struct gpio_desc **this = res, **gpio = data;
28 : :
29 : 0 : return *this == *gpio;
30 : : }
31 : :
32 : 0 : static void devm_gpiod_release_array(struct device *dev, void *res)
33 : : {
34 : : struct gpio_descs **descs = res;
35 : :
36 : 0 : gpiod_put_array(*descs);
37 : 0 : }
38 : :
39 : 0 : static int devm_gpiod_match_array(struct device *dev, void *res, void *data)
40 : : {
41 : : struct gpio_descs **this = res, **gpios = data;
42 : :
43 : 0 : return *this == *gpios;
44 : : }
45 : :
46 : : /**
47 : : * devm_gpiod_get - Resource-managed gpiod_get()
48 : : * @dev: GPIO consumer
49 : : * @con_id: function within the GPIO consumer
50 : : * @flags: optional GPIO initialization flags
51 : : *
52 : : * Managed gpiod_get(). GPIO descriptors returned from this function are
53 : : * automatically disposed on driver detach. See gpiod_get() for detailed
54 : : * information about behavior and return values.
55 : : */
56 : 0 : struct gpio_desc *__must_check devm_gpiod_get(struct device *dev,
57 : : const char *con_id,
58 : : enum gpiod_flags flags)
59 : : {
60 : 0 : return devm_gpiod_get_index(dev, con_id, 0, flags);
61 : : }
62 : : EXPORT_SYMBOL_GPL(devm_gpiod_get);
63 : :
64 : : /**
65 : : * devm_gpiod_get_optional - Resource-managed gpiod_get_optional()
66 : : * @dev: GPIO consumer
67 : : * @con_id: function within the GPIO consumer
68 : : * @flags: optional GPIO initialization flags
69 : : *
70 : : * Managed gpiod_get_optional(). GPIO descriptors returned from this function
71 : : * are automatically disposed on driver detach. See gpiod_get_optional() for
72 : : * detailed information about behavior and return values.
73 : : */
74 : 207 : struct gpio_desc *__must_check devm_gpiod_get_optional(struct device *dev,
75 : : const char *con_id,
76 : : enum gpiod_flags flags)
77 : : {
78 : 207 : return devm_gpiod_get_index_optional(dev, con_id, 0, flags);
79 : : }
80 : : EXPORT_SYMBOL_GPL(devm_gpiod_get_optional);
81 : :
82 : : /**
83 : : * devm_gpiod_get_index - Resource-managed gpiod_get_index()
84 : : * @dev: GPIO consumer
85 : : * @con_id: function within the GPIO consumer
86 : : * @idx: index of the GPIO to obtain in the consumer
87 : : * @flags: optional GPIO initialization flags
88 : : *
89 : : * Managed gpiod_get_index(). GPIO descriptors returned from this function are
90 : : * automatically disposed on driver detach. See gpiod_get_index() for detailed
91 : : * information about behavior and return values.
92 : : */
93 : 621 : struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
94 : : const char *con_id,
95 : : unsigned int idx,
96 : : enum gpiod_flags flags)
97 : : {
98 : : struct gpio_desc **dr;
99 : : struct gpio_desc *desc;
100 : :
101 : 621 : desc = gpiod_get_index(dev, con_id, idx, flags);
102 [ - + ]: 621 : if (IS_ERR(desc))
103 : : return desc;
104 : :
105 : : /*
106 : : * For non-exclusive GPIO descriptors, check if this descriptor is
107 : : * already under resource management by this device.
108 : : */
109 [ # # ]: 0 : if (flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE) {
110 : : struct devres *dres;
111 : :
112 : 0 : dres = devres_find(dev, devm_gpiod_release,
113 : : devm_gpiod_match, &desc);
114 [ # # ]: 0 : if (dres)
115 : 0 : return desc;
116 : : }
117 : :
118 : : dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *),
119 : : GFP_KERNEL);
120 [ # # ]: 0 : if (!dr) {
121 : 0 : gpiod_put(desc);
122 : 0 : return ERR_PTR(-ENOMEM);
123 : : }
124 : :
125 : 0 : *dr = desc;
126 : 0 : devres_add(dev, dr);
127 : :
128 : 0 : return desc;
129 : : }
130 : : EXPORT_SYMBOL_GPL(devm_gpiod_get_index);
131 : :
132 : : /**
133 : : * devm_gpiod_get_from_of_node() - obtain a GPIO from an OF node
134 : : * @dev: device for lifecycle management
135 : : * @node: handle of the OF node
136 : : * @propname: name of the DT property representing the GPIO
137 : : * @index: index of the GPIO to obtain for the consumer
138 : : * @dflags: GPIO initialization flags
139 : : * @label: label to attach to the requested GPIO
140 : : *
141 : : * Returns:
142 : : * On successful request the GPIO pin is configured in accordance with
143 : : * provided @dflags.
144 : : *
145 : : * In case of error an ERR_PTR() is returned.
146 : : */
147 : 0 : struct gpio_desc *devm_gpiod_get_from_of_node(struct device *dev,
148 : : struct device_node *node,
149 : : const char *propname, int index,
150 : : enum gpiod_flags dflags,
151 : : const char *label)
152 : : {
153 : : struct gpio_desc **dr;
154 : : struct gpio_desc *desc;
155 : :
156 : 0 : desc = gpiod_get_from_of_node(node, propname, index, dflags, label);
157 [ # # ]: 0 : if (IS_ERR(desc))
158 : : return desc;
159 : :
160 : : /*
161 : : * For non-exclusive GPIO descriptors, check if this descriptor is
162 : : * already under resource management by this device.
163 : : */
164 [ # # ]: 0 : if (dflags & GPIOD_FLAGS_BIT_NONEXCLUSIVE) {
165 : : struct devres *dres;
166 : :
167 : 0 : dres = devres_find(dev, devm_gpiod_release,
168 : : devm_gpiod_match, &desc);
169 [ # # ]: 0 : if (dres)
170 : 0 : return desc;
171 : : }
172 : :
173 : : dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *),
174 : : GFP_KERNEL);
175 [ # # ]: 0 : if (!dr) {
176 : 0 : gpiod_put(desc);
177 : 0 : return ERR_PTR(-ENOMEM);
178 : : }
179 : :
180 : 0 : *dr = desc;
181 : 0 : devres_add(dev, dr);
182 : :
183 : 0 : return desc;
184 : : }
185 : : EXPORT_SYMBOL_GPL(devm_gpiod_get_from_of_node);
186 : :
187 : : /**
188 : : * devm_fwnode_get_index_gpiod_from_child - get a GPIO descriptor from a
189 : : * device's child node
190 : : * @dev: GPIO consumer
191 : : * @con_id: function within the GPIO consumer
192 : : * @index: index of the GPIO to obtain in the consumer
193 : : * @child: firmware node (child of @dev)
194 : : * @flags: GPIO initialization flags
195 : : * @label: label to attach to the requested GPIO
196 : : *
197 : : * GPIO descriptors returned from this function are automatically disposed on
198 : : * driver detach.
199 : : *
200 : : * On successful request the GPIO pin is configured in accordance with
201 : : * provided @flags.
202 : : */
203 : 414 : struct gpio_desc *devm_fwnode_get_index_gpiod_from_child(struct device *dev,
204 : : const char *con_id, int index,
205 : : struct fwnode_handle *child,
206 : : enum gpiod_flags flags,
207 : : const char *label)
208 : : {
209 : : char prop_name[32]; /* 32 is max size of property name */
210 : : struct gpio_desc **dr;
211 : : struct gpio_desc *desc;
212 : : unsigned int i;
213 : :
214 : : dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *),
215 : : GFP_KERNEL);
216 [ + - ]: 414 : if (!dr)
217 : : return ERR_PTR(-ENOMEM);
218 : :
219 [ + - ]: 0 : for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) {
220 [ - + ]: 414 : if (con_id)
221 : 0 : snprintf(prop_name, sizeof(prop_name), "%s-%s",
222 : : con_id, gpio_suffixes[i]);
223 : : else
224 : 414 : snprintf(prop_name, sizeof(prop_name), "%s",
225 : : gpio_suffixes[i]);
226 : :
227 : 414 : desc = fwnode_get_named_gpiod(child, prop_name, index, flags,
228 : : label);
229 [ - + # # ]: 414 : if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT))
230 : : break;
231 : : }
232 [ - + ]: 414 : if (IS_ERR(desc)) {
233 : 0 : devres_free(dr);
234 : 0 : return desc;
235 : : }
236 : :
237 : 414 : *dr = desc;
238 : 414 : devres_add(dev, dr);
239 : :
240 : 414 : return desc;
241 : : }
242 : : EXPORT_SYMBOL_GPL(devm_fwnode_get_index_gpiod_from_child);
243 : :
244 : : /**
245 : : * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional()
246 : : * @dev: GPIO consumer
247 : : * @con_id: function within the GPIO consumer
248 : : * @index: index of the GPIO to obtain in the consumer
249 : : * @flags: optional GPIO initialization flags
250 : : *
251 : : * Managed gpiod_get_index_optional(). GPIO descriptors returned from this
252 : : * function are automatically disposed on driver detach. See
253 : : * gpiod_get_index_optional() for detailed information about behavior and
254 : : * return values.
255 : : */
256 : 0 : struct gpio_desc *__must_check devm_gpiod_get_index_optional(struct device *dev,
257 : : const char *con_id,
258 : : unsigned int index,
259 : : enum gpiod_flags flags)
260 : : {
261 : : struct gpio_desc *desc;
262 : :
263 : 207 : desc = devm_gpiod_get_index(dev, con_id, index, flags);
264 [ # # + - ]: 207 : if (IS_ERR(desc)) {
265 [ # # - + ]: 207 : if (PTR_ERR(desc) == -ENOENT)
266 : : return NULL;
267 : : }
268 : :
269 : 0 : return desc;
270 : : }
271 : : EXPORT_SYMBOL_GPL(devm_gpiod_get_index_optional);
272 : :
273 : : /**
274 : : * devm_gpiod_get_array - Resource-managed gpiod_get_array()
275 : : * @dev: GPIO consumer
276 : : * @con_id: function within the GPIO consumer
277 : : * @flags: optional GPIO initialization flags
278 : : *
279 : : * Managed gpiod_get_array(). GPIO descriptors returned from this function are
280 : : * automatically disposed on driver detach. See gpiod_get_array() for detailed
281 : : * information about behavior and return values.
282 : : */
283 : 0 : struct gpio_descs *__must_check devm_gpiod_get_array(struct device *dev,
284 : : const char *con_id,
285 : : enum gpiod_flags flags)
286 : : {
287 : : struct gpio_descs **dr;
288 : : struct gpio_descs *descs;
289 : :
290 : : dr = devres_alloc(devm_gpiod_release_array,
291 : : sizeof(struct gpio_descs *), GFP_KERNEL);
292 [ # # ]: 0 : if (!dr)
293 : : return ERR_PTR(-ENOMEM);
294 : :
295 : 0 : descs = gpiod_get_array(dev, con_id, flags);
296 [ # # ]: 0 : if (IS_ERR(descs)) {
297 : 0 : devres_free(dr);
298 : 0 : return descs;
299 : : }
300 : :
301 : 0 : *dr = descs;
302 : 0 : devres_add(dev, dr);
303 : :
304 : 0 : return descs;
305 : : }
306 : : EXPORT_SYMBOL_GPL(devm_gpiod_get_array);
307 : :
308 : : /**
309 : : * devm_gpiod_get_array_optional - Resource-managed gpiod_get_array_optional()
310 : : * @dev: GPIO consumer
311 : : * @con_id: function within the GPIO consumer
312 : : * @flags: optional GPIO initialization flags
313 : : *
314 : : * Managed gpiod_get_array_optional(). GPIO descriptors returned from this
315 : : * function are automatically disposed on driver detach.
316 : : * See gpiod_get_array_optional() for detailed information about behavior and
317 : : * return values.
318 : : */
319 : : struct gpio_descs *__must_check
320 : 0 : devm_gpiod_get_array_optional(struct device *dev, const char *con_id,
321 : : enum gpiod_flags flags)
322 : : {
323 : : struct gpio_descs *descs;
324 : :
325 : 0 : descs = devm_gpiod_get_array(dev, con_id, flags);
326 [ # # # # ]: 0 : if (IS_ERR(descs) && (PTR_ERR(descs) == -ENOENT))
327 : : return NULL;
328 : :
329 : 0 : return descs;
330 : : }
331 : : EXPORT_SYMBOL_GPL(devm_gpiod_get_array_optional);
332 : :
333 : : /**
334 : : * devm_gpiod_put - Resource-managed gpiod_put()
335 : : * @dev: GPIO consumer
336 : : * @desc: GPIO descriptor to dispose of
337 : : *
338 : : * Dispose of a GPIO descriptor obtained with devm_gpiod_get() or
339 : : * devm_gpiod_get_index(). Normally this function will not be called as the GPIO
340 : : * will be disposed of by the resource management code.
341 : : */
342 : 0 : void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
343 : : {
344 [ # # ]: 0 : WARN_ON(devres_release(dev, devm_gpiod_release, devm_gpiod_match,
345 : : &desc));
346 : 0 : }
347 : : EXPORT_SYMBOL_GPL(devm_gpiod_put);
348 : :
349 : : /**
350 : : * devm_gpiod_unhinge - Remove resource management from a gpio descriptor
351 : : * @dev: GPIO consumer
352 : : * @desc: GPIO descriptor to remove resource management from
353 : : *
354 : : * Remove resource management from a GPIO descriptor. This is needed when
355 : : * you want to hand over lifecycle management of a descriptor to another
356 : : * mechanism.
357 : : */
358 : :
359 : 0 : void devm_gpiod_unhinge(struct device *dev, struct gpio_desc *desc)
360 : : {
361 : : int ret;
362 : :
363 [ # # ]: 0 : if (IS_ERR_OR_NULL(desc))
364 : : return;
365 : 0 : ret = devres_destroy(dev, devm_gpiod_release,
366 : : devm_gpiod_match, &desc);
367 : : /*
368 : : * If the GPIO descriptor is requested as nonexclusive, we
369 : : * may call this function several times on the same descriptor
370 : : * so it is OK if devres_destroy() returns -ENOENT.
371 : : */
372 [ # # ]: 0 : if (ret == -ENOENT)
373 : : return;
374 : : /* Anything else we should warn about */
375 [ # # ]: 0 : WARN_ON(ret);
376 : : }
377 : : EXPORT_SYMBOL_GPL(devm_gpiod_unhinge);
378 : :
379 : : /**
380 : : * devm_gpiod_put_array - Resource-managed gpiod_put_array()
381 : : * @dev: GPIO consumer
382 : : * @descs: GPIO descriptor array to dispose of
383 : : *
384 : : * Dispose of an array of GPIO descriptors obtained with devm_gpiod_get_array().
385 : : * Normally this function will not be called as the GPIOs will be disposed of
386 : : * by the resource management code.
387 : : */
388 : 0 : void devm_gpiod_put_array(struct device *dev, struct gpio_descs *descs)
389 : : {
390 [ # # ]: 0 : WARN_ON(devres_release(dev, devm_gpiod_release_array,
391 : : devm_gpiod_match_array, &descs));
392 : 0 : }
393 : : EXPORT_SYMBOL_GPL(devm_gpiod_put_array);
394 : :
395 : :
396 : :
397 : :
398 : 0 : static void devm_gpio_release(struct device *dev, void *res)
399 : : {
400 : : unsigned *gpio = res;
401 : :
402 : 0 : gpio_free(*gpio);
403 : 0 : }
404 : :
405 : 0 : static int devm_gpio_match(struct device *dev, void *res, void *data)
406 : : {
407 : : unsigned *this = res, *gpio = data;
408 : :
409 : 0 : return *this == *gpio;
410 : : }
411 : :
412 : : /**
413 : : * devm_gpio_request - request a GPIO for a managed device
414 : : * @dev: device to request the GPIO for
415 : : * @gpio: GPIO to allocate
416 : : * @label: the name of the requested GPIO
417 : : *
418 : : * Except for the extra @dev argument, this function takes the
419 : : * same arguments and performs the same function as
420 : : * gpio_request(). GPIOs requested with this function will be
421 : : * automatically freed on driver detach.
422 : : *
423 : : * If an GPIO allocated with this function needs to be freed
424 : : * separately, devm_gpio_free() must be used.
425 : : */
426 : :
427 : 0 : int devm_gpio_request(struct device *dev, unsigned gpio, const char *label)
428 : : {
429 : : unsigned *dr;
430 : : int rc;
431 : :
432 : : dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL);
433 [ # # ]: 0 : if (!dr)
434 : : return -ENOMEM;
435 : :
436 : 0 : rc = gpio_request(gpio, label);
437 [ # # ]: 0 : if (rc) {
438 : 0 : devres_free(dr);
439 : 0 : return rc;
440 : : }
441 : :
442 : 0 : *dr = gpio;
443 : 0 : devres_add(dev, dr);
444 : :
445 : 0 : return 0;
446 : : }
447 : : EXPORT_SYMBOL_GPL(devm_gpio_request);
448 : :
449 : : /**
450 : : * devm_gpio_request_one - request a single GPIO with initial setup
451 : : * @dev: device to request for
452 : : * @gpio: the GPIO number
453 : : * @flags: GPIO configuration as specified by GPIOF_*
454 : : * @label: a literal description string of this GPIO
455 : : */
456 : 0 : int devm_gpio_request_one(struct device *dev, unsigned gpio,
457 : : unsigned long flags, const char *label)
458 : : {
459 : : unsigned *dr;
460 : : int rc;
461 : :
462 : : dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL);
463 [ # # ]: 0 : if (!dr)
464 : : return -ENOMEM;
465 : :
466 : 0 : rc = gpio_request_one(gpio, flags, label);
467 [ # # ]: 0 : if (rc) {
468 : 0 : devres_free(dr);
469 : 0 : return rc;
470 : : }
471 : :
472 : 0 : *dr = gpio;
473 : 0 : devres_add(dev, dr);
474 : :
475 : 0 : return 0;
476 : : }
477 : : EXPORT_SYMBOL_GPL(devm_gpio_request_one);
478 : :
479 : : /**
480 : : * devm_gpio_free - free a GPIO
481 : : * @dev: device to free GPIO for
482 : : * @gpio: GPIO to free
483 : : *
484 : : * Except for the extra @dev argument, this function takes the
485 : : * same arguments and performs the same function as gpio_free().
486 : : * This function instead of gpio_free() should be used to manually
487 : : * free GPIOs allocated with devm_gpio_request().
488 : : */
489 : 0 : void devm_gpio_free(struct device *dev, unsigned int gpio)
490 : : {
491 : :
492 [ # # ]: 0 : WARN_ON(devres_release(dev, devm_gpio_release, devm_gpio_match,
493 : : &gpio));
494 : 0 : }
495 : : EXPORT_SYMBOL_GPL(devm_gpio_free);
|