aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Courbot <acourbot@nvidia.com>2013-10-17 13:21:38 -0400
committerLinus Walleij <linus.walleij@linaro.org>2013-10-19 17:24:56 -0400
commitbae48da237fcedd7ad09569025483b988635efb7 (patch)
tree51d82d78acc5e248623dd73d9e5deb2ce4f0e869
parentaf8b6375a8291fe2cf77707f3edec86b98a999cc (diff)
gpiolib: add gpiod_get() and gpiod_put() functions
Add gpiod_get(), gpiod_get_index() and gpiod_put() functions that provide safer management of GPIOs. These functions put the GPIO framework in line with the conventions of other frameworks in the kernel, and help ensure every GPIO is declared properly and valid while it is used. Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/gpio/devres.c83
-rw-r--r--drivers/gpio/gpiolib.c203
-rw-r--r--include/linux/gpio/consumer.h15
-rw-r--r--include/linux/gpio/driver.h56
4 files changed, 357 insertions, 0 deletions
diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c
index 3e7812f0405e..2caa2571734e 100644
--- a/drivers/gpio/devres.c
+++ b/drivers/gpio/devres.c
@@ -19,6 +19,89 @@
19#include <linux/device.h> 19#include <linux/device.h>
20#include <linux/gfp.h> 20#include <linux/gfp.h>
21 21
22static void devm_gpiod_release(struct device *dev, void *res)
23{
24 struct gpio_desc **desc = res;
25
26 gpiod_put(*desc);
27}
28
29static 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 */
45struct 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}
50EXPORT_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 */
62struct 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 0;
84}
85EXPORT_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 */
95void 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}
100EXPORT_SYMBOL(devm_gpiod_put);
101
102
103
104
22static void devm_gpio_release(struct device *dev, void *res) 105static void devm_gpio_release(struct device *dev, void *res)
23{ 106{
24 unsigned *gpio = res; 107 unsigned *gpio = res;
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 224abdc4b095..9263c7b359b7 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -70,6 +70,8 @@ static struct gpio_desc gpio_desc[ARCH_NR_GPIOS];
70 70
71#define GPIO_OFFSET_VALID(chip, offset) (offset >= 0 && offset < chip->ngpio) 71#define GPIO_OFFSET_VALID(chip, offset) (offset >= 0 && offset < chip->ngpio)
72 72
73static DEFINE_MUTEX(gpio_lookup_lock);
74static LIST_HEAD(gpio_lookup_list);
73static LIST_HEAD(gpio_chips); 75static LIST_HEAD(gpio_chips);
74 76
75#ifdef CONFIG_GPIO_SYSFS 77#ifdef CONFIG_GPIO_SYSFS
@@ -2192,6 +2194,207 @@ void gpiod_set_value_cansleep(struct gpio_desc *desc, int value)
2192} 2194}
2193EXPORT_SYMBOL_GPL(gpiod_set_value_cansleep); 2195EXPORT_SYMBOL_GPL(gpiod_set_value_cansleep);
2194 2196
2197/**
2198 * gpiod_add_table() - register GPIO device consumers
2199 * @table: array of consumers to register
2200 * @num: number of consumers in table
2201 */
2202void gpiod_add_table(struct gpiod_lookup *table, size_t size)
2203{
2204 mutex_lock(&gpio_lookup_lock);
2205
2206 while (size--) {
2207 list_add_tail(&table->list, &gpio_lookup_list);
2208 table++;
2209 }
2210
2211 mutex_unlock(&gpio_lookup_lock);
2212}
2213
2214/*
2215 * Caller must have a acquired gpio_lookup_lock
2216 */
2217static struct gpio_chip *find_chip_by_name(const char *name)
2218{
2219 struct gpio_chip *chip = NULL;
2220
2221 list_for_each_entry(chip, &gpio_lookup_list, list) {
2222 if (chip->label == NULL)
2223 continue;
2224 if (!strcmp(chip->label, name))
2225 break;
2226 }
2227
2228 return chip;
2229}
2230
2231#ifdef CONFIG_OF
2232static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
2233 unsigned int idx, unsigned long *flags)
2234{
2235 char prop_name[32]; /* 32 is max size of property name */
2236 enum of_gpio_flags of_flags;
2237 struct gpio_desc *desc;
2238
2239 if (con_id)
2240 snprintf(prop_name, 32, "%s-gpios", con_id);
2241 else
2242 snprintf(prop_name, 32, "gpios");
2243
2244 desc = of_get_named_gpiod_flags(dev->of_node, prop_name, idx,
2245 &of_flags);
2246
2247 if (IS_ERR(desc))
2248 return desc;
2249
2250 if (of_flags & OF_GPIO_ACTIVE_LOW)
2251 *flags |= GPIOF_ACTIVE_LOW;
2252
2253 return desc;
2254}
2255#else
2256static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
2257 unsigned int idx, unsigned long *flags)
2258{
2259 return ERR_PTR(-ENODEV);
2260}
2261#endif
2262
2263static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id,
2264 unsigned int idx, unsigned long *flags)
2265{
2266 const char *dev_id = dev ? dev_name(dev) : NULL;
2267 struct gpio_desc *desc = ERR_PTR(-ENODEV);
2268 unsigned int match, best = 0;
2269 struct gpiod_lookup *p;
2270
2271 mutex_lock(&gpio_lookup_lock);
2272
2273 list_for_each_entry(p, &gpio_lookup_list, list) {
2274 match = 0;
2275
2276 if (p->dev_id) {
2277 if (!dev_id || strcmp(p->dev_id, dev_id))
2278 continue;
2279
2280 match += 2;
2281 }
2282
2283 if (p->con_id) {
2284 if (!con_id || strcmp(p->con_id, con_id))
2285 continue;
2286
2287 match += 1;
2288 }
2289
2290 if (p->idx != idx)
2291 continue;
2292
2293 if (match > best) {
2294 struct gpio_chip *chip;
2295
2296 chip = find_chip_by_name(p->chip_label);
2297
2298 if (!chip) {
2299 dev_warn(dev, "cannot find GPIO chip %s\n",
2300 p->chip_label);
2301 continue;
2302 }
2303
2304 if (chip->ngpio >= p->chip_hwnum) {
2305 dev_warn(dev, "GPIO chip %s has %d GPIOs\n",
2306 chip->label, chip->ngpio);
2307 continue;
2308 }
2309
2310 desc = gpio_to_desc(chip->base + p->chip_hwnum);
2311 *flags = p->flags;
2312
2313 if (match != 3)
2314 best = match;
2315 else
2316 break;
2317 }
2318 }
2319
2320 mutex_unlock(&gpio_lookup_lock);
2321
2322 return desc;
2323}
2324
2325/**
2326 * gpio_get - obtain a GPIO for a given GPIO function
2327 * @dev: GPIO consumer
2328 * @con_id: function within the GPIO consumer
2329 *
2330 * Return the GPIO descriptor corresponding to the function con_id of device
2331 * dev, or an IS_ERR() condition if an error occured.
2332 */
2333struct gpio_desc *__must_check gpiod_get(struct device *dev, const char *con_id)
2334{
2335 return gpiod_get_index(dev, con_id, 0);
2336}
2337EXPORT_SYMBOL_GPL(gpiod_get);
2338
2339/**
2340 * gpiod_get_index - obtain a GPIO from a multi-index GPIO function
2341 * @dev: GPIO consumer
2342 * @con_id: function within the GPIO consumer
2343 * @idx: index of the GPIO to obtain in the consumer
2344 *
2345 * This variant of gpiod_get() allows to access GPIOs other than the first
2346 * defined one for functions that define several GPIOs.
2347 *
2348 * Return a valid GPIO descriptor, or an IS_ERR() condition in case of error.
2349 */
2350struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
2351 const char *con_id,
2352 unsigned int idx)
2353{
2354 struct gpio_desc *desc;
2355 int status;
2356 unsigned long flags = 0;
2357
2358 dev_dbg(dev, "GPIO lookup for consumer %s\n", con_id);
2359
2360 /* Using device tree? */
2361 if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node) {
2362 dev_dbg(dev, "using device tree for GPIO lookup\n");
2363 desc = of_find_gpio(dev, con_id, idx, &flags);
2364 } else {
2365 dev_dbg(dev, "using lookup tables for GPIO lookup");
2366 desc = gpiod_find(dev, con_id, idx, &flags);
2367 }
2368
2369 if (IS_ERR(desc)) {
2370 dev_warn(dev, "lookup for GPIO %s failed\n", con_id);
2371 return desc;
2372 }
2373
2374 status = gpiod_request(desc, con_id);
2375
2376 if (status < 0)
2377 return ERR_PTR(status);
2378
2379 if (flags & GPIOF_ACTIVE_LOW)
2380 set_bit(FLAG_ACTIVE_LOW, &desc->flags);
2381
2382 return desc;
2383}
2384EXPORT_SYMBOL_GPL(gpiod_get_index);
2385
2386/**
2387 * gpiod_put - dispose of a GPIO descriptor
2388 * @desc: GPIO descriptor to dispose of
2389 *
2390 * No descriptor can be used after gpiod_put() has been called on it.
2391 */
2392void gpiod_put(struct gpio_desc *desc)
2393{
2394 gpiod_free(desc);
2395}
2396EXPORT_SYMBOL_GPL(gpiod_put);
2397
2195#ifdef CONFIG_DEBUG_FS 2398#ifdef CONFIG_DEBUG_FS
2196 2399
2197static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) 2400static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
index 2088eb50421c..4d34dbbbad4d 100644
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
@@ -18,6 +18,21 @@ struct gpio_chip;
18 */ 18 */
19struct gpio_desc; 19struct gpio_desc;
20 20
21/* Acquire and dispose GPIOs */
22struct gpio_desc *__must_check gpiod_get(struct device *dev,
23 const char *con_id);
24struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
25 const char *con_id,
26 unsigned int idx);
27void gpiod_put(struct gpio_desc *desc);
28
29struct gpio_desc *__must_check devm_gpiod_get(struct device *dev,
30 const char *con_id);
31struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
32 const char *con_id,
33 unsigned int idx);
34void devm_gpiod_put(struct device *dev, struct gpio_desc *desc);
35
21int gpiod_get_direction(const struct gpio_desc *desc); 36int gpiod_get_direction(const struct gpio_desc *desc);
22int gpiod_direction_input(struct gpio_desc *desc); 37int gpiod_direction_input(struct gpio_desc *desc);
23int gpiod_direction_output(struct gpio_desc *desc, int value); 38int gpiod_direction_output(struct gpio_desc *desc, int value);
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index 5dc172c72f0f..cd9da3885d79 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -124,4 +124,60 @@ extern struct gpio_chip *gpiochip_find(void *data,
124int gpiod_lock_as_irq(struct gpio_desc *desc); 124int gpiod_lock_as_irq(struct gpio_desc *desc);
125void gpiod_unlock_as_irq(struct gpio_desc *desc); 125void gpiod_unlock_as_irq(struct gpio_desc *desc);
126 126
127/**
128 * Lookup table for associating GPIOs to specific devices and functions using
129 * platform data.
130 */
131struct gpiod_lookup {
132 struct list_head list;
133 /*
134 * name of the chip the GPIO belongs to
135 */
136 const char *chip_label;
137 /*
138 * hardware number (i.e. relative to the chip) of the GPIO
139 */
140 u16 chip_hwnum;
141 /*
142 * name of device that can claim this GPIO
143 */
144 const char *dev_id;
145 /*
146 * name of the GPIO from the device's point of view
147 */
148 const char *con_id;
149 /*
150 * index of the GPIO in case several GPIOs share the same name
151 */
152 unsigned int idx;
153 /*
154 * mask of GPIOF_* values
155 */
156 unsigned long flags;
157};
158
159/*
160 * Simple definition of a single GPIO under a con_id
161 */
162#define GPIO_LOOKUP(_chip_label, _chip_hwnum, _dev_id, _con_id, _flags) \
163 GPIO_LOOKUP_IDX(_chip_label, _chip_hwnum, _dev_id, _con_id, 0, _flags)
164
165/*
166 * Use this macro if you need to have several GPIOs under the same con_id.
167 * Each GPIO needs to use a different index and can be accessed using
168 * gpiod_get_index()
169 */
170#define GPIO_LOOKUP_IDX(_chip_label, _chip_hwnum, _dev_id, _con_id, _idx, \
171 _flags) \
172{ \
173 .chip_label = _chip_label, \
174 .chip_hwnum = _chip_hwnum, \
175 .dev_id = _dev_id, \
176 .con_id = _con_id, \
177 .idx = _idx, \
178 .flags = _flags, \
179}
180
181void gpiod_add_table(struct gpiod_lookup *table, size_t size);
182
127#endif 183#endif