regulator: Fixes for v3.7
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. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJQpFCIAAoJELSic+t+oim9qSoP/jvczRiW2kS9Rac8JWR3q08K htYKMR2Ve825AI5gqx6J68gzo5gCBFef1wZ6cacTa3LTYebHLWBV3IRfQqUhuIhA sxx15nABvjp/hMOo/7pFSyzxy/Gq5bDY1cBfPggTHo2tFVQ3vwp/K4subo0T/8j+ oQPb1YMVM3nPTEXiJfZJ2lnuIc7eOtGMptVOsW/0JHdzzij6CKqeHI6PYmzpsHMm wevhYbEefTi0jauXXtDUPFEqD/QCMe/C1oYdE0G+Xh7vCiD5S/C2c7cEeEjvX5QH xXsy3ksSIEyrMXQ/KjJNCvTe/LnoxTkCstuEVDkxImCSGLdfqyWwWwgDODuFAAk6 MpPjie9pFeBRcCsJuZgnst1NKS4PNVMnorMOOeQvzNhltsGhojSG2j5UVyQW/tnD UNbKxlPfrvsy9oyPB/YWkPmjGggwIOIsXfHYFlH2QrHuTNfawFl22PUteSRKCedi /DDL5tuz1u2kEZd5TB+xodKtnxPUxexrQbrChN4BXlRrGSfjr79lmr9HW7lz1UJm HlTjmrjXn3esQyIgIuBseXSQP6jpXAvXvuZ+Fw/YuOYxqZiREtsPix9ADLRwGj20 aGCrghXMylk0VMP8mqMeurry36OYP+0v0GyDnB5cQrkyW0TS+kPSrReNyJ6apn3N dt50RbLYnF7uaZJh48OD =HyTz -----END PGP SIGNATURE----- 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.
This commit is contained in:
commit
7c96cfcd4e
@ -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(®ulator_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)
|
|||||||
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(®ulator_list_mutex);
|
||||||
|
_regulator_put(regulator);
|
||||||
mutex_unlock(®ulator_list_mutex);
|
mutex_unlock(®ulator_list_mutex);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(regulator_put);
|
EXPORT_SYMBOL_GPL(regulator_put);
|
||||||
@ -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,
|
|||||||
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 @@ unset_supplies:
|
|||||||
|
|
||||||
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user