summaryrefslogtreecommitdiffstats
path: root/drivers/of/of_gpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/of/of_gpio.c')
-rw-r--r--drivers/of/of_gpio.c72
1 files changed, 54 insertions, 18 deletions
diff --git a/drivers/of/of_gpio.c b/drivers/of/of_gpio.c
index 42e0347529..25496a3cf1 100644
--- a/drivers/of/of_gpio.c
+++ b/drivers/of/of_gpio.c
@@ -30,8 +30,8 @@ static void of_gpio_flags_quirks(struct device_node *np,
* be actively ignored.
*/
if ((*flags & OF_GPIO_ACTIVE_LOW) && !active_low) {
- pr_warn("%s GPIO handle specifies active low - ignored\n",
- np->full_name);
+ pr_warn("%pOF GPIO handle specifies active low - ignored\n",
+ np);
*flags &= ~OF_GPIO_ACTIVE_LOW;
}
if (active_low)
@@ -46,6 +46,44 @@ static void of_gpio_flags_quirks(struct device_node *np,
}
+static struct gpio_chip *of_find_gpiochip_by_xlate(
+ struct of_phandle_args *gpiospec)
+{
+ struct gpio_chip *chip;
+ struct device *dev;
+
+ dev = of_find_device_by_node(gpiospec->np);
+ if (!dev) {
+ pr_debug("%s: unable to find device of node %pOF\n",
+ __func__, gpiospec->np);
+ return NULL;
+ }
+
+ chip = gpio_get_chip_by_dev(dev);
+ if (!chip) {
+ pr_debug("%s: unable to find gpiochip\n", __func__);
+ return NULL;
+ }
+
+ if (!chip->ops->of_xlate ||
+ chip->ops->of_xlate(chip, gpiospec, NULL) < 0) {
+ pr_err("%s: failed to execute of_xlate\n", __func__);
+ return NULL;
+ }
+
+ return chip;
+}
+
+static int of_xlate_and_get_gpiod_flags(struct gpio_chip *chip,
+ struct of_phandle_args *gpiospec,
+ enum of_gpio_flags *flags)
+{
+ if (chip->of_gpio_n_cells != gpiospec->args_count)
+ return -EINVAL;
+
+ return chip->ops->of_xlate(chip, gpiospec, flags);
+}
+
/**
* of_get_named_gpio_flags() - Get a GPIO number and flags to use with GPIO API
* @np: device node to get GPIO from
@@ -60,38 +98,36 @@ static void of_gpio_flags_quirks(struct device_node *np,
int of_get_named_gpio_flags(struct device_node *np, const char *propname,
int index, enum of_gpio_flags *flags)
{
- struct of_phandle_args out_args;
- struct device_d *dev;
+ struct of_phandle_args gpiospec;
+ struct gpio_chip *chip;
int ret;
ret = of_parse_phandle_with_args(np, propname, "#gpio-cells",
- index, &out_args);
+ index, &gpiospec);
if (ret) {
pr_debug("%s: cannot parse %s property: %d\n",
__func__, propname, ret);
return ret;
}
- dev = of_find_device_by_node(out_args.np);
- if (!dev) {
- pr_debug("%s: unable to find device of node %s\n",
- __func__, out_args.np->full_name);
- return -EPROBE_DEFER;
+ chip = of_find_gpiochip_by_xlate(&gpiospec);
+ if (!chip) {
+ ret = -EPROBE_DEFER;
+ goto out;
}
- ret = gpio_get_num(dev, out_args.args[0]);
- if (ret == -EPROBE_DEFER)
- return ret;
+ ret = of_xlate_and_get_gpiod_flags(chip, &gpiospec, flags);
if (ret < 0) {
pr_err("%s: unable to get gpio num of device %s: %d\n",
- __func__, dev_name(dev), ret);
- return ret;
+ __func__, dev_name(chip->dev), ret);
+ goto out;
}
- if (flags) {
- *flags = out_args.args[1];
+ if (flags)
of_gpio_flags_quirks(np, propname, flags, index);
- }
+
+out:
+ of_node_put(gpiospec.np);
return ret;
}