diff options
author | Boris Brezillon <boris.brezillon@free-electrons.com> | 2017-02-02 08:53:11 -0500 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2017-02-04 15:28:51 -0500 |
commit | 537b94dafce29af6a3e923d216472cfc2f3659af (patch) | |
tree | 358e78fe44033fb00490111fea7b873ef16ce0f5 | |
parent | 4b0947974e593d52aace18ca5c7e2746fdebae60 (diff) |
gpio: Add the devm_fwnode_get_index_gpiod_from_child() helper
devm_fwnode_get_gpiod_from_child() currently allows GPIO users to
request a GPIO that is defined in a child fwnode instead of directly in
the device fwnode.
Extend this API by adding the devm_fwnode_get_index_gpiod_from_child()
helper which does the same except you can also specify an index in case
the 'xx-gpios' property describe several GPIOs.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r-- | drivers/gpio/devres.c | 20 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 9 | ||||
-rw-r--r-- | include/linux/gpio/consumer.h | 31 |
3 files changed, 37 insertions, 23 deletions
diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index cd1bd1c3d2c0..b2bbcaae6a1f 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c | |||
@@ -123,10 +123,11 @@ struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev, | |||
123 | EXPORT_SYMBOL(devm_gpiod_get_index); | 123 | EXPORT_SYMBOL(devm_gpiod_get_index); |
124 | 124 | ||
125 | /** | 125 | /** |
126 | * devm_fwnode_get_gpiod_from_child - get a GPIO descriptor from a device's | 126 | * devm_fwnode_get_index_gpiod_from_child - get a GPIO descriptor from a |
127 | * child node | 127 | * device's child node |
128 | * @dev: GPIO consumer | 128 | * @dev: GPIO consumer |
129 | * @con_id: function within the GPIO consumer | 129 | * @con_id: function within the GPIO consumer |
130 | * @index: index of the GPIO to obtain in the consumer | ||
130 | * @child: firmware node (child of @dev) | 131 | * @child: firmware node (child of @dev) |
131 | * @flags: GPIO initialization flags | 132 | * @flags: GPIO initialization flags |
132 | * | 133 | * |
@@ -136,11 +137,11 @@ EXPORT_SYMBOL(devm_gpiod_get_index); | |||
136 | * On successfull request the GPIO pin is configured in accordance with | 137 | * On successfull request the GPIO pin is configured in accordance with |
137 | * provided @flags. | 138 | * provided @flags. |
138 | */ | 139 | */ |
139 | struct gpio_desc *devm_fwnode_get_gpiod_from_child(struct device *dev, | 140 | struct gpio_desc *devm_fwnode_get_index_gpiod_from_child(struct device *dev, |
140 | const char *con_id, | 141 | const char *con_id, int index, |
141 | struct fwnode_handle *child, | 142 | struct fwnode_handle *child, |
142 | enum gpiod_flags flags, | 143 | enum gpiod_flags flags, |
143 | const char *label) | 144 | const char *label) |
144 | { | 145 | { |
145 | static const char * const suffixes[] = { "gpios", "gpio" }; | 146 | static const char * const suffixes[] = { "gpios", "gpio" }; |
146 | char prop_name[32]; /* 32 is max size of property name */ | 147 | char prop_name[32]; /* 32 is max size of property name */ |
@@ -161,7 +162,8 @@ struct gpio_desc *devm_fwnode_get_gpiod_from_child(struct device *dev, | |||
161 | snprintf(prop_name, sizeof(prop_name), "%s", | 162 | snprintf(prop_name, sizeof(prop_name), "%s", |
162 | suffixes[i]); | 163 | suffixes[i]); |
163 | 164 | ||
164 | desc = fwnode_get_named_gpiod(child, prop_name, flags, label); | 165 | desc = fwnode_get_named_gpiod(child, prop_name, index, flags, |
166 | label); | ||
165 | if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT)) | 167 | if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT)) |
166 | break; | 168 | break; |
167 | } | 169 | } |
@@ -175,7 +177,7 @@ struct gpio_desc *devm_fwnode_get_gpiod_from_child(struct device *dev, | |||
175 | 177 | ||
176 | return desc; | 178 | return desc; |
177 | } | 179 | } |
178 | EXPORT_SYMBOL(devm_fwnode_get_gpiod_from_child); | 180 | EXPORT_SYMBOL(devm_fwnode_get_index_gpiod_from_child); |
179 | 181 | ||
180 | /** | 182 | /** |
181 | * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional() | 183 | * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional() |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 20c6c51cbe10..5e5d48c3512c 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -3309,6 +3309,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_index); | |||
3309 | * fwnode_get_named_gpiod - obtain a GPIO from firmware node | 3309 | * fwnode_get_named_gpiod - obtain a GPIO from firmware node |
3310 | * @fwnode: handle of the firmware node | 3310 | * @fwnode: handle of the firmware node |
3311 | * @propname: name of the firmware property representing the GPIO | 3311 | * @propname: name of the firmware property representing the GPIO |
3312 | * @index: index of the GPIO to obtain in the consumer | ||
3312 | * @dflags: GPIO initialization flags | 3313 | * @dflags: GPIO initialization flags |
3313 | * | 3314 | * |
3314 | * This function can be used for drivers that get their configuration | 3315 | * This function can be used for drivers that get their configuration |
@@ -3324,7 +3325,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_index); | |||
3324 | * In case of error an ERR_PTR() is returned. | 3325 | * In case of error an ERR_PTR() is returned. |
3325 | */ | 3326 | */ |
3326 | struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, | 3327 | struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, |
3327 | const char *propname, | 3328 | const char *propname, int index, |
3328 | enum gpiod_flags dflags, | 3329 | enum gpiod_flags dflags, |
3329 | const char *label) | 3330 | const char *label) |
3330 | { | 3331 | { |
@@ -3340,8 +3341,8 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, | |||
3340 | if (is_of_node(fwnode)) { | 3341 | if (is_of_node(fwnode)) { |
3341 | enum of_gpio_flags flags; | 3342 | enum of_gpio_flags flags; |
3342 | 3343 | ||
3343 | desc = of_get_named_gpiod_flags(to_of_node(fwnode), propname, 0, | 3344 | desc = of_get_named_gpiod_flags(to_of_node(fwnode), propname, |
3344 | &flags); | 3345 | index, &flags); |
3345 | if (!IS_ERR(desc)) { | 3346 | if (!IS_ERR(desc)) { |
3346 | active_low = flags & OF_GPIO_ACTIVE_LOW; | 3347 | active_low = flags & OF_GPIO_ACTIVE_LOW; |
3347 | single_ended = flags & OF_GPIO_SINGLE_ENDED; | 3348 | single_ended = flags & OF_GPIO_SINGLE_ENDED; |
@@ -3349,7 +3350,7 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, | |||
3349 | } else if (is_acpi_node(fwnode)) { | 3350 | } else if (is_acpi_node(fwnode)) { |
3350 | struct acpi_gpio_info info; | 3351 | struct acpi_gpio_info info; |
3351 | 3352 | ||
3352 | desc = acpi_node_get_gpiod(fwnode, propname, 0, &info); | 3353 | desc = acpi_node_get_gpiod(fwnode, propname, index, &info); |
3353 | if (!IS_ERR(desc)) | 3354 | if (!IS_ERR(desc)) |
3354 | active_low = info.polarity == GPIO_ACTIVE_LOW; | 3355 | active_low = info.polarity == GPIO_ACTIVE_LOW; |
3355 | } | 3356 | } |
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index f32f49e96c0b..ea9b01d40017 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h | |||
@@ -135,14 +135,14 @@ int desc_to_gpio(const struct gpio_desc *desc); | |||
135 | struct fwnode_handle; | 135 | struct fwnode_handle; |
136 | 136 | ||
137 | struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, | 137 | struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, |
138 | const char *propname, | 138 | const char *propname, int index, |
139 | enum gpiod_flags dflags, | 139 | enum gpiod_flags dflags, |
140 | const char *label); | 140 | const char *label); |
141 | struct gpio_desc *devm_fwnode_get_gpiod_from_child(struct device *dev, | 141 | struct gpio_desc *devm_fwnode_get_index_gpiod_from_child(struct device *dev, |
142 | const char *con_id, | 142 | const char *con_id, int index, |
143 | struct fwnode_handle *child, | 143 | struct fwnode_handle *child, |
144 | enum gpiod_flags flags, | 144 | enum gpiod_flags flags, |
145 | const char *label); | 145 | const char *label); |
146 | #else /* CONFIG_GPIOLIB */ | 146 | #else /* CONFIG_GPIOLIB */ |
147 | 147 | ||
148 | static inline int gpiod_count(struct device *dev, const char *con_id) | 148 | static inline int gpiod_count(struct device *dev, const char *con_id) |
@@ -417,7 +417,7 @@ struct fwnode_handle; | |||
417 | 417 | ||
418 | static inline | 418 | static inline |
419 | struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, | 419 | struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, |
420 | const char *propname, | 420 | const char *propname, int index, |
421 | enum gpiod_flags dflags, | 421 | enum gpiod_flags dflags, |
422 | const char *label) | 422 | const char *label) |
423 | { | 423 | { |
@@ -425,17 +425,28 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, | |||
425 | } | 425 | } |
426 | 426 | ||
427 | static inline | 427 | static inline |
428 | struct gpio_desc *devm_fwnode_get_index_gpiod_from_child(struct device *dev, | ||
429 | const char *con_id, int index, | ||
430 | struct fwnode_handle *child, | ||
431 | enum gpiod_flags flags, | ||
432 | const char *label) | ||
433 | { | ||
434 | return ERR_PTR(-ENOSYS); | ||
435 | } | ||
436 | |||
437 | #endif /* CONFIG_GPIOLIB */ | ||
438 | |||
439 | static inline | ||
428 | struct gpio_desc *devm_fwnode_get_gpiod_from_child(struct device *dev, | 440 | struct gpio_desc *devm_fwnode_get_gpiod_from_child(struct device *dev, |
429 | const char *con_id, | 441 | const char *con_id, |
430 | struct fwnode_handle *child, | 442 | struct fwnode_handle *child, |
431 | enum gpiod_flags flags, | 443 | enum gpiod_flags flags, |
432 | const char *label) | 444 | const char *label) |
433 | { | 445 | { |
434 | return ERR_PTR(-ENOSYS); | 446 | return devm_fwnode_get_index_gpiod_from_child(dev, con_id, 0, child, |
447 | flags, label); | ||
435 | } | 448 | } |
436 | 449 | ||
437 | #endif /* CONFIG_GPIOLIB */ | ||
438 | |||
439 | #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS) | 450 | #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS) |
440 | 451 | ||
441 | int gpiod_export(struct gpio_desc *desc, bool direction_may_change); | 452 | int gpiod_export(struct gpio_desc *desc, bool direction_may_change); |