Skip to content

Commit

Permalink
pinctrl: implement pinctrl deferred probing
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Linus Walleij committed Apr 18, 2012
1 parent ad8bb72 commit c05127c
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 6 deletions.
5 changes: 5 additions & 0 deletions Documentation/pinctrl.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
==========================
Expand Down
9 changes: 6 additions & 3 deletions drivers/pinctrl/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
6 changes: 3 additions & 3 deletions drivers/pinctrl/devicetree.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit c05127c

Please sign in to comment.