• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/err.h>
19 #include <linux/gpio.h>
20 #include <linux/gpio/consumer.h>
21 #include <linux/device.h>
22 #include <linux/gfp.h>
23 
devm_gpiod_release(struct device * dev,void * res)24 static void devm_gpiod_release(struct device *dev, void *res)
25 {
26 	struct gpio_desc **desc = res;
27 
28 	gpiod_put(*desc);
29 }
30 
devm_gpiod_match(struct device * dev,void * res,void * data)31 static 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 
38 /**
39  * devm_gpiod_get - Resource-managed gpiod_get()
40  * @dev:	GPIO consumer
41  * @con_id:	function within the GPIO consumer
42  * @flags:	optional GPIO initialization flags
43  *
44  * Managed gpiod_get(). GPIO descriptors returned from this function are
45  * automatically disposed on driver detach. See gpiod_get() for detailed
46  * information about behavior and return values.
47  */
__devm_gpiod_get(struct device * dev,const char * con_id,enum gpiod_flags flags)48 struct gpio_desc *__must_check __devm_gpiod_get(struct device *dev,
49 					      const char *con_id,
50 					      enum gpiod_flags flags)
51 {
52 	return devm_gpiod_get_index(dev, con_id, 0, flags);
53 }
54 EXPORT_SYMBOL(__devm_gpiod_get);
55 
56 /**
57  * devm_gpiod_get_optional - Resource-managed gpiod_get_optional()
58  * @dev: GPIO consumer
59  * @con_id: function within the GPIO consumer
60  * @flags: optional GPIO initialization flags
61  *
62  * Managed gpiod_get_optional(). GPIO descriptors returned from this function
63  * are automatically disposed on driver detach. See gpiod_get_optional() for
64  * detailed information about behavior and return values.
65  */
__devm_gpiod_get_optional(struct device * dev,const char * con_id,enum gpiod_flags flags)66 struct gpio_desc *__must_check __devm_gpiod_get_optional(struct device *dev,
67 						       const char *con_id,
68 						       enum gpiod_flags flags)
69 {
70 	return devm_gpiod_get_index_optional(dev, con_id, 0, flags);
71 }
72 EXPORT_SYMBOL(__devm_gpiod_get_optional);
73 
74 /**
75  * devm_gpiod_get_index - Resource-managed gpiod_get_index()
76  * @dev:	GPIO consumer
77  * @con_id:	function within the GPIO consumer
78  * @idx:	index of the GPIO to obtain in the consumer
79  * @flags:	optional GPIO initialization flags
80  *
81  * Managed gpiod_get_index(). GPIO descriptors returned from this function are
82  * automatically disposed on driver detach. See gpiod_get_index() for detailed
83  * information about behavior and return values.
84  */
__devm_gpiod_get_index(struct device * dev,const char * con_id,unsigned int idx,enum gpiod_flags flags)85 struct gpio_desc *__must_check __devm_gpiod_get_index(struct device *dev,
86 						    const char *con_id,
87 						    unsigned int idx,
88 						    enum gpiod_flags flags)
89 {
90 	struct gpio_desc **dr;
91 	struct gpio_desc *desc;
92 
93 	dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *),
94 			  GFP_KERNEL);
95 	if (!dr)
96 		return ERR_PTR(-ENOMEM);
97 
98 	desc = gpiod_get_index(dev, con_id, idx, flags);
99 	if (IS_ERR(desc)) {
100 		devres_free(dr);
101 		return desc;
102 	}
103 
104 	*dr = desc;
105 	devres_add(dev, dr);
106 
107 	return desc;
108 }
109 EXPORT_SYMBOL(__devm_gpiod_get_index);
110 
111 /**
112  * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional()
113  * @dev: GPIO consumer
114  * @con_id: function within the GPIO consumer
115  * @index: index of the GPIO to obtain in the consumer
116  * @flags: optional GPIO initialization flags
117  *
118  * Managed gpiod_get_index_optional(). GPIO descriptors returned from this
119  * function are automatically disposed on driver detach. See
120  * gpiod_get_index_optional() for detailed information about behavior and
121  * return values.
122  */
__devm_gpiod_get_index_optional(struct device * dev,const char * con_id,unsigned int index,enum gpiod_flags flags)123 struct gpio_desc *__must_check __devm_gpiod_get_index_optional(struct device *dev,
124 							     const char *con_id,
125 							     unsigned int index,
126 							 enum gpiod_flags flags)
127 {
128 	struct gpio_desc *desc;
129 
130 	desc = devm_gpiod_get_index(dev, con_id, index, flags);
131 	if (IS_ERR(desc)) {
132 		if (PTR_ERR(desc) == -ENOENT)
133 			return NULL;
134 	}
135 
136 	return desc;
137 }
138 EXPORT_SYMBOL(__devm_gpiod_get_index_optional);
139 
140 /**
141  * devm_gpiod_put - Resource-managed gpiod_put()
142  * @desc:	GPIO descriptor to dispose of
143  *
144  * Dispose of a GPIO descriptor obtained with devm_gpiod_get() or
145  * devm_gpiod_get_index(). Normally this function will not be called as the GPIO
146  * will be disposed of by the resource management code.
147  */
devm_gpiod_put(struct device * dev,struct gpio_desc * desc)148 void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
149 {
150 	WARN_ON(devres_release(dev, devm_gpiod_release, devm_gpiod_match,
151 		&desc));
152 }
153 EXPORT_SYMBOL(devm_gpiod_put);
154 
155 
156 
157 
devm_gpio_release(struct device * dev,void * res)158 static void devm_gpio_release(struct device *dev, void *res)
159 {
160 	unsigned *gpio = res;
161 
162 	gpio_free(*gpio);
163 }
164 
devm_gpio_match(struct device * dev,void * res,void * data)165 static int devm_gpio_match(struct device *dev, void *res, void *data)
166 {
167 	unsigned *this = res, *gpio = data;
168 
169 	return *this == *gpio;
170 }
171 
172 /**
173  *      devm_gpio_request - request a GPIO for a managed device
174  *      @dev: device to request the GPIO for
175  *      @gpio: GPIO to allocate
176  *      @label: the name of the requested GPIO
177  *
178  *      Except for the extra @dev argument, this function takes the
179  *      same arguments and performs the same function as
180  *      gpio_request().  GPIOs requested with this function will be
181  *      automatically freed on driver detach.
182  *
183  *      If an GPIO allocated with this function needs to be freed
184  *      separately, devm_gpio_free() must be used.
185  */
186 
devm_gpio_request(struct device * dev,unsigned gpio,const char * label)187 int devm_gpio_request(struct device *dev, unsigned gpio, const char *label)
188 {
189 	unsigned *dr;
190 	int rc;
191 
192 	dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL);
193 	if (!dr)
194 		return -ENOMEM;
195 
196 	rc = gpio_request(gpio, label);
197 	if (rc) {
198 		devres_free(dr);
199 		return rc;
200 	}
201 
202 	*dr = gpio;
203 	devres_add(dev, dr);
204 
205 	return 0;
206 }
207 EXPORT_SYMBOL(devm_gpio_request);
208 
209 /**
210  *	devm_gpio_request_one - request a single GPIO with initial setup
211  *	@dev:   device to request for
212  *	@gpio:	the GPIO number
213  *	@flags:	GPIO configuration as specified by GPIOF_*
214  *	@label:	a literal description string of this GPIO
215  */
devm_gpio_request_one(struct device * dev,unsigned gpio,unsigned long flags,const char * label)216 int devm_gpio_request_one(struct device *dev, unsigned gpio,
217 			  unsigned long flags, const char *label)
218 {
219 	unsigned *dr;
220 	int rc;
221 
222 	dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL);
223 	if (!dr)
224 		return -ENOMEM;
225 
226 	rc = gpio_request_one(gpio, flags, label);
227 	if (rc) {
228 		devres_free(dr);
229 		return rc;
230 	}
231 
232 	*dr = gpio;
233 	devres_add(dev, dr);
234 
235 	return 0;
236 }
237 EXPORT_SYMBOL(devm_gpio_request_one);
238 
239 /**
240  *      devm_gpio_free - free a GPIO
241  *      @dev: device to free GPIO for
242  *      @gpio: GPIO to free
243  *
244  *      Except for the extra @dev argument, this function takes the
245  *      same arguments and performs the same function as gpio_free().
246  *      This function instead of gpio_free() should be used to manually
247  *      free GPIOs allocated with devm_gpio_request().
248  */
devm_gpio_free(struct device * dev,unsigned int gpio)249 void devm_gpio_free(struct device *dev, unsigned int gpio)
250 {
251 
252 	WARN_ON(devres_release(dev, devm_gpio_release, devm_gpio_match,
253 		&gpio));
254 }
255 EXPORT_SYMBOL(devm_gpio_free);
256