aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2014-04-25 11:10:06 -0400
committerLinus Walleij <linus.walleij@linaro.org>2014-05-09 07:48:30 -0400
commit29a1f2333e07bbbecb920cc78fd035fe8f53207a (patch)
treeb2cb50d4c41ff4d1337cca888da3840f6f0d4d84
parent91329132c909bbeb27699556b98b7f745ddb2ed9 (diff)
gpio: Add helpers for optional GPIOs
Introduce gpiod_get_optional() and gpiod_get_index_optional() helpers that make it easier for drivers to handle optional GPIOs. Currently in order to handle optional GPIOs, a driver needs to special case error handling for -ENOENT, such as this: gpio = gpiod_get(dev, "foo"); if (IS_ERR(gpio)) { if (PTR_ERR(gpio) != -ENOENT) return PTR_ERR(gpio); gpio = NULL; } if (gpio) { /* set up GPIO */ } With these new helpers the above is reduced to: gpio = gpiod_get_optional(dev, "foo"); if (IS_ERR(gpio)) return PTR_ERR(gpio); if (gpio) { /* set up GPIO */ } While at it, device-managed variants of these functions are also provided. Signed-off-by: Thierry Reding <treding@nvidia.com> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--Documentation/driver-model/devres.txt2
-rw-r--r--drivers/gpio/devres.c43
-rw-r--r--drivers/gpio/gpiolib.c43
-rw-r--r--include/linux/gpio/consumer.h40
4 files changed, 128 insertions, 0 deletions
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index 8ff1167cfedf..10b8c5d2c797 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -312,4 +312,6 @@ SPI
312GPIO 312GPIO
313 devm_gpiod_get() 313 devm_gpiod_get()
314 devm_gpiod_get_index() 314 devm_gpiod_get_index()
315 devm_gpiod_get_optional()
316 devm_gpiod_get_index_optional()
315 devm_gpiod_put() 317 devm_gpiod_put()
diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c
index 307464fd015f..65978cf85f79 100644
--- a/drivers/gpio/devres.c
+++ b/drivers/gpio/devres.c
@@ -52,6 +52,22 @@ struct gpio_desc *__must_check devm_gpiod_get(struct device *dev,
52EXPORT_SYMBOL(devm_gpiod_get); 52EXPORT_SYMBOL(devm_gpiod_get);
53 53
54/** 54/**
55 * devm_gpiod_get_optional - Resource-managed gpiod_get_optional()
56 * @dev: GPIO consumer
57 * @con_id: function within the GPIO consumer
58 *
59 * Managed gpiod_get_optional(). GPIO descriptors returned from this function
60 * are automatically disposed on driver detach. See gpiod_get_optional() for
61 * detailed information about behavior and return values.
62 */
63struct gpio_desc *__must_check devm_gpiod_get_optional(struct device *dev,
64 const char *con_id)
65{
66 return devm_gpiod_get_index_optional(dev, con_id, 0);
67}
68EXPORT_SYMBOL(devm_gpiod_get_optional);
69
70/**
55 * devm_gpiod_get_index - Resource-managed gpiod_get_index() 71 * devm_gpiod_get_index - Resource-managed gpiod_get_index()
56 * @dev: GPIO consumer 72 * @dev: GPIO consumer
57 * @con_id: function within the GPIO consumer 73 * @con_id: function within the GPIO consumer
@@ -87,6 +103,33 @@ struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
87EXPORT_SYMBOL(devm_gpiod_get_index); 103EXPORT_SYMBOL(devm_gpiod_get_index);
88 104
89/** 105/**
106 * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional()
107 * @dev: GPIO consumer
108 * @con_id: function within the GPIO consumer
109 * @index: index of the GPIO to obtain in the consumer
110 *
111 * Managed gpiod_get_index_optional(). GPIO descriptors returned from this
112 * function are automatically disposed on driver detach. See
113 * gpiod_get_index_optional() for detailed information about behavior and
114 * return values.
115 */
116struct gpio_desc *__must_check devm_gpiod_get_index_optional(struct device *dev,
117 const char *con_id,
118 unsigned int index)
119{
120 struct gpio_desc *desc;
121
122 desc = devm_gpiod_get_index(dev, con_id, index);
123 if (IS_ERR(desc)) {
124 if (PTR_ERR(desc) == -ENOENT)
125 return NULL;
126 }
127
128 return desc;
129}
130EXPORT_SYMBOL(devm_gpiod_get_index_optional);
131
132/**
90 * devm_gpiod_put - Resource-managed gpiod_put() 133 * devm_gpiod_put - Resource-managed gpiod_put()
91 * @desc: GPIO descriptor to dispose of 134 * @desc: GPIO descriptor to dispose of
92 * 135 *
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 4ad110e793c5..d9c9cb4665db 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2738,6 +2738,22 @@ struct gpio_desc *__must_check gpiod_get(struct device *dev, const char *con_id)
2738EXPORT_SYMBOL_GPL(gpiod_get); 2738EXPORT_SYMBOL_GPL(gpiod_get);
2739 2739
2740/** 2740/**
2741 * gpiod_get_optional - obtain an optional GPIO for a given GPIO function
2742 * @dev: GPIO consumer, can be NULL for system-global GPIOs
2743 * @con_id: function within the GPIO consumer
2744 *
2745 * This is equivalent to gpiod_get(), except that when no GPIO was assigned to
2746 * the requested function it will return NULL. This is convenient for drivers
2747 * that need to handle optional GPIOs.
2748 */
2749struct gpio_desc *__must_check gpiod_get_optional(struct device *dev,
2750 const char *con_id)
2751{
2752 return gpiod_get_index_optional(dev, con_id, 0);
2753}
2754EXPORT_SYMBOL_GPL(gpiod_get_optional);
2755
2756/**
2741 * gpiod_get_index - obtain a GPIO from a multi-index GPIO function 2757 * gpiod_get_index - obtain a GPIO from a multi-index GPIO function
2742 * @dev: GPIO consumer, can be NULL for system-global GPIOs 2758 * @dev: GPIO consumer, can be NULL for system-global GPIOs
2743 * @con_id: function within the GPIO consumer 2759 * @con_id: function within the GPIO consumer
@@ -2800,6 +2816,33 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
2800EXPORT_SYMBOL_GPL(gpiod_get_index); 2816EXPORT_SYMBOL_GPL(gpiod_get_index);
2801 2817
2802/** 2818/**
2819 * gpiod_get_index_optional - obtain an optional GPIO from a multi-index GPIO
2820 * function
2821 * @dev: GPIO consumer, can be NULL for system-global GPIOs
2822 * @con_id: function within the GPIO consumer
2823 * @index: index of the GPIO to obtain in the consumer
2824 *
2825 * This is equivalent to gpiod_get_index(), except that when no GPIO with the
2826 * specified index was assigned to the requested function it will return NULL.
2827 * This is convenient for drivers that need to handle optional GPIOs.
2828 */
2829struct gpio_desc *__must_check gpiod_get_index_optional(struct device *dev,
2830 const char *con_id,
2831 unsigned int index)
2832{
2833 struct gpio_desc *desc;
2834
2835 desc = gpiod_get_index(dev, con_id, index);
2836 if (IS_ERR(desc)) {
2837 if (PTR_ERR(desc) == -ENOENT)
2838 return NULL;
2839 }
2840
2841 return desc;
2842}
2843EXPORT_SYMBOL_GPL(gpiod_get_index_optional);
2844
2845/**
2803 * gpiod_put - dispose of a GPIO descriptor 2846 * gpiod_put - dispose of a GPIO descriptor
2804 * @desc: GPIO descriptor to dispose of 2847 * @desc: GPIO descriptor to dispose of
2805 * 2848 *
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
index bed128e8f4b1..6a37ef0dc59c 100644
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
@@ -23,6 +23,12 @@ struct gpio_desc *__must_check gpiod_get(struct device *dev,
23struct gpio_desc *__must_check gpiod_get_index(struct device *dev, 23struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
24 const char *con_id, 24 const char *con_id,
25 unsigned int idx); 25 unsigned int idx);
26struct gpio_desc *__must_check gpiod_get_optional(struct device *dev,
27 const char *con_id);
28struct gpio_desc *__must_check gpiod_get_index_optional(struct device *dev,
29 const char *con_id,
30 unsigned int index);
31
26void gpiod_put(struct gpio_desc *desc); 32void gpiod_put(struct gpio_desc *desc);
27 33
28struct gpio_desc *__must_check devm_gpiod_get(struct device *dev, 34struct gpio_desc *__must_check devm_gpiod_get(struct device *dev,
@@ -30,6 +36,12 @@ struct gpio_desc *__must_check devm_gpiod_get(struct device *dev,
30struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev, 36struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
31 const char *con_id, 37 const char *con_id,
32 unsigned int idx); 38 unsigned int idx);
39struct gpio_desc *__must_check devm_gpiod_get_optional(struct device *dev,
40 const char *con_id);
41struct gpio_desc *__must_check
42devm_gpiod_get_index_optional(struct device *dev, const char *con_id,
43 unsigned int index);
44
33void devm_gpiod_put(struct device *dev, struct gpio_desc *desc); 45void devm_gpiod_put(struct device *dev, struct gpio_desc *desc);
34 46
35int gpiod_get_direction(const struct gpio_desc *desc); 47int gpiod_get_direction(const struct gpio_desc *desc);
@@ -73,6 +85,20 @@ static inline struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
73{ 85{
74 return ERR_PTR(-ENOSYS); 86 return ERR_PTR(-ENOSYS);
75} 87}
88
89static inline struct gpio_desc *__must_check
90gpiod_get_optional(struct device *dev, const char *con_id)
91{
92 return ERR_PTR(-ENOSYS);
93}
94
95static inline struct gpio_desc *__must_check
96gpiod_get_index_optional(struct device *dev, const char *con_id,
97 unsigned int index)
98{
99 return ERR_PTR(-ENOSYS);
100}
101
76static inline void gpiod_put(struct gpio_desc *desc) 102static inline void gpiod_put(struct gpio_desc *desc)
77{ 103{
78 might_sleep(); 104 might_sleep();
@@ -93,6 +119,20 @@ struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
93{ 119{
94 return ERR_PTR(-ENOSYS); 120 return ERR_PTR(-ENOSYS);
95} 121}
122
123static inline struct gpio_desc *__must_check
124devm_gpiod_get_optional(struct device *dev, const char *con_id)
125{
126 return ERR_PTR(-ENOSYS);
127}
128
129static inline struct gpio_desc *__must_check
130devm_gpiod_get_index_optional(struct device *dev, const char *con_id,
131 unsigned int index)
132{
133 return ERR_PTR(-ENOSYS);
134}
135
96static inline void devm_gpiod_put(struct device *dev, struct gpio_desc *desc) 136static inline void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
97{ 137{
98 might_sleep(); 138 might_sleep();