aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRojhalat Ibrahim <imr@rtschenk.de>2015-02-11 11:28:02 -0500
committerLinus Walleij <linus.walleij@linaro.org>2015-03-05 03:55:42 -0500
commit331758eef83620eef3f21289f0f44aba094d0503 (patch)
tree45b24f0b201b6b05333ebcf433a80a41454f6e73
parent668585273246f67b0cdafa30dd2da2047a2e1290 (diff)
gpiolib: add devm_gpiod_get_array and devm_gpiod_put_array functions
Add device managed variants of gpiod_get_array() / gpiod_put_array() functions for conveniently obtaining and disposing of an entire array of GPIOs with one function call. Signed-off-by: Rojhalat Ibrahim <imr@rtschenk.de> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--Documentation/gpio/consumer.txt14
-rw-r--r--drivers/gpio/devres.c89
-rw-r--r--include/linux/gpio/consumer.h30
3 files changed, 131 insertions, 2 deletions
diff --git a/Documentation/gpio/consumer.txt b/Documentation/gpio/consumer.txt
index 2924f2ffcd91..d29a9725c9e5 100644
--- a/Documentation/gpio/consumer.txt
+++ b/Documentation/gpio/consumer.txt
@@ -102,11 +102,19 @@ Device-managed variants of these functions are also defined:
102 const char *con_id, 102 const char *con_id,
103 enum gpiod_flags flags) 103 enum gpiod_flags flags)
104 104
105 struct gpio_desc * devm_gpiod_get_index_optional(struct device *dev, 105 struct gpio_desc *devm_gpiod_get_index_optional(struct device *dev,
106 const char *con_id, 106 const char *con_id,
107 unsigned int index, 107 unsigned int index,
108 enum gpiod_flags flags) 108 enum gpiod_flags flags)
109 109
110 struct gpio_descs *devm_gpiod_get_array(struct device *dev,
111 const char *con_id,
112 enum gpiod_flags flags)
113
114 struct gpio_descs *devm_gpiod_get_array_optional(struct device *dev,
115 const char *con_id,
116 enum gpiod_flags flags)
117
110A GPIO descriptor can be disposed of using the gpiod_put() function: 118A GPIO descriptor can be disposed of using the gpiod_put() function:
111 119
112 void gpiod_put(struct gpio_desc *desc) 120 void gpiod_put(struct gpio_desc *desc)
@@ -119,10 +127,12 @@ It is strictly forbidden to use a descriptor after calling these functions.
119It is also not allowed to individually release descriptors (using gpiod_put()) 127It is also not allowed to individually release descriptors (using gpiod_put())
120from an array acquired with gpiod_get_array(). 128from an array acquired with gpiod_get_array().
121 129
122The device-managed variant is, unsurprisingly: 130The device-managed variants are, unsurprisingly:
123 131
124 void devm_gpiod_put(struct device *dev, struct gpio_desc *desc) 132 void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
125 133
134 void devm_gpiod_put_array(struct device *dev, struct gpio_descs *descs)
135
126 136
127Using GPIOs 137Using GPIOs
128=========== 138===========
diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c
index 12c2082f968e..ec24da2418b3 100644
--- a/drivers/gpio/devres.c
+++ b/drivers/gpio/devres.c
@@ -35,6 +35,20 @@ static int devm_gpiod_match(struct device *dev, void *res, void *data)
35 return *this == *gpio; 35 return *this == *gpio;
36} 36}
37 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
38/** 52/**
39 * devm_gpiod_get - Resource-managed gpiod_get() 53 * devm_gpiod_get - Resource-managed gpiod_get()
40 * @dev: GPIO consumer 54 * @dev: GPIO consumer
@@ -186,6 +200,66 @@ struct gpio_desc *__must_check __devm_gpiod_get_index_optional(struct device *de
186EXPORT_SYMBOL(__devm_gpiod_get_index_optional); 200EXPORT_SYMBOL(__devm_gpiod_get_index_optional);
187 201
188/** 202/**
203 * devm_gpiod_get_array - Resource-managed gpiod_get_array()
204 * @dev: GPIO consumer
205 * @con_id: function within the GPIO consumer
206 * @flags: optional GPIO initialization flags
207 *
208 * Managed gpiod_get_array(). GPIO descriptors returned from this function are
209 * automatically disposed on driver detach. See gpiod_get_array() for detailed
210 * information about behavior and return values.
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 * devm_gpiod_get_array_optional - Resource-managed gpiod_get_array_optional()
239 * @dev: GPIO consumer
240 * @con_id: function within the GPIO consumer
241 * @flags: optional GPIO initialization flags
242 *
243 * Managed gpiod_get_array_optional(). GPIO descriptors returned from this
244 * function are automatically disposed on driver detach.
245 * See gpiod_get_array_optional() for detailed information about behavior and
246 * return values.
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/**
189 * devm_gpiod_put - Resource-managed gpiod_put() 263 * devm_gpiod_put - Resource-managed gpiod_put()
190 * @desc: GPIO descriptor to dispose of 264 * @desc: GPIO descriptor to dispose of
191 * 265 *
@@ -200,6 +274,21 @@ void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
200} 274}
201EXPORT_SYMBOL(devm_gpiod_put); 275EXPORT_SYMBOL(devm_gpiod_put);
202 276
277/**
278 * devm_gpiod_put_array - Resource-managed gpiod_put_array()
279 * @descs: GPIO descriptor array to dispose of
280 *
281 * Dispose of an array of GPIO descriptors obtained with devm_gpiod_get_array().
282 * Normally this function will not be called as the GPIOs will be disposed of
283 * by the resource management code.
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
203 292
204 293
205 294
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
index 33eb52fd0932..3a7c9ffd5ab9 100644
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
@@ -83,7 +83,14 @@ struct gpio_desc *__must_check __devm_gpiod_get_optional(struct device *dev,
83struct gpio_desc *__must_check 83struct gpio_desc *__must_check
84__devm_gpiod_get_index_optional(struct device *dev, const char *con_id, 84__devm_gpiod_get_index_optional(struct device *dev, const char *con_id,
85 unsigned int index, enum gpiod_flags flags); 85 unsigned int index, enum gpiod_flags flags);
86struct gpio_descs *__must_check devm_gpiod_get_array(struct device *dev,
87 const char *con_id,
88 enum gpiod_flags flags);
89struct gpio_descs *__must_check
90devm_gpiod_get_array_optional(struct device *dev, const char *con_id,
91 enum gpiod_flags flags);
86void devm_gpiod_put(struct device *dev, struct gpio_desc *desc); 92void devm_gpiod_put(struct device *dev, struct gpio_desc *desc);
93void devm_gpiod_put_array(struct device *dev, struct gpio_descs *descs);
87 94
88int gpiod_get_direction(struct gpio_desc *desc); 95int gpiod_get_direction(struct gpio_desc *desc);
89int gpiod_direction_input(struct gpio_desc *desc); 96int gpiod_direction_input(struct gpio_desc *desc);
@@ -228,6 +235,20 @@ __devm_gpiod_get_index_optional(struct device *dev, const char *con_id,
228 return ERR_PTR(-ENOSYS); 235 return ERR_PTR(-ENOSYS);
229} 236}
230 237
238static inline struct gpio_descs *__must_check
239devm_gpiod_get_array(struct device *dev, const char *con_id,
240 enum gpiod_flags flags)
241{
242 return ERR_PTR(-ENOSYS);
243}
244
245static inline struct gpio_descs *__must_check
246devm_gpiod_get_array_optional(struct device *dev, const char *con_id,
247 enum gpiod_flags flags)
248{
249 return ERR_PTR(-ENOSYS);
250}
251
231static inline void devm_gpiod_put(struct device *dev, struct gpio_desc *desc) 252static inline void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
232{ 253{
233 might_sleep(); 254 might_sleep();
@@ -236,6 +257,15 @@ static inline void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
236 WARN_ON(1); 257 WARN_ON(1);
237} 258}
238 259
260static inline void devm_gpiod_put_array(struct device *dev,
261 struct gpio_descs *descs)
262{
263 might_sleep();
264
265 /* GPIO can never have been requested */
266 WARN_ON(1);
267}
268
239 269
240static inline int gpiod_get_direction(const struct gpio_desc *desc) 270static inline int gpiod_get_direction(const struct gpio_desc *desc)
241{ 271{