aboutsummaryrefslogtreecommitdiff
path: root/drivers/pinctrl/devicetree.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/devicetree.c')
-rw-r--r--drivers/pinctrl/devicetree.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c
index b601039d6c69..2969ff3162c3 100644
--- a/drivers/pinctrl/devicetree.c
+++ b/drivers/pinctrl/devicetree.c
@@ -101,30 +101,40 @@ struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
}
static int dt_to_map_one_config(struct pinctrl *p,
- struct pinctrl_dev *pctldev,
+ struct pinctrl_dev *hog_pctldev,
const char *statename,
struct device_node *np_config)
{
+ struct pinctrl_dev *pctldev = NULL;
struct device_node *np_pctldev;
const struct pinctrl_ops *ops;
int ret;
struct pinctrl_map *map;
unsigned num_maps;
+ bool allow_default = false;
/* Find the pin controller containing np_config */
np_pctldev = of_node_get(np_config);
for (;;) {
+ if (!allow_default)
+ allow_default = of_property_read_bool(np_pctldev,
+ "pinctrl-use-default");
+
np_pctldev = of_get_next_parent(np_pctldev);
if (!np_pctldev || of_node_is_root(np_pctldev)) {
- dev_info(p->dev, "could not find pctldev for node %pOF, deferring probe\n",
- np_config);
of_node_put(np_pctldev);
- /* OK let's just assume this will appear later then */
- return -EPROBE_DEFER;
+ ret = driver_deferred_probe_check_state(p->dev);
+ /* keep deferring if modules are enabled unless we've timed out */
+ if (IS_ENABLED(CONFIG_MODULES) && !allow_default && ret == -ENODEV)
+ ret = -EPROBE_DEFER;
+
+ return ret;
}
/* If we're creating a hog we can use the passed pctldev */
- if (pctldev && (np_pctldev == p->dev->of_node))
+ if (hog_pctldev && (np_pctldev == p->dev->of_node)) {
+ pctldev = hog_pctldev;
break;
+ }
pctldev = get_pinctrl_dev_from_of_node(np_pctldev);
if (pctldev)
break;