Commit c05127c4 authored by Linus Walleij's avatar Linus Walleij

pinctrl: implement pinctrl deferred probing

If drivers try to obtain pinctrl handles for a pin controller that
has not yet registered to the subsystem, we need to be able to
back out and retry with deferred probing. So let's return
-EPROBE_DEFER whenever this location fails. Also downgrade the
errors to info, maybe we will even set them to debug once the
deferred probing is commonplace.

Cc: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: default avatarStephen Warren <swarren@wwwdotorg.org>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent ad8bb720
...@@ -1043,6 +1043,11 @@ quickly poking some registers. ...@@ -1043,6 +1043,11 @@ quickly poking some registers.
The pins are allocated for your device when you issue the pinctrl_get() call, The pins are allocated for your device when you issue the pinctrl_get() call,
after this you should be able to see this in the debugfs listing of all pins. after this you should be able to see this in the debugfs listing of all pins.
NOTE: the pinctrl system will return -EPROBE_DEFER if it cannot find the
requested pinctrl handles, for example if the pinctrl driver has not yet
registered. Thus make sure that the error path in your driver gracefully
cleans up and is ready to retry the probing later in the startup process.
System pin control hogging System pin control hogging
========================== ==========================
......
...@@ -518,11 +518,14 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map) ...@@ -518,11 +518,14 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map)
setting->pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); setting->pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name);
if (setting->pctldev == NULL) { if (setting->pctldev == NULL) {
dev_err(p->dev, "unknown pinctrl device %s in map entry", dev_info(p->dev, "unknown pinctrl device %s in map entry, deferring probe",
map->ctrl_dev_name); map->ctrl_dev_name);
kfree(setting); kfree(setting);
/* Eventually, this should trigger deferred probe */ /*
return -ENODEV; * OK let us guess that the driver is not there yet, and
* let's defer obtaining this pinctrl handle to later...
*/
return -EPROBE_DEFER;
} }
switch (map->type) { switch (map->type) {
......
...@@ -121,11 +121,11 @@ static int dt_to_map_one_config(struct pinctrl *p, const char *statename, ...@@ -121,11 +121,11 @@ static int dt_to_map_one_config(struct pinctrl *p, const char *statename,
for (;;) { for (;;) {
np_pctldev = of_get_next_parent(np_pctldev); np_pctldev = of_get_next_parent(np_pctldev);
if (!np_pctldev || of_node_is_root(np_pctldev)) { if (!np_pctldev || of_node_is_root(np_pctldev)) {
dev_err(p->dev, "could not find pctldev for node %s\n", dev_info(p->dev, "could not find pctldev for node %s, deferring probe\n",
np_config->full_name); np_config->full_name);
of_node_put(np_pctldev); of_node_put(np_pctldev);
/* FIXME: This should trigger deferrered probe */ /* OK let's just assume this will appear later then */
return -ENODEV; return -EPROBE_DEFER;
} }
pctldev = find_pinctrl_by_of_node(np_pctldev); pctldev = find_pinctrl_by_of_node(np_pctldev);
if (pctldev) if (pctldev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment