aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Hunter <jonathanh@nvidia.com>2016-04-26 06:29:45 -0400
committerMark Brown <broonie@kernel.org>2016-04-27 11:32:19 -0400
commit45389c47526d1eca70f96872c172aea0941e8520 (patch)
tree6a81f0253984258847c4ef072720752b94d81b3b
parentcbc13a66fdd89ac5e360af32fec0a1a4fcd4d2f1 (diff)
regulator: core: Add early supply resolution for regulators
The call to set_machine_constraints() in regulator_register(), will attempt to get the voltage for the regulator. If a regulator is in bypass will fail to get the voltage (ie. it's bypass voltage) and hence register the regulator, because the supply for the regulator has not been resolved yet. To fix this, add a call to regulator_resolve_supply() before we call set_machine_constraints(). If the call to regulator_resolve_supply() fails, rather than returning an error at this point, allow the registration of the regulator to continue because for some regulators resolving the supply at this point may not be necessary and it will be resolved later as more regulators are added. Furthermore, if the supply is still not resolved for a bypassed regulator, this will be detected when we attempt to get the voltage for the regulator and an error will be propagated at this point. If a bypassed regulator does not have a supply when we attempt to get the voltage, rather than returing -EINVAL, return -EPROBE_DEFER instead to allow the registration of the regulator to be deferred and tried again later. Please note that regulator_resolve_supply() will call regulator_dev_lookup() which may acquire the regulator_list_mutex. To avoid any deadlocks we cannot hold the regulator_list_mutex when calling regulator_resolve_supply(). Therefore, rather than holding the lock around a large portion of the registration code, just hold the lock when aquiring any GPIOs and setting up supplies because these sections may add entries to the regulator_map_list and regulator_ena_gpio_list, respectively. Signed-off-by: Jon Hunter <jonathanh@nvidia.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/regulator/core.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index f6d624dfcf9f..f4ab8c8bab23 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -3118,8 +3118,11 @@ static int _regulator_get_voltage(struct regulator_dev *rdev)
3118 return ret; 3118 return ret;
3119 if (bypassed) { 3119 if (bypassed) {
3120 /* if bypassed the regulator must have a supply */ 3120 /* if bypassed the regulator must have a supply */
3121 if (!rdev->supply) 3121 if (!rdev->supply) {
3122 return -EINVAL; 3122 rdev_err(rdev,
3123 "bypassed regulator has no supply!\n");
3124 return -EPROBE_DEFER;
3125 }
3123 3126
3124 return _regulator_get_voltage(rdev->supply->rdev); 3127 return _regulator_get_voltage(rdev->supply->rdev);
3125 } 3128 }
@@ -3936,8 +3939,6 @@ regulator_register(const struct regulator_desc *regulator_desc,
3936 rdev->dev.of_node = of_node_get(config->of_node); 3939 rdev->dev.of_node = of_node_get(config->of_node);
3937 } 3940 }
3938 3941
3939 mutex_lock(&regulator_list_mutex);
3940
3941 mutex_init(&rdev->mutex); 3942 mutex_init(&rdev->mutex);
3942 rdev->reg_data = config->driver_data; 3943 rdev->reg_data = config->driver_data;
3943 rdev->owner = regulator_desc->owner; 3944 rdev->owner = regulator_desc->owner;
@@ -3962,7 +3963,9 @@ regulator_register(const struct regulator_desc *regulator_desc,
3962 3963
3963 if ((config->ena_gpio || config->ena_gpio_initialized) && 3964 if ((config->ena_gpio || config->ena_gpio_initialized) &&
3964 gpio_is_valid(config->ena_gpio)) { 3965 gpio_is_valid(config->ena_gpio)) {
3966 mutex_lock(&regulator_list_mutex);
3965 ret = regulator_ena_gpio_request(rdev, config); 3967 ret = regulator_ena_gpio_request(rdev, config);
3968 mutex_unlock(&regulator_list_mutex);
3966 if (ret != 0) { 3969 if (ret != 0) {
3967 rdev_err(rdev, "Failed to request enable GPIO%d: %d\n", 3970 rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
3968 config->ena_gpio, ret); 3971 config->ena_gpio, ret);
@@ -3980,31 +3983,40 @@ regulator_register(const struct regulator_desc *regulator_desc,
3980 if (init_data) 3983 if (init_data)
3981 constraints = &init_data->constraints; 3984 constraints = &init_data->constraints;
3982 3985
3983 ret = set_machine_constraints(rdev, constraints);
3984 if (ret < 0)
3985 goto wash;
3986
3987 if (init_data && init_data->supply_regulator) 3986 if (init_data && init_data->supply_regulator)
3988 rdev->supply_name = init_data->supply_regulator; 3987 rdev->supply_name = init_data->supply_regulator;
3989 else if (regulator_desc->supply_name) 3988 else if (regulator_desc->supply_name)
3990 rdev->supply_name = regulator_desc->supply_name; 3989 rdev->supply_name = regulator_desc->supply_name;
3991 3990
3991 /*
3992 * Attempt to resolve the regulator supply, if specified,
3993 * but don't return an error if we fail because we will try
3994 * to resolve it again later as more regulators are added.
3995 */
3996 if (regulator_resolve_supply(rdev))
3997 rdev_dbg(rdev, "unable to resolve supply\n");
3998
3999 ret = set_machine_constraints(rdev, constraints);
4000 if (ret < 0)
4001 goto wash;
4002
3992 /* add consumers devices */ 4003 /* add consumers devices */
3993 if (init_data) { 4004 if (init_data) {
4005 mutex_lock(&regulator_list_mutex);
3994 for (i = 0; i < init_data->num_consumer_supplies; i++) { 4006 for (i = 0; i < init_data->num_consumer_supplies; i++) {
3995 ret = set_consumer_device_supply(rdev, 4007 ret = set_consumer_device_supply(rdev,
3996 init_data->consumer_supplies[i].dev_name, 4008 init_data->consumer_supplies[i].dev_name,
3997 init_data->consumer_supplies[i].supply); 4009 init_data->consumer_supplies[i].supply);
3998 if (ret < 0) { 4010 if (ret < 0) {
4011 mutex_unlock(&regulator_list_mutex);
3999 dev_err(dev, "Failed to set supply %s\n", 4012 dev_err(dev, "Failed to set supply %s\n",
4000 init_data->consumer_supplies[i].supply); 4013 init_data->consumer_supplies[i].supply);
4001 goto unset_supplies; 4014 goto unset_supplies;
4002 } 4015 }
4003 } 4016 }
4017 mutex_unlock(&regulator_list_mutex);
4004 } 4018 }
4005 4019
4006 mutex_unlock(&regulator_list_mutex);
4007
4008 ret = device_register(&rdev->dev); 4020 ret = device_register(&rdev->dev);
4009 if (ret != 0) { 4021 if (ret != 0) {
4010 put_device(&rdev->dev); 4022 put_device(&rdev->dev);
@@ -4021,13 +4033,16 @@ regulator_register(const struct regulator_desc *regulator_desc,
4021 return rdev; 4033 return rdev;
4022 4034
4023unset_supplies: 4035unset_supplies:
4036 mutex_lock(&regulator_list_mutex);
4024 unset_regulator_supplies(rdev); 4037 unset_regulator_supplies(rdev);
4038 mutex_unlock(&regulator_list_mutex);
4025wash: 4039wash:
4026 kfree(rdev->constraints); 4040 kfree(rdev->constraints);
4041 mutex_lock(&regulator_list_mutex);
4027 regulator_ena_gpio_free(rdev); 4042 regulator_ena_gpio_free(rdev);
4043 mutex_unlock(&regulator_list_mutex);
4028clean: 4044clean:
4029 kfree(rdev); 4045 kfree(rdev);
4030 mutex_unlock(&regulator_list_mutex);
4031 kfree(config); 4046 kfree(config);
4032 return ERR_PTR(ret); 4047 return ERR_PTR(ret);
4033} 4048}