summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarco Felsch <m.felsch@pengutronix.de>2019-09-17 17:40:21 +0200
committerMark Brown <broonie@kernel.org>2019-09-17 16:59:38 +0100
commitf8970d341eec73c976a3462b9ecdb02b60b84dd6 (patch)
tree95099c8b375d20b6f445644923d40ebaae3c7348
parent131cb1210d4b58acb0695707dad2eb90dcb50a2a (diff)
downloadlinux-f8970d341eec73c976a3462b9ecdb02b60b84dd6.tar.bz2
regulator: core: make regulator_register() EPROBE_DEFER aware
Sometimes it can happen that the regulator_of_get_init_data() can't retrieve the config due to a not probed device the regulator depends on. Fix that by checking the return value of of_parse_cb() and return EPROBE_DEFER in such cases. Signed-off-by: Marco Felsch <m.felsch@pengutronix.de> Link: https://lore.kernel.org/r/20190917154021.14693-4-m.felsch@pengutronix.de Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/regulator/core.c13
-rw-r--r--drivers/regulator/of_regulator.c19
2 files changed, 27 insertions, 5 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index afe94470b67f..a46be221dbdc 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -5053,6 +5053,19 @@ regulator_register(const struct regulator_desc *regulator_desc,
init_data = regulator_of_get_init_data(dev, regulator_desc, config,
&rdev->dev.of_node);
+
+ /*
+ * Sometimes not all resources are probed already so we need to take
+ * that into account. This happens most the time if the ena_gpiod comes
+ * from a gpio extender or something else.
+ */
+ if (PTR_ERR(init_data) == -EPROBE_DEFER) {
+ kfree(config);
+ kfree(rdev);
+ ret = -EPROBE_DEFER;
+ goto rinse;
+ }
+
/*
* We need to keep track of any GPIO descriptor coming from the
* device tree until we have handled it over to the core. If the
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
index 38dd06fbab38..ef7198b76e50 100644
--- a/drivers/regulator/of_regulator.c
+++ b/drivers/regulator/of_regulator.c
@@ -445,11 +445,20 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
goto error;
}
- if (desc->of_parse_cb && desc->of_parse_cb(child, desc, config)) {
- dev_err(dev,
- "driver callback failed to parse DT for regulator %pOFn\n",
- child);
- goto error;
+ if (desc->of_parse_cb) {
+ int ret;
+
+ ret = desc->of_parse_cb(child, desc, config);
+ if (ret) {
+ if (ret == -EPROBE_DEFER) {
+ of_node_put(child);
+ return ERR_PTR(-EPROBE_DEFER);
+ }
+ dev_err(dev,
+ "driver callback failed to parse DT for regulator %pOFn\n",
+ child);
+ goto error;
+ }
}
*node = child;