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: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Stephen Warren <swarren@wwwdotorg.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
Linus Walleij 2012-04-10 10:00:38 +02:00
parent ad8bb720c2
commit c05127c4e2
3 changed files with 14 additions and 6 deletions

View file

@ -1043,6 +1043,11 @@ quickly poking some registers.
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.
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
==========================

View file

@ -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);
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);
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) {

View file

@ -121,11 +121,11 @@ static int dt_to_map_one_config(struct pinctrl *p, const char *statename,
for (;;) {
np_pctldev = of_get_next_parent(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);
of_node_put(np_pctldev);
/* FIXME: This should trigger deferrered probe */
return -ENODEV;
/* OK let's just assume this will appear later then */
return -EPROBE_DEFER;
}
pctldev = find_pinctrl_by_of_node(np_pctldev);
if (pctldev)