Commit 1feb57a2 authored by Olliver Schinagl's avatar Olliver Schinagl Committed by Linus Walleij

gpio: add parameter to allow the use named gpios

The gpio binding document says that new code should always use named
gpios. Patch 40b73183 added support to parse a list of gpios from child
nodes, but does not make it possible to use named gpios. This patch adds
the con_id property and implements it is done in gpiolib.c, where the
old-style of using unnamed gpios still works.
Signed-off-by: default avatarOlliver Schinagl <oliver@schinagl.nl>
Acked-by: default avatarBryan Wu <cooloney@gmail.com>
Acked-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
Reviewed-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent b80eef95
......@@ -111,23 +111,39 @@ EXPORT_SYMBOL(__devm_gpiod_get_index);
/**
* devm_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)
*
* GPIO descriptors returned from this function are automatically disposed on
* driver detach.
*/
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;
unsigned int i;
dr = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc *),
GFP_KERNEL);
if (!dr)
return ERR_PTR(-ENOMEM);
desc = fwnode_get_named_gpiod(child, "gpios");
for (i = 0; i < ARRAY_SIZE(suffixes); i++) {
if (con_id)
snprintf(prop_name, sizeof(prop_name), "%s-%s",
con_id, suffixes[i]);
else
snprintf(prop_name, sizeof(prop_name), "%s",
suffixes[i]);
desc = fwnode_get_named_gpiod(child, prop_name);
if (!IS_ERR(desc) || (PTR_ERR(desc) == -EPROBE_DEFER))
break;
}
if (IS_ERR(desc)) {
devres_free(dr);
return desc;
......
......@@ -125,7 +125,7 @@ static struct gpio_keys_platform_data *gpio_keys_polled_get_devtree_pdata(struct
device_for_each_child_node(dev, child) {
struct gpio_desc *desc;
desc = devm_get_gpiod_from_child(dev, child);
desc = devm_get_gpiod_from_child(dev, NULL, child);
if (IS_ERR(desc)) {
error = PTR_ERR(desc);
if (error != -EPROBE_DEFER)
......
......@@ -184,7 +184,7 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
struct gpio_led led = {};
const char *state = NULL;
led.gpiod = devm_get_gpiod_from_child(dev, child);
led.gpiod = devm_get_gpiod_from_child(dev, NULL, child);
if (IS_ERR(led.gpiod)) {
fwnode_handle_put(child);
ret = PTR_ERR(led.gpiod);
......
......@@ -110,6 +110,7 @@ struct fwnode_handle;
struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
const char *propname);
struct gpio_desc *devm_get_gpiod_from_child(struct device *dev,
const char *con_id,
struct fwnode_handle *child);
#else /* CONFIG_GPIOLIB */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment