From: Roland Stigge <stigge@antcom.de>
To: Grant Likely <grant.likely@secretlab.ca>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/3] gpio: Adjust of_xlate API to support multiple GPIO chips
Date: Fri, 18 May 2012 10:05:23 +0200 [thread overview]
Message-ID: <4FB602C3.4060208@antcom.de> (raw)
In-Reply-To: <1337285060-31919-1-git-send-email-grant.likely@secretlab.ca>
On 05/17/2012 10:04 PM, Grant Likely wrote:
> This patch changes the of_xlate API to make it possible for multiple
> gpio_chips to refer to the same device tree node. This is useful for
> banked GPIO controllers that use multiple gpio_chips for a single
> device. With this change the core code will try calling of_xlate on
> each gpio_chip that references the device_node and will return the
> gpio number for the first one to return 'true'.
>
> Cc: Roland Stigge <stigge@antcom.de>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Tested-by: Roland Stigge <stigge@antcom.de>
> ---
> arch/arm/mach-imx/mach-mx35_3ds.c | 3 +-
> drivers/gpio/gpiolib-of.c | 80 ++++++++++++++++++-------------------
> drivers/gpio/gpiolib.c | 2 +-
> include/asm-generic/gpio.h | 2 +-
> include/linux/of_gpio.h | 1 -
> 5 files changed, 41 insertions(+), 47 deletions(-)
>
> diff --git a/arch/arm/mach-imx/mach-mx35_3ds.c b/arch/arm/mach-imx/mach-mx35_3ds.c
> index 6ae51c6..6a7cf91 100644
> --- a/arch/arm/mach-imx/mach-mx35_3ds.c
> +++ b/arch/arm/mach-imx/mach-mx35_3ds.c
> @@ -96,8 +96,7 @@ static struct i2c_board_info __initdata i2c_devices_3ds[] = {
>
> static int lcd_power_gpio = -ENXIO;
>
> -static int mc9s08dz60_gpiochip_match(struct gpio_chip *chip,
> - const void *data)
> +static int mc9s08dz60_gpiochip_match(struct gpio_chip *chip, void *data)
> {
> return !strcmp(chip->label, data);
> }
> diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
> index bf984b6..d18068a 100644
> --- a/drivers/gpio/gpiolib-of.c
> +++ b/drivers/gpio/gpiolib-of.c
> @@ -15,11 +15,39 @@
> #include <linux/errno.h>
> #include <linux/module.h>
> #include <linux/io.h>
> +#include <linux/gpio.h>
> #include <linux/of.h>
> #include <linux/of_address.h>
> #include <linux/of_gpio.h>
> #include <linux/slab.h>
>
> +/* Private data structure for of_gpiochip_is_match */
> +struct gg_data {
> + enum of_gpio_flags *flags;
> + struct of_phandle_args gpiospec;
> +
> + int out_gpio;
> +};
> +
> +/* Private function for resolving node pointer to gpio_chip */
> +static int of_gpiochip_find_and_xlate(struct gpio_chip *gc, void *data)
> +{
> + struct gg_data *gg_data = data;
> + int ret;
> +
> + if ((gc->of_node != gg_data->gpiospec.np) ||
> + (gc->of_gpio_n_cells != gg_data->gpiospec.args_count) ||
> + (!gc->of_xlate))
> + return false;
> +
> + ret = gc->of_xlate(gc, &gg_data->gpiospec, gg_data->flags);
> + if (ret < 0)
> + return false;
> +
> + gg_data->out_gpio = ret + gc->base;
> + return true;
> +}
> +
> /**
> * of_get_named_gpio_flags() - Get a GPIO number and flags to use with GPIO API
> * @np: device node to get GPIO from
> @@ -34,46 +62,25 @@
> int of_get_named_gpio_flags(struct device_node *np, const char *propname,
> int index, enum of_gpio_flags *flags)
> {
> + struct gg_data gg_data = { .flags = flags, .out_gpio = -ENODEV };
> int ret;
> - struct gpio_chip *gc;
> - struct of_phandle_args gpiospec;
> +
> + /* .of_xlate might decide to not fill in the flags, so clear it. */
> + if (flags)
> + *flags = 0;
>
> ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", index,
> - &gpiospec);
> + &gg_data.gpiospec);
> if (ret) {
> pr_debug("%s: can't parse gpios property\n", __func__);
> - goto err0;
> - }
> -
> - gc = of_node_to_gpiochip(gpiospec.np);
> - if (!gc) {
> - pr_debug("%s: gpio controller %s isn't registered\n",
> - np->full_name, gpiospec.np->full_name);
> - ret = -ENODEV;
> - goto err1;
> - }
> -
> - if (gpiospec.args_count != gc->of_gpio_n_cells) {
> - pr_debug("%s: wrong #gpio-cells for %s\n",
> - np->full_name, gpiospec.np->full_name);
> - ret = -EINVAL;
> - goto err1;
> + return -EINVAL;
> }
>
> - /* .xlate might decide to not fill in the flags, so clear it. */
> - if (flags)
> - *flags = 0;
> -
> - ret = gc->of_xlate(gc, &gpiospec, flags);
> - if (ret < 0)
> - goto err1;
> + gpiochip_find(&gg_data, of_gpiochip_find_and_xlate);
>
> - ret += gc->base;
> -err1:
> - of_node_put(gpiospec.np);
> -err0:
> + of_node_put(gg_data.gpiospec.np);
> pr_debug("%s exited with status %d\n", __func__, ret);
> - return ret;
> + return gg_data.out_gpio;
> }
> EXPORT_SYMBOL(of_get_named_gpio_flags);
>
> @@ -227,14 +234,3 @@ void of_gpiochip_remove(struct gpio_chip *chip)
> if (chip->of_node)
> of_node_put(chip->of_node);
> }
> -
> -/* Private function for resolving node pointer to gpio_chip */
> -static int of_gpiochip_is_match(struct gpio_chip *chip, const void *data)
> -{
> - return chip->of_node == data;
> -}
> -
> -struct gpio_chip *of_node_to_gpiochip(struct device_node *np)
> -{
> - return gpiochip_find(np, of_gpiochip_is_match);
> -}
> diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
> index 566d012..38353c0 100644
> --- a/drivers/gpio/gpiolib.c
> +++ b/drivers/gpio/gpiolib.c
> @@ -1156,7 +1156,7 @@ EXPORT_SYMBOL_GPL(gpiochip_remove);
> */
> struct gpio_chip *gpiochip_find(const void *data,
> int (*match)(struct gpio_chip *chip,
> - const void *data))
> + void *data))
> {
> struct gpio_chip *chip = NULL;
> unsigned long flags;
> diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
> index 5f52690..1cb3dd1 100644
> --- a/include/asm-generic/gpio.h
> +++ b/include/asm-generic/gpio.h
> @@ -144,7 +144,7 @@ extern int gpiochip_add(struct gpio_chip *chip);
> extern int __must_check gpiochip_remove(struct gpio_chip *chip);
> extern struct gpio_chip *gpiochip_find(const void *data,
> int (*match)(struct gpio_chip *chip,
> - const void *data));
> + void *data));
>
>
> /* Always use the library code for GPIO management calls,
> diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h
> index 81733d1..c454f57 100644
> --- a/include/linux/of_gpio.h
> +++ b/include/linux/of_gpio.h
> @@ -58,7 +58,6 @@ extern int of_mm_gpiochip_add(struct device_node *np,
>
> extern void of_gpiochip_add(struct gpio_chip *gc);
> extern void of_gpiochip_remove(struct gpio_chip *gc);
> -extern struct gpio_chip *of_node_to_gpiochip(struct device_node *np);
> extern int of_gpio_simple_xlate(struct gpio_chip *gc,
> const struct of_phandle_args *gpiospec,
> u32 *flags);
next prev parent reply other threads:[~2012-05-18 8:05 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-05-17 20:04 [PATCH 1/3] gpio: Adjust of_xlate API to support multiple GPIO chips Grant Likely
2012-05-17 20:04 ` [PATCH 2/3] gpio/lpc32xx: Add device tree support Grant Likely
2012-05-17 20:10 ` Grant Likely
2012-05-17 20:04 ` [PATCH 3/3] gpio/lpc32xx: Fixup of_xlate for core changes Grant Likely
2012-05-18 8:08 ` Roland Stigge
2012-05-17 20:10 ` [PATCH 1/3] gpio: Adjust of_xlate API to support multiple GPIO chips Grant Likely
2012-05-18 8:05 ` Roland Stigge [this message]
2012-05-18 8:06 ` Roland Stigge
2012-05-18 8:17 ` [PATCH 2/2] gpio: Device tree support for LPC32xx Roland Stigge
2012-05-18 8:18 ` Roland Stigge
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4FB602C3.4060208@antcom.de \
--to=stigge@antcom.de \
--cc=grant.likely@secretlab.ca \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.