gpiolib: devres: fix devm_gpiod_get_index()
[firefly-linux-kernel-4.4.55.git] / drivers / gpio / devres.c
1 /*
2  * drivers/gpio/devres.c - managed gpio resources
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2
6  * as published by the Free Software Foundation.
7  *
8  * You should have received a copy of the GNU General Public License
9  * along with this program; if not, write to the Free Software
10  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
11  *
12  * This file is based on kernel/irq/devres.c
13  *
14  * Copyright (c) 2011 John Crispin <blogic@openwrt.org>
15  */
16
17 #include <linux/module.h>
18 #include <linux/gpio.h>
19 #include <linux/device.h>
20 #include <linux/gfp.h>
21
22 static void devm_gpiod_release(struct device *dev, void *res)
23 {
24         struct gpio_desc **desc = res;
25
26         gpiod_put(*desc);
27 }
28
29 static int devm_gpiod_match(struct device *dev, void *res, void *data)
30 {
31         struct gpio_desc **this = res, **gpio = data;
32
33         return *this == *gpio;
34 }
35
36 /**
37  * devm_gpiod_get - Resource-managed gpiod_get()
38  * @dev:        GPIO consumer
39  * @con_id:     function within the GPIO consumer
40  *
41  * Managed gpiod_get(). GPIO descriptors returned from this function are
42  * automatically disposed on driver detach. See gpiod_get() for detailed
43  * information about behavior and return values.
44  */
45 struct gpio_desc *__must_check devm_gpiod_get(struct device *dev,
46                                               const char *con_id)
47 {
48         return devm_gpiod_get_index(dev, con_id, 0);
49 }
50 EXPORT_SYMBOL(devm_gpiod_get);
51
52 /**
53  * devm_gpiod_get_index - Resource-managed gpiod_get_index()
54  * @dev:        GPIO consumer
55  * @con_id:     function within the GPIO consumer
56  * @idx:        index of the GPIO to obtain in the consumer
57  *
58  * Managed gpiod_get_index(). GPIO descriptors returned from this function are
59  * automatically disposed on driver detach. See gpiod_get_index() for detailed
60  * information about behavior and return values.
61  */
62 struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
63                                                     const char *con_id,
64                                                     unsigned int idx)
65 {
66         struct gpio_desc **dr;
67         struct gpio_desc *desc;
68
69         dr = devres_alloc(devm_gpiod_release, sizeof(struct gpiod_desc *),
70                           GFP_KERNEL);
71         if (!dr)
72                 return ERR_PTR(-ENOMEM);
73
74         desc = gpiod_get_index(dev, con_id, idx);
75         if (IS_ERR(desc)) {
76                 devres_free(dr);
77                 return desc;
78         }
79
80         *dr = desc;
81         devres_add(dev, dr);
82
83         return desc;
84 }
85 EXPORT_SYMBOL(devm_gpiod_get_index);
86
87 /**
88  * devm_gpiod_put - Resource-managed gpiod_put()
89  * @desc:       GPIO descriptor to dispose of
90  *
91  * Dispose of a GPIO descriptor obtained with devm_gpiod_get() or
92  * devm_gpiod_get_index(). Normally this function will not be called as the GPIO
93  * will be disposed of by the resource management code.
94  */
95 void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
96 {
97         WARN_ON(devres_release(dev, devm_gpiod_release, devm_gpiod_match,
98                 &desc));
99 }
100 EXPORT_SYMBOL(devm_gpiod_put);
101
102
103
104
105 static void devm_gpio_release(struct device *dev, void *res)
106 {
107         unsigned *gpio = res;
108
109         gpio_free(*gpio);
110 }
111
112 static int devm_gpio_match(struct device *dev, void *res, void *data)
113 {
114         unsigned *this = res, *gpio = data;
115
116         return *this == *gpio;
117 }
118
119 /**
120  *      devm_gpio_request - request a GPIO for a managed device
121  *      @dev: device to request the GPIO for
122  *      @gpio: GPIO to allocate
123  *      @label: the name of the requested GPIO
124  *
125  *      Except for the extra @dev argument, this function takes the
126  *      same arguments and performs the same function as
127  *      gpio_request().  GPIOs requested with this function will be
128  *      automatically freed on driver detach.
129  *
130  *      If an GPIO allocated with this function needs to be freed
131  *      separately, devm_gpio_free() must be used.
132  */
133
134 int devm_gpio_request(struct device *dev, unsigned gpio, const char *label)
135 {
136         unsigned *dr;
137         int rc;
138
139         dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL);
140         if (!dr)
141                 return -ENOMEM;
142
143         rc = gpio_request(gpio, label);
144         if (rc) {
145                 devres_free(dr);
146                 return rc;
147         }
148
149         *dr = gpio;
150         devres_add(dev, dr);
151
152         return 0;
153 }
154 EXPORT_SYMBOL(devm_gpio_request);
155
156 /**
157  *      devm_gpio_request_one - request a single GPIO with initial setup
158  *      @dev:   device to request for
159  *      @gpio:  the GPIO number
160  *      @flags: GPIO configuration as specified by GPIOF_*
161  *      @label: a literal description string of this GPIO
162  */
163 int devm_gpio_request_one(struct device *dev, unsigned gpio,
164                           unsigned long flags, const char *label)
165 {
166         unsigned *dr;
167         int rc;
168
169         dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL);
170         if (!dr)
171                 return -ENOMEM;
172
173         rc = gpio_request_one(gpio, flags, label);
174         if (rc) {
175                 devres_free(dr);
176                 return rc;
177         }
178
179         *dr = gpio;
180         devres_add(dev, dr);
181
182         return 0;
183 }
184 EXPORT_SYMBOL(devm_gpio_request_one);
185
186 /**
187  *      devm_gpio_free - free a GPIO
188  *      @dev: device to free GPIO for
189  *      @gpio: GPIO to free
190  *
191  *      Except for the extra @dev argument, this function takes the
192  *      same arguments and performs the same function as gpio_free().
193  *      This function instead of gpio_free() should be used to manually
194  *      free GPIOs allocated with devm_gpio_request().
195  */
196 void devm_gpio_free(struct device *dev, unsigned int gpio)
197 {
198
199         WARN_ON(devres_release(dev, devm_gpio_release, devm_gpio_match,
200                 &gpio));
201 }
202 EXPORT_SYMBOL(devm_gpio_free);