Commit 7c96cfcd authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'regulator-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator

Pull regulator fixes from Mark Brown:
 "A few fixes for teardown issues that will be rarely seen, plus a fix
  for a silly bug in regulator_is_supported_voltage() which shows how
  often the answer to the question should be false.

  The supported voltage commit is very new as I just edited to add a Cc
  to stable, the code itself has been in -next."

* tag 'regulator-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator:
  regulator: fix voltage check in regulator_is_supported_voltage()
  regulator: core: Avoid deadlock when regulator_register fails
  Regulator: core: Unregister when gpio request fails.
parents 38216134 ecb48c33
...@@ -1381,22 +1381,14 @@ struct regulator *regulator_get_exclusive(struct device *dev, const char *id) ...@@ -1381,22 +1381,14 @@ struct regulator *regulator_get_exclusive(struct device *dev, const char *id)
} }
EXPORT_SYMBOL_GPL(regulator_get_exclusive); EXPORT_SYMBOL_GPL(regulator_get_exclusive);
/** /* Locks held by regulator_put() */
* regulator_put - "free" the regulator source static void _regulator_put(struct regulator *regulator)
* @regulator: regulator source
*
* Note: drivers must ensure that all regulator_enable calls made on this
* regulator source are balanced by regulator_disable calls prior to calling
* this function.
*/
void regulator_put(struct regulator *regulator)
{ {
struct regulator_dev *rdev; struct regulator_dev *rdev;
if (regulator == NULL || IS_ERR(regulator)) if (regulator == NULL || IS_ERR(regulator))
return; return;
mutex_lock(&regulator_list_mutex);
rdev = regulator->rdev; rdev = regulator->rdev;
debugfs_remove_recursive(regulator->debugfs); debugfs_remove_recursive(regulator->debugfs);
...@@ -1412,6 +1404,20 @@ void regulator_put(struct regulator *regulator) ...@@ -1412,6 +1404,20 @@ void regulator_put(struct regulator *regulator)
rdev->exclusive = 0; rdev->exclusive = 0;
module_put(rdev->owner); module_put(rdev->owner);
}
/**
* regulator_put - "free" the regulator source
* @regulator: regulator source
*
* Note: drivers must ensure that all regulator_enable calls made on this
* regulator source are balanced by regulator_disable calls prior to calling
* this function.
*/
void regulator_put(struct regulator *regulator)
{
mutex_lock(&regulator_list_mutex);
_regulator_put(regulator);
mutex_unlock(&regulator_list_mutex); mutex_unlock(&regulator_list_mutex);
} }
EXPORT_SYMBOL_GPL(regulator_put); EXPORT_SYMBOL_GPL(regulator_put);
...@@ -1974,7 +1980,7 @@ int regulator_is_supported_voltage(struct regulator *regulator, ...@@ -1974,7 +1980,7 @@ int regulator_is_supported_voltage(struct regulator *regulator,
if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
ret = regulator_get_voltage(regulator); ret = regulator_get_voltage(regulator);
if (ret >= 0) if (ret >= 0)
return (min_uV >= ret && ret <= max_uV); return (min_uV <= ret && ret <= max_uV);
else else
return ret; return ret;
} }
...@@ -3365,7 +3371,7 @@ regulator_register(const struct regulator_desc *regulator_desc, ...@@ -3365,7 +3371,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
if (ret != 0) { if (ret != 0) {
rdev_err(rdev, "Failed to request enable GPIO%d: %d\n", rdev_err(rdev, "Failed to request enable GPIO%d: %d\n",
config->ena_gpio, ret); config->ena_gpio, ret);
goto clean; goto wash;
} }
rdev->ena_gpio = config->ena_gpio; rdev->ena_gpio = config->ena_gpio;
...@@ -3445,10 +3451,11 @@ regulator_register(const struct regulator_desc *regulator_desc, ...@@ -3445,10 +3451,11 @@ regulator_register(const struct regulator_desc *regulator_desc,
scrub: scrub:
if (rdev->supply) if (rdev->supply)
regulator_put(rdev->supply); _regulator_put(rdev->supply);
if (rdev->ena_gpio) if (rdev->ena_gpio)
gpio_free(rdev->ena_gpio); gpio_free(rdev->ena_gpio);
kfree(rdev->constraints); kfree(rdev->constraints);
wash:
device_unregister(&rdev->dev); device_unregister(&rdev->dev);
/* device core frees rdev */ /* device core frees rdev */
rdev = ERR_PTR(ret); rdev = ERR_PTR(ret);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment