diff options
Diffstat (limited to 'drivers/base/pinctrl.c')
| -rw-r--r-- | drivers/base/pinctrl.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/drivers/base/pinctrl.c b/drivers/base/pinctrl.c index 5fb74b43848e..c22864458511 100644 --- a/drivers/base/pinctrl.c +++ b/drivers/base/pinctrl.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Driver core interface to the pinctrl subsystem. * @@ -6,8 +7,6 @@ * Based on bits of regulator core, gpio core and clk core * * Author: Linus Walleij <linus.walleij@linaro.org> - * - * License terms: GNU General Public License (GPL) version 2 */ #include <linux/device.h> @@ -23,6 +22,9 @@ int pinctrl_bind_pins(struct device *dev) { int ret; + if (dev->of_node_reused) + return 0; + dev->pins = devm_kzalloc(dev, sizeof(*(dev->pins)), GFP_KERNEL); if (!dev->pins) return -ENOMEM; @@ -42,9 +44,20 @@ int pinctrl_bind_pins(struct device *dev) goto cleanup_get; } - ret = pinctrl_select_state(dev->pins->p, dev->pins->default_state); + dev->pins->init_state = pinctrl_lookup_state(dev->pins->p, + PINCTRL_STATE_INIT); + if (IS_ERR(dev->pins->init_state)) { + /* Not supplying this state is perfectly legal */ + dev_dbg(dev, "no init pinctrl state\n"); + + ret = pinctrl_select_state(dev->pins->p, + dev->pins->default_state); + } else { + ret = pinctrl_select_state(dev->pins->p, dev->pins->init_state); + } + if (ret) { - dev_dbg(dev, "failed to activate default pinctrl state\n"); + dev_dbg(dev, "failed to activate initial pinctrl state\n"); goto cleanup_get; } @@ -80,9 +93,13 @@ cleanup_alloc: devm_kfree(dev, dev->pins); dev->pins = NULL; - /* Only return deferrals */ - if (ret != -EPROBE_DEFER) - ret = 0; + /* Return deferrals */ + if (ret == -EPROBE_DEFER) + return ret; + /* Return serious errors */ + if (ret == -EINVAL) + return ret; + /* We ignore errors like -ENOENT meaning no pinctrl state */ - return ret; + return 0; } |
