summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/regulator/core.c49
1 files changed, 29 insertions, 20 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 990fd7b3da7d..f6d624dfcf9f 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1536,6 +1536,7 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
ret = regulator_enable(rdev->supply);
if (ret < 0) {
_regulator_put(rdev->supply);
+ rdev->supply = NULL;
return ret;
}
}
@@ -3854,6 +3855,16 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
&rdev->bypass_count);
}
+static int regulator_register_resolve_supply(struct device *dev, void *data)
+{
+ struct regulator_dev *rdev = dev_to_rdev(dev);
+
+ if (regulator_resolve_supply(rdev))
+ rdev_dbg(rdev, "unable to resolve supply\n");
+
+ return 0;
+}
+
/**
* regulator_register - register regulator
* @regulator_desc: regulator to register
@@ -3964,13 +3975,6 @@ regulator_register(const struct regulator_desc *regulator_desc,
rdev->dev.parent = dev;
dev_set_name(&rdev->dev, "regulator.%lu",
(unsigned long) atomic_inc_return(&regulator_no));
- ret = device_register(&rdev->dev);
- if (ret != 0) {
- put_device(&rdev->dev);
- goto wash;
- }
-
- dev_set_drvdata(&rdev->dev, rdev);
/* set regulator constraints */
if (init_data)
@@ -3978,7 +3982,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
ret = set_machine_constraints(rdev, constraints);
if (ret < 0)
- goto scrub;
+ goto wash;
if (init_data && init_data->supply_regulator)
rdev->supply_name = init_data->supply_regulator;
@@ -3999,28 +4003,33 @@ regulator_register(const struct regulator_desc *regulator_desc,
}
}
- rdev_init_debugfs(rdev);
-out:
mutex_unlock(&regulator_list_mutex);
+
+ ret = device_register(&rdev->dev);
+ if (ret != 0) {
+ put_device(&rdev->dev);
+ goto unset_supplies;
+ }
+
+ dev_set_drvdata(&rdev->dev, rdev);
+ rdev_init_debugfs(rdev);
+
+ /* try to resolve regulators supply since a new one was registered */
+ class_for_each_device(&regulator_class, NULL, NULL,
+ regulator_register_resolve_supply);
kfree(config);
return rdev;
unset_supplies:
unset_regulator_supplies(rdev);
-
-scrub:
- regulator_ena_gpio_free(rdev);
- device_unregister(&rdev->dev);
- /* device core frees rdev */
- rdev = ERR_PTR(ret);
- goto out;
-
wash:
+ kfree(rdev->constraints);
regulator_ena_gpio_free(rdev);
clean:
kfree(rdev);
- rdev = ERR_PTR(ret);
- goto out;
+ mutex_unlock(&regulator_list_mutex);
+ kfree(config);
+ return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(regulator_register);