aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoris Brezillon <boris.brezillon@free-electrons.com>2016-04-12 06:31:00 -0400
committerMark Brown <broonie@kernel.org>2016-04-13 02:33:44 -0400
commit469b640e4f4a28bdd50f0ac1d2b310907afb464c (patch)
treec739534dfe6b5bc6441680c51d21ed4269fdd8ce
parentf55532a0c0b8bb6148f4e07853b876ef73bc69ca (diff)
regulator: reorder initialization steps in regulator_register()
device_register() is calling ->get_voltage() as part of it's sysfs attribute initialization process, and this functions might need to know the regulator constraints to return a valid value. This is at least true for the pwm regulator driver (when operating in continuous mode) which needs to know the minimum and maximum voltage values to calculate the current voltage: min_uV + (((max_uV - min_uV) * dutycycle) / 100); Move device_register() after set_machine_constraints() to make sure those constraints are correctly initialized when ->get_voltage() is called. Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> Reported-by: Stephen Barber <smbarber@chromium.org> Tested-by: Caesar Wang <wxt@rock-chips.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/regulator/core.c20
1 files changed, 10 insertions, 10 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index e0b764284773..8258568c793a 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -3950,13 +3950,6 @@ regulator_register(const struct regulator_desc *regulator_desc,
3950 rdev->dev.parent = dev; 3950 rdev->dev.parent = dev;
3951 dev_set_name(&rdev->dev, "regulator.%lu", 3951 dev_set_name(&rdev->dev, "regulator.%lu",
3952 (unsigned long) atomic_inc_return(&regulator_no)); 3952 (unsigned long) atomic_inc_return(&regulator_no));
3953 ret = device_register(&rdev->dev);
3954 if (ret != 0) {
3955 put_device(&rdev->dev);
3956 goto wash;
3957 }
3958
3959 dev_set_drvdata(&rdev->dev, rdev);
3960 3953
3961 /* set regulator constraints */ 3954 /* set regulator constraints */
3962 if (init_data) 3955 if (init_data)
@@ -3964,7 +3957,15 @@ regulator_register(const struct regulator_desc *regulator_desc,
3964 3957
3965 ret = set_machine_constraints(rdev, constraints); 3958 ret = set_machine_constraints(rdev, constraints);
3966 if (ret < 0) 3959 if (ret < 0)
3967 goto scrub; 3960 goto wash;
3961
3962 ret = device_register(&rdev->dev);
3963 if (ret != 0) {
3964 put_device(&rdev->dev);
3965 goto wash;
3966 }
3967
3968 dev_set_drvdata(&rdev->dev, rdev);
3968 3969
3969 if (init_data && init_data->supply_regulator) 3970 if (init_data && init_data->supply_regulator)
3970 rdev->supply_name = init_data->supply_regulator; 3971 rdev->supply_name = init_data->supply_regulator;
@@ -3993,8 +3994,6 @@ out:
3993 3994
3994unset_supplies: 3995unset_supplies:
3995 unset_regulator_supplies(rdev); 3996 unset_regulator_supplies(rdev);
3996
3997scrub:
3998 regulator_ena_gpio_free(rdev); 3997 regulator_ena_gpio_free(rdev);
3999 device_unregister(&rdev->dev); 3998 device_unregister(&rdev->dev);
4000 /* device core frees rdev */ 3999 /* device core frees rdev */
@@ -4002,6 +4001,7 @@ scrub:
4002 goto out; 4001 goto out;
4003 4002
4004wash: 4003wash:
4004 kfree(rdev->constraints);
4005 regulator_ena_gpio_free(rdev); 4005 regulator_ena_gpio_free(rdev);
4006clean: 4006clean:
4007 kfree(rdev); 4007 kfree(rdev);