summaryrefslogtreecommitdiffstats
path: root/drivers/regulator/core.c
diff options
context:
space:
mode:
authorJon Hunter <jonathanh@nvidia.com>2016-04-21 17:11:59 +0100
committerMark Brown <broonie@kernel.org>2016-04-22 11:38:47 +0100
commitc438b9d017362b65f6b1a9e54f7f35e7f873dc7c (patch)
tree9ba4ac5fe0000d1b1ba483f6772accfd6dde58b8 /drivers/regulator/core.c
parentf89ba3383ee69e2e1473e41ed42614fc7c9d9192 (diff)
downloadlinux-c438b9d017362b65f6b1a9e54f7f35e7f873dc7c.tar.gz
linux-c438b9d017362b65f6b1a9e54f7f35e7f873dc7c.tar.bz2
linux-c438b9d017362b65f6b1a9e54f7f35e7f873dc7c.zip
regulator: core: Move registration of regulator device
The public functions to acquire a regulator, such as regulator_get(), internally look-up the regulator from the list of regulators that have been registered with the regulator device class. The registration of a new regulator with the regulator device class happens before the regulator has been completely setup. Therefore, it is possible that the regulator could be acquired before it has been setup successfully. To avoid this move the device registration of the regulator to the end of the regulator setup and update the error exit path accordingly. Signed-off-by: Jon Hunter <jonathanh@nvidia.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/regulator/core.c')
-rw-r--r--drivers/regulator/core.c24
1 files changed, 9 insertions, 15 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index a17ce6cbbe77..8362a0a5105d 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -3970,14 +3970,6 @@ regulator_register(const struct regulator_desc *regulator_desc,
if (ret < 0)
goto wash;
- ret = device_register(&rdev->dev);
- if (ret != 0) {
- put_device(&rdev->dev);
- goto wash;
- }
-
- dev_set_drvdata(&rdev->dev, rdev);
-
if (init_data && init_data->supply_regulator)
rdev->supply_name = init_data->supply_regulator;
else if (regulator_desc->supply_name)
@@ -3997,9 +3989,17 @@ regulator_register(const struct regulator_desc *regulator_desc,
}
}
- rdev_init_debugfs(rdev);
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);
@@ -4008,17 +4008,11 @@ regulator_register(const struct regulator_desc *regulator_desc,
unset_supplies:
unset_regulator_supplies(rdev);
- regulator_ena_gpio_free(rdev);
- device_unregister(&rdev->dev);
- /* device core frees rdev */
- goto out;
-
wash:
kfree(rdev->constraints);
regulator_ena_gpio_free(rdev);
clean:
kfree(rdev);
-out:
mutex_unlock(&regulator_list_mutex);
kfree(config);
return ERR_PTR(ret);