diff options
Diffstat (limited to 'drivers/pinctrl/devicetree.c')
-rw-r--r-- | drivers/pinctrl/devicetree.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c index 54dad89fc9bf..1f890267cb72 100644 --- a/drivers/pinctrl/devicetree.c +++ b/drivers/pinctrl/devicetree.c @@ -18,6 +18,7 @@ #include <linux/device.h> #include <linux/of.h> +#include <linux/of_gpio.h> #include <linux/pinctrl/pinctrl.h> #include <linux/slab.h> @@ -166,6 +167,43 @@ static int dt_remember_dummy_state(struct pinctrl *p, const char *statename) return dt_remember_or_free_map(p, statename, NULL, map, 1); } +static int dt_gpio_assert_pinctrl(struct pinctrl *p) +{ + struct device_node *np = p->dev->of_node; + enum of_gpio_flags flags; + int gpio; + int index = 0; + int ret; + + if (!of_find_property(np, "pinctrl-assert-gpios", NULL)) + return 0; /* Missing the property, so nothing to be done */ + + for (;; index++) { + gpio = of_get_named_gpio_flags(np, "pinctrl-assert-gpios", + index, &flags); + if (gpio < 0) + break; /* End of the phandle list */ + + if (!gpio_is_valid(gpio)) + return -EINVAL; + + ret = devm_gpio_request_one(p->dev, gpio, GPIOF_OUT_INIT_LOW, + NULL); + if (ret < 0) + return ret; + + if (flags & OF_GPIO_ACTIVE_LOW) + continue; + + if (gpio_cansleep(gpio)) + gpio_set_value_cansleep(gpio, 1); + else + gpio_set_value(gpio, 1); + } + + return 0; +} + int pinctrl_dt_to_map(struct pinctrl *p) { struct device_node *np = p->dev->of_node; @@ -186,6 +224,12 @@ int pinctrl_dt_to_map(struct pinctrl *p) return 0; } + ret = dt_gpio_assert_pinctrl(p); + if (ret) { + dev_dbg(p->dev, "failed to assert pinctrl setting: %d\n", ret); + return ret; + } + /* We may store pointers to property names within the node */ of_node_get(np); |