Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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)
+1 −1
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -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 */