diff options
-rw-r--r-- | drivers/regulator/core.c | 49 |
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(®ulator_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(®ulator_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(®ulator_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(®ulator_list_mutex); + kfree(config); + return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(regulator_register); |