From baddc7ca446c18c68a0c8b298fd9920bf049efce Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 20 Dec 2016 19:57:55 +0100 Subject: gpio: update my email address This patch updates my email address as I no longer have access to the old one. Signed-off-by: John Crispin Signed-off-by: Linus Walleij --- drivers/gpio/devres.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio/devres.c') diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index b760cbbb41d8..b1c41db52089 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c @@ -11,7 +11,7 @@ * * This file is based on kernel/irq/devres.c * - * Copyright (c) 2011 John Crispin + * Copyright (c) 2011 John Crispin */ #include -- cgit From 200d0177b4623cf218239ad7a21466459c174bff Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 3 Jan 2017 19:00:20 +0200 Subject: gpio: devres: Use global array of gpio suffixes We have already a global array of possible GPIO suffixes. Use it here instead of another copy of them. Unfortunately this will not reduce the memory footprint, though allows to easy maintain list in only one place. Signed-off-by: Andy Shevchenko Signed-off-by: Linus Walleij --- drivers/gpio/devres.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/gpio/devres.c') diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index b1c41db52089..2c49a8bc9e3f 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c @@ -21,6 +21,8 @@ #include #include +#include "gpiolib.h" + static void devm_gpiod_release(struct device *dev, void *res) { struct gpio_desc **desc = res; @@ -135,7 +137,6 @@ struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, const char *con_id, struct fwnode_handle *child) { - static const char * const suffixes[] = { "gpios", "gpio" }; char prop_name[32]; /* 32 is max size of property name */ struct gpio_desc **dr; struct gpio_desc *desc; @@ -146,13 +147,13 @@ struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, if (!dr) return ERR_PTR(-ENOMEM); - for (i = 0; i < ARRAY_SIZE(suffixes); i++) { + for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { if (con_id) snprintf(prop_name, sizeof(prop_name), "%s-%s", - con_id, suffixes[i]); + con_id, gpio_suffixes[i]); else snprintf(prop_name, sizeof(prop_name), "%s", - suffixes[i]); + gpio_suffixes[i]); desc = fwnode_get_named_gpiod(child, prop_name); if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT)) -- cgit From a264d10ff45c688293d9112fddd8d29c819e0853 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 9 Jan 2017 16:02:28 +0200 Subject: gpiolib: Convert fwnode_get_named_gpiod() to configure GPIO Make fwnode_get_named_gpiod() consistent with the rest of gpiod_get() like API, i.e. configure GPIO pin immediately after request. Besides obvious clean up it will help to configure pins based on firmware provided resources. Reviewed-by: Mika Westerberg Signed-off-by: Andy Shevchenko Signed-off-by: Linus Walleij --- drivers/gpio/devres.c | 9 +++++++-- drivers/gpio/gpiolib.c | 20 ++++++++++++++++---- drivers/input/keyboard/gpio_keys.c | 9 +-------- drivers/input/keyboard/gpio_keys_polled.c | 11 ++--------- drivers/leds/leds-gpio.c | 2 +- drivers/video/fbdev/amba-clcd-nomadik.c | 15 +++++---------- include/linux/gpio/consumer.h | 19 +++++++++++++------ 7 files changed, 45 insertions(+), 40 deletions(-) (limited to 'drivers/gpio/devres.c') diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index b760cbbb41d8..5e0b41b5e554 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c @@ -127,13 +127,18 @@ EXPORT_SYMBOL(devm_gpiod_get_index); * @dev: GPIO consumer * @con_id: function within the GPIO consumer * @child: firmware node (child of @dev) + * @flags: GPIO initialization flags * * GPIO descriptors returned from this function are automatically disposed on * driver detach. + * + * On successfull request the GPIO pin is configured in accordance with + * provided @flags. */ struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, const char *con_id, - struct fwnode_handle *child) + struct fwnode_handle *child, + enum gpiod_flags flags) { static const char * const suffixes[] = { "gpios", "gpio" }; char prop_name[32]; /* 32 is max size of property name */ @@ -154,7 +159,7 @@ struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, snprintf(prop_name, sizeof(prop_name), "%s", suffixes[i]); - desc = fwnode_get_named_gpiod(child, prop_name); + desc = fwnode_get_named_gpiod(child, prop_name, flags); if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT)) break; } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index f4c26c7826cd..bb3d3a7edc45 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -3309,6 +3309,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_index); * fwnode_get_named_gpiod - obtain a GPIO from firmware node * @fwnode: handle of the firmware node * @propname: name of the firmware property representing the GPIO + * @dflags: GPIO initialization flags * * This function can be used for drivers that get their configuration * from firmware. @@ -3317,12 +3318,17 @@ EXPORT_SYMBOL_GPL(gpiod_get_index); * underlying firmware interface and then makes sure that the GPIO * descriptor is requested before it is returned to the caller. * + * On successfull request the GPIO pin is configured in accordance with + * provided @dflags. + * * In case of error an ERR_PTR() is returned. */ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, - const char *propname) + const char *propname, + enum gpiod_flags dflags) { struct gpio_desc *desc = ERR_PTR(-ENODEV); + unsigned long lflags = 0; bool active_low = false; bool single_ended = false; int ret; @@ -3355,13 +3361,19 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, return ERR_PTR(ret); if (active_low) - set_bit(FLAG_ACTIVE_LOW, &desc->flags); + lflags |= GPIO_ACTIVE_LOW; if (single_ended) { if (active_low) - set_bit(FLAG_OPEN_DRAIN, &desc->flags); + lflags |= GPIO_OPEN_DRAIN; else - set_bit(FLAG_OPEN_SOURCE, &desc->flags); + lflags |= GPIO_OPEN_SOURCE; + } + + ret = gpiod_configure_flags(desc, propname, lflags, dflags); + if (ret < 0) { + gpiod_put(desc); + return ERR_PTR(ret); } return desc; diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 582462d0af75..9de4b876100a 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -481,7 +481,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev, spin_lock_init(&bdata->lock); if (child) { - bdata->gpiod = devm_get_gpiod_from_child(dev, NULL, child); + bdata->gpiod = devm_get_gpiod_from_child(dev, NULL, child, GPIOD_IN); if (IS_ERR(bdata->gpiod)) { error = PTR_ERR(bdata->gpiod); if (error == -ENOENT) { @@ -496,13 +496,6 @@ static int gpio_keys_setup_key(struct platform_device *pdev, error); return error; } - } else { - error = gpiod_direction_input(bdata->gpiod); - if (error) { - dev_err(dev, "Failed to configure GPIO %d as input: %d\n", - desc_to_gpio(bdata->gpiod), error); - return error; - } } } else if (gpio_is_valid(button->gpio)) { /* diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index bed4f2086158..fd7ab4dad87b 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c @@ -304,7 +304,8 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) } bdata->gpiod = devm_get_gpiod_from_child(dev, NULL, - child); + child, + GPIOD_IN); if (IS_ERR(bdata->gpiod)) { error = PTR_ERR(bdata->gpiod); if (error != -EPROBE_DEFER) @@ -314,14 +315,6 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) fwnode_handle_put(child); return error; } - - error = gpiod_direction_input(bdata->gpiod); - if (error) { - dev_err(dev, "Failed to configure GPIO %d as input: %d\n", - desc_to_gpio(bdata->gpiod), error); - fwnode_handle_put(child); - return error; - } } else if (gpio_is_valid(button->gpio)) { /* * Legacy GPIO number so request the GPIO here and diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index d400dcaf4d29..00cc671cddcc 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -174,7 +174,7 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev) const char *state = NULL; struct device_node *np = to_of_node(child); - led.gpiod = devm_get_gpiod_from_child(dev, NULL, child); + led.gpiod = devm_get_gpiod_from_child(dev, NULL, child, GPIOD_ASIS); if (IS_ERR(led.gpiod)) { fwnode_handle_put(child); return ERR_CAST(led.gpiod); diff --git a/drivers/video/fbdev/amba-clcd-nomadik.c b/drivers/video/fbdev/amba-clcd-nomadik.c index 0c06fcaaa6e8..2e800d70b0e5 100644 --- a/drivers/video/fbdev/amba-clcd-nomadik.c +++ b/drivers/video/fbdev/amba-clcd-nomadik.c @@ -184,32 +184,27 @@ static void tpg110_init(struct device *dev, struct device_node *np, { dev_info(dev, "TPG110 display init\n"); - grestb = devm_get_gpiod_from_child(dev, "grestb", &np->fwnode); + /* This asserts the GRESTB signal, putting the display into reset */ + grestb = devm_get_gpiod_from_child(dev, "grestb", &np->fwnode, GPIOD_OUT_HIGH); if (IS_ERR(grestb)) { dev_err(dev, "no GRESTB GPIO\n"); return; } - /* This asserts the GRESTB signal, putting the display into reset */ - gpiod_direction_output(grestb, 1); - - scen = devm_get_gpiod_from_child(dev, "scen", &np->fwnode); + scen = devm_get_gpiod_from_child(dev, "scen", &np->fwnode, GPIOD_OUT_LOW); if (IS_ERR(scen)) { dev_err(dev, "no SCEN GPIO\n"); return; } - gpiod_direction_output(scen, 0); - scl = devm_get_gpiod_from_child(dev, "scl", &np->fwnode); + scl = devm_get_gpiod_from_child(dev, "scl", &np->fwnode, GPIOD_OUT_LOW); if (IS_ERR(scl)) { dev_err(dev, "no SCL GPIO\n"); return; } - gpiod_direction_output(scl, 0); - sda = devm_get_gpiod_from_child(dev, "sda", &np->fwnode); + sda = devm_get_gpiod_from_child(dev, "sda", &np->fwnode, GPIOD_OUT_LOW); if (IS_ERR(sda)) { dev_err(dev, "no SDA GPIO\n"); return; } - gpiod_direction_output(sda, 0); board->enable = tpg110_enable; board->disable = tpg110_disable; } diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index fb0fde686cb1..930d10049d8d 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -135,10 +135,12 @@ int desc_to_gpio(const struct gpio_desc *desc); struct fwnode_handle; struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, - const char *propname); + const char *propname, + enum gpiod_flags dflags); struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, const char *con_id, - struct fwnode_handle *child); + struct fwnode_handle *child, + enum gpiod_flags flags); #else /* CONFIG_GPIOLIB */ static inline int gpiod_count(struct device *dev, const char *con_id) @@ -411,14 +413,19 @@ static inline int desc_to_gpio(const struct gpio_desc *desc) /* Child properties interface */ struct fwnode_handle; -static inline struct gpio_desc *fwnode_get_named_gpiod( - struct fwnode_handle *fwnode, const char *propname) +static inline +struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, + const char *propname, + enum gpiod_flags dflags) { return ERR_PTR(-ENOSYS); } -static inline struct gpio_desc *devm_get_gpiod_from_child( - struct device *dev, const char *con_id, struct fwnode_handle *child) +static inline +struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, + const char *con_id, + struct fwnode_handle *child, + enum gpiod_flags flags) { return ERR_PTR(-ENOSYS); } -- cgit From b2987d7438e0ca949d81774ca8b43d370a1f9947 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Thu, 12 Jan 2017 17:39:24 +0100 Subject: gpio: Pass GPIO label down to gpiod_request Currently all users of fwnode_get_named_gpiod() have no way to specify a label for the GPIO. So GPIOs listed in debugfs are shown with label "?". With this change a proper label is used. Also adjust all users so they can pass a label, properly retrieved from device tree properties. Signed-off-by: Alexander Stein Cc: Andy Shevchenko Acked-by: Jacek Anaszewski Acked-by: Bartlomiej Zolnierkiewicz Acked-by: Dmitry Torokhov Signed-off-by: Linus Walleij --- drivers/gpio/devres.c | 5 +++-- drivers/gpio/gpiolib.c | 5 +++-- drivers/input/keyboard/gpio_keys.c | 3 ++- drivers/input/keyboard/gpio_keys_polled.c | 3 ++- drivers/leds/leds-gpio.c | 13 +++++++------ drivers/video/fbdev/amba-clcd-nomadik.c | 12 ++++++++---- include/linux/gpio/consumer.h | 12 ++++++++---- 7 files changed, 33 insertions(+), 20 deletions(-) (limited to 'drivers/gpio/devres.c') diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index 5e0b41b5e554..89969e887e5d 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c @@ -138,7 +138,8 @@ EXPORT_SYMBOL(devm_gpiod_get_index); struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, const char *con_id, struct fwnode_handle *child, - enum gpiod_flags flags) + enum gpiod_flags flags, + const char *label) { static const char * const suffixes[] = { "gpios", "gpio" }; char prop_name[32]; /* 32 is max size of property name */ @@ -159,7 +160,7 @@ struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, snprintf(prop_name, sizeof(prop_name), "%s", suffixes[i]); - desc = fwnode_get_named_gpiod(child, prop_name, flags); + desc = fwnode_get_named_gpiod(child, prop_name, flags, label); if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT)) break; } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index bb3d3a7edc45..20c6c51cbe10 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -3325,7 +3325,8 @@ EXPORT_SYMBOL_GPL(gpiod_get_index); */ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, const char *propname, - enum gpiod_flags dflags) + enum gpiod_flags dflags, + const char *label) { struct gpio_desc *desc = ERR_PTR(-ENODEV); unsigned long lflags = 0; @@ -3356,7 +3357,7 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, if (IS_ERR(desc)) return desc; - ret = gpiod_request(desc, NULL); + ret = gpiod_request(desc, label); if (ret) return ERR_PTR(ret); diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 9de4b876100a..2ec74d90ef78 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -481,7 +481,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev, spin_lock_init(&bdata->lock); if (child) { - bdata->gpiod = devm_get_gpiod_from_child(dev, NULL, child, GPIOD_IN); + bdata->gpiod = devm_get_gpiod_from_child(dev, NULL, child, + GPIOD_IN, desc); if (IS_ERR(bdata->gpiod)) { error = PTR_ERR(bdata->gpiod); if (error == -ENOENT) { diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index fd7ab4dad87b..5e35c565e341 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c @@ -305,7 +305,8 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) bdata->gpiod = devm_get_gpiod_from_child(dev, NULL, child, - GPIOD_IN); + GPIOD_IN, + button->desc); if (IS_ERR(bdata->gpiod)) { error = PTR_ERR(bdata->gpiod); if (error != -EPROBE_DEFER) diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 00cc671cddcc..6c4825d96693 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -174,12 +174,6 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev) const char *state = NULL; struct device_node *np = to_of_node(child); - led.gpiod = devm_get_gpiod_from_child(dev, NULL, child, GPIOD_ASIS); - if (IS_ERR(led.gpiod)) { - fwnode_handle_put(child); - return ERR_CAST(led.gpiod); - } - ret = fwnode_property_read_string(child, "label", &led.name); if (ret && IS_ENABLED(CONFIG_OF) && np) led.name = np->name; @@ -188,6 +182,13 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev) return ERR_PTR(-EINVAL); } + led.gpiod = devm_get_gpiod_from_child(dev, NULL, child, + GPIOD_ASIS, led.name); + if (IS_ERR(led.gpiod)) { + fwnode_handle_put(child); + return ERR_CAST(led.gpiod); + } + fwnode_property_read_string(child, "linux,default-trigger", &led.default_trigger); diff --git a/drivers/video/fbdev/amba-clcd-nomadik.c b/drivers/video/fbdev/amba-clcd-nomadik.c index 2e800d70b0e5..9175ad9034e1 100644 --- a/drivers/video/fbdev/amba-clcd-nomadik.c +++ b/drivers/video/fbdev/amba-clcd-nomadik.c @@ -185,22 +185,26 @@ static void tpg110_init(struct device *dev, struct device_node *np, dev_info(dev, "TPG110 display init\n"); /* This asserts the GRESTB signal, putting the display into reset */ - grestb = devm_get_gpiod_from_child(dev, "grestb", &np->fwnode, GPIOD_OUT_HIGH); + grestb = devm_get_gpiod_from_child(dev, "grestb", &np->fwnode, + GPIOD_OUT_HIGH, "grestb"); if (IS_ERR(grestb)) { dev_err(dev, "no GRESTB GPIO\n"); return; } - scen = devm_get_gpiod_from_child(dev, "scen", &np->fwnode, GPIOD_OUT_LOW); + scen = devm_get_gpiod_from_child(dev, "scen", &np->fwnode, + GPIOD_OUT_LOW, "scen"); if (IS_ERR(scen)) { dev_err(dev, "no SCEN GPIO\n"); return; } - scl = devm_get_gpiod_from_child(dev, "scl", &np->fwnode, GPIOD_OUT_LOW); + scl = devm_get_gpiod_from_child(dev, "scl", &np->fwnode, GPIOD_OUT_LOW, + "scl"); if (IS_ERR(scl)) { dev_err(dev, "no SCL GPIO\n"); return; } - sda = devm_get_gpiod_from_child(dev, "sda", &np->fwnode, GPIOD_OUT_LOW); + sda = devm_get_gpiod_from_child(dev, "sda", &np->fwnode, GPIOD_OUT_LOW, + "sda"); if (IS_ERR(sda)) { dev_err(dev, "no SDA GPIO\n"); return; diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index 930d10049d8d..80bad7ebde04 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -136,11 +136,13 @@ struct fwnode_handle; struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, const char *propname, - enum gpiod_flags dflags); + enum gpiod_flags dflags, + const char *label); struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, const char *con_id, struct fwnode_handle *child, - enum gpiod_flags flags); + enum gpiod_flags flags, + const char *label); #else /* CONFIG_GPIOLIB */ static inline int gpiod_count(struct device *dev, const char *con_id) @@ -416,7 +418,8 @@ struct fwnode_handle; static inline struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, const char *propname, - enum gpiod_flags dflags) + enum gpiod_flags dflags, + const char *label) { return ERR_PTR(-ENOSYS); } @@ -425,7 +428,8 @@ static inline struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, const char *con_id, struct fwnode_handle *child, - enum gpiod_flags flags) + enum gpiod_flags flags, + const char *label) { return ERR_PTR(-ENOSYS); } -- cgit From 4b0947974e593d52aace18ca5c7e2746fdebae60 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 2 Feb 2017 14:53:10 +0100 Subject: gpio: Rename devm_get_gpiod_from_child() Rename devm_get_gpiod_from_child() into devm_fwnode_get_gpiod_from_child() to reflect the fact that this function is operating on a fwnode object. Signed-off-by: Boris Brezillon Acked-by: Jacek Anaszewski Acked-by: Dmitry Torokhov Signed-off-by: Linus Walleij --- drivers/gpio/devres.c | 15 ++++++++------- drivers/input/keyboard/gpio_keys.c | 6 ++++-- drivers/input/keyboard/gpio_keys_polled.c | 8 ++++---- drivers/leds/leds-gpio.c | 5 +++-- drivers/video/fbdev/amba-clcd-nomadik.c | 16 ++++++++-------- include/linux/gpio/consumer.h | 20 ++++++++++---------- 6 files changed, 37 insertions(+), 33 deletions(-) (limited to 'drivers/gpio/devres.c') diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index 89969e887e5d..cd1bd1c3d2c0 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c @@ -123,7 +123,8 @@ struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev, EXPORT_SYMBOL(devm_gpiod_get_index); /** - * devm_get_gpiod_from_child - get a GPIO descriptor from a device's child node + * devm_fwnode_get_gpiod_from_child - get a GPIO descriptor from a device's + * child node * @dev: GPIO consumer * @con_id: function within the GPIO consumer * @child: firmware node (child of @dev) @@ -135,11 +136,11 @@ EXPORT_SYMBOL(devm_gpiod_get_index); * On successfull request the GPIO pin is configured in accordance with * provided @flags. */ -struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, - const char *con_id, - struct fwnode_handle *child, - enum gpiod_flags flags, - const char *label) +struct gpio_desc *devm_fwnode_get_gpiod_from_child(struct device *dev, + const char *con_id, + struct fwnode_handle *child, + enum gpiod_flags flags, + const char *label) { static const char * const suffixes[] = { "gpios", "gpio" }; char prop_name[32]; /* 32 is max size of property name */ @@ -174,7 +175,7 @@ struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, return desc; } -EXPORT_SYMBOL(devm_get_gpiod_from_child); +EXPORT_SYMBOL(devm_fwnode_get_gpiod_from_child); /** * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional() diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 2ec74d90ef78..13372782dffe 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -481,8 +481,10 @@ static int gpio_keys_setup_key(struct platform_device *pdev, spin_lock_init(&bdata->lock); if (child) { - bdata->gpiod = devm_get_gpiod_from_child(dev, NULL, child, - GPIOD_IN, desc); + bdata->gpiod = devm_fwnode_get_gpiod_from_child(dev, NULL, + child, + GPIOD_IN, + desc); if (IS_ERR(bdata->gpiod)) { error = PTR_ERR(bdata->gpiod); if (error == -ENOENT) { diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index 5e35c565e341..b3c8d5e7985c 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c @@ -303,10 +303,10 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) return -EINVAL; } - bdata->gpiod = devm_get_gpiod_from_child(dev, NULL, - child, - GPIOD_IN, - button->desc); + bdata->gpiod = devm_fwnode_get_gpiod_from_child(dev, + NULL, child, + GPIOD_IN, + button->desc); if (IS_ERR(bdata->gpiod)) { error = PTR_ERR(bdata->gpiod); if (error != -EPROBE_DEFER) diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 6c4825d96693..066fc7590729 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -182,8 +182,9 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev) return ERR_PTR(-EINVAL); } - led.gpiod = devm_get_gpiod_from_child(dev, NULL, child, - GPIOD_ASIS, led.name); + led.gpiod = devm_fwnode_get_gpiod_from_child(dev, NULL, child, + GPIOD_ASIS, + led.name); if (IS_ERR(led.gpiod)) { fwnode_handle_put(child); return ERR_CAST(led.gpiod); diff --git a/drivers/video/fbdev/amba-clcd-nomadik.c b/drivers/video/fbdev/amba-clcd-nomadik.c index 9175ad9034e1..476ff3f4d466 100644 --- a/drivers/video/fbdev/amba-clcd-nomadik.c +++ b/drivers/video/fbdev/amba-clcd-nomadik.c @@ -185,26 +185,26 @@ static void tpg110_init(struct device *dev, struct device_node *np, dev_info(dev, "TPG110 display init\n"); /* This asserts the GRESTB signal, putting the display into reset */ - grestb = devm_get_gpiod_from_child(dev, "grestb", &np->fwnode, - GPIOD_OUT_HIGH, "grestb"); + grestb = devm_fwnode_get_gpiod_from_child(dev, "grestb", &np->fwnode, + GPIOD_OUT_HIGH, "grestb"); if (IS_ERR(grestb)) { dev_err(dev, "no GRESTB GPIO\n"); return; } - scen = devm_get_gpiod_from_child(dev, "scen", &np->fwnode, - GPIOD_OUT_LOW, "scen"); + scen = devm_fwnode_get_gpiod_from_child(dev, "scen", &np->fwnode, + GPIOD_OUT_LOW, "scen"); if (IS_ERR(scen)) { dev_err(dev, "no SCEN GPIO\n"); return; } - scl = devm_get_gpiod_from_child(dev, "scl", &np->fwnode, GPIOD_OUT_LOW, - "scl"); + scl = devm_fwnode_get_gpiod_from_child(dev, "scl", &np->fwnode, + GPIOD_OUT_LOW, "scl"); if (IS_ERR(scl)) { dev_err(dev, "no SCL GPIO\n"); return; } - sda = devm_get_gpiod_from_child(dev, "sda", &np->fwnode, GPIOD_OUT_LOW, - "sda"); + sda = devm_fwnode_get_gpiod_from_child(dev, "sda", &np->fwnode, + GPIOD_OUT_LOW, "sda"); if (IS_ERR(sda)) { dev_err(dev, "no SDA GPIO\n"); return; diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index 80bad7ebde04..f32f49e96c0b 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -138,11 +138,11 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, const char *propname, enum gpiod_flags dflags, const char *label); -struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, - const char *con_id, - struct fwnode_handle *child, - enum gpiod_flags flags, - const char *label); +struct gpio_desc *devm_fwnode_get_gpiod_from_child(struct device *dev, + const char *con_id, + struct fwnode_handle *child, + enum gpiod_flags flags, + const char *label); #else /* CONFIG_GPIOLIB */ static inline int gpiod_count(struct device *dev, const char *con_id) @@ -425,11 +425,11 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, } static inline -struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, - const char *con_id, - struct fwnode_handle *child, - enum gpiod_flags flags, - const char *label) +struct gpio_desc *devm_fwnode_get_gpiod_from_child(struct device *dev, + const char *con_id, + struct fwnode_handle *child, + enum gpiod_flags flags, + const char *label) { return ERR_PTR(-ENOSYS); } -- cgit From 537b94dafce29af6a3e923d216472cfc2f3659af Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 2 Feb 2017 14:53:11 +0100 Subject: 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 Signed-off-by: Linus Walleij --- drivers/gpio/devres.c | 20 +++++++++++--------- drivers/gpio/gpiolib.c | 9 +++++---- include/linux/gpio/consumer.h | 31 +++++++++++++++++++++---------- 3 files changed, 37 insertions(+), 23 deletions(-) (limited to 'drivers/gpio/devres.c') 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, EXPORT_SYMBOL(devm_gpiod_get_index); /** - * devm_fwnode_get_gpiod_from_child - get a GPIO descriptor from a device's - * child node + * devm_fwnode_get_index_gpiod_from_child - get a GPIO descriptor from a + * device's child node * @dev: GPIO consumer * @con_id: function within the GPIO consumer + * @index: index of the GPIO to obtain in the consumer * @child: firmware node (child of @dev) * @flags: GPIO initialization flags * @@ -136,11 +137,11 @@ EXPORT_SYMBOL(devm_gpiod_get_index); * On successfull request the GPIO pin is configured in accordance with * provided @flags. */ -struct gpio_desc *devm_fwnode_get_gpiod_from_child(struct device *dev, - const char *con_id, - struct fwnode_handle *child, - enum gpiod_flags flags, - const char *label) +struct gpio_desc *devm_fwnode_get_index_gpiod_from_child(struct device *dev, + const char *con_id, int index, + struct fwnode_handle *child, + enum gpiod_flags flags, + const char *label) { static const char * const suffixes[] = { "gpios", "gpio" }; 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, snprintf(prop_name, sizeof(prop_name), "%s", suffixes[i]); - desc = fwnode_get_named_gpiod(child, prop_name, flags, label); + desc = fwnode_get_named_gpiod(child, prop_name, index, flags, + label); if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT)) break; } @@ -175,7 +177,7 @@ struct gpio_desc *devm_fwnode_get_gpiod_from_child(struct device *dev, return desc; } -EXPORT_SYMBOL(devm_fwnode_get_gpiod_from_child); +EXPORT_SYMBOL(devm_fwnode_get_index_gpiod_from_child); /** * 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); * fwnode_get_named_gpiod - obtain a GPIO from firmware node * @fwnode: handle of the firmware node * @propname: name of the firmware property representing the GPIO + * @index: index of the GPIO to obtain in the consumer * @dflags: GPIO initialization flags * * This function can be used for drivers that get their configuration @@ -3324,7 +3325,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_index); * In case of error an ERR_PTR() is returned. */ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, - const char *propname, + const char *propname, int index, enum gpiod_flags dflags, const char *label) { @@ -3340,8 +3341,8 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, if (is_of_node(fwnode)) { enum of_gpio_flags flags; - desc = of_get_named_gpiod_flags(to_of_node(fwnode), propname, 0, - &flags); + desc = of_get_named_gpiod_flags(to_of_node(fwnode), propname, + index, &flags); if (!IS_ERR(desc)) { active_low = flags & OF_GPIO_ACTIVE_LOW; single_ended = flags & OF_GPIO_SINGLE_ENDED; @@ -3349,7 +3350,7 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, } else if (is_acpi_node(fwnode)) { struct acpi_gpio_info info; - desc = acpi_node_get_gpiod(fwnode, propname, 0, &info); + desc = acpi_node_get_gpiod(fwnode, propname, index, &info); if (!IS_ERR(desc)) active_low = info.polarity == GPIO_ACTIVE_LOW; } 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); struct fwnode_handle; struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, - const char *propname, + const char *propname, int index, enum gpiod_flags dflags, const char *label); -struct gpio_desc *devm_fwnode_get_gpiod_from_child(struct device *dev, - const char *con_id, - struct fwnode_handle *child, - enum gpiod_flags flags, - const char *label); +struct gpio_desc *devm_fwnode_get_index_gpiod_from_child(struct device *dev, + const char *con_id, int index, + struct fwnode_handle *child, + enum gpiod_flags flags, + const char *label); #else /* CONFIG_GPIOLIB */ static inline int gpiod_count(struct device *dev, const char *con_id) @@ -417,13 +417,25 @@ struct fwnode_handle; static inline struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, - const char *propname, + const char *propname, int index, enum gpiod_flags dflags, const char *label) { return ERR_PTR(-ENOSYS); } +static inline +struct gpio_desc *devm_fwnode_get_index_gpiod_from_child(struct device *dev, + const char *con_id, int index, + struct fwnode_handle *child, + enum gpiod_flags flags, + const char *label) +{ + return ERR_PTR(-ENOSYS); +} + +#endif /* CONFIG_GPIOLIB */ + static inline struct gpio_desc *devm_fwnode_get_gpiod_from_child(struct device *dev, const char *con_id, @@ -431,11 +443,10 @@ struct gpio_desc *devm_fwnode_get_gpiod_from_child(struct device *dev, enum gpiod_flags flags, const char *label) { - return ERR_PTR(-ENOSYS); + return devm_fwnode_get_index_gpiod_from_child(dev, con_id, 0, child, + flags, label); } -#endif /* CONFIG_GPIOLIB */ - #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS) int gpiod_export(struct gpio_desc *desc, bool direction_may_change); -- cgit