regulator: Fixes for v4.0
The two main fixes here from Javier and Doug both fix issues seen on the Exynos-based ARM Chromebooks with reference counting of GPIO regulators over system suspend. The GPIO enable code didn't properly take account of this cases (a full analysis is in Doug's commit log). This is fixed by both fixing the reference counting directly and by making the resume code skip enables it doesn't need to do. We could skip the change in the resume code but it's a very simple change and adds extra robustness against problems in other drivers. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJVCBjKAAoJECTWi3JdVIfQiA4H/2/zS+bEGIJs0yquAsmNT0as v1XW+K8pw8klcCUbUpBgeqwBDmhiHHJtL5AWuC68KZHLRmg4+ryRdCyUgZ51AyJ4 4obGKxVrWpO0xM3BLeoeCc0ZSAAQzVuxplFSyFEbE14ULUKBqsVS8YKD2+FyrDRL 0RPAdNDak2Z7HD60W6234qqGfmEW0e1NAYTuZ7sCjE4dp8+S8OeauuwT489tuGt7 7N+BusHHnjWASW3tcitANTE8f3l3K4b5sUueolxi+ZghnrcxHcZn7LlKbVj0tpiF yOCjc6jiLUL5UiCZ5q5IhamKPCTpTf/9LJlsjoSmj3Ze4PXn9/rEPW3wrIUyAh4= =Dxlj -----END PGP SIGNATURE----- Merge tag 'regulator-fix-v4.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator Pull regulator fixes from Mark Brown: "The two main fixes here from Javier and Doug both fix issues seen on the Exynos-based ARM Chromebooks with reference counting of GPIO regulators over system suspend. The GPIO enable code didn't properly take account of this case (a full analysis is in Doug's commit log). This is fixed by both fixing the reference counting directly and by making the resume code skip enables it doesn't need to do. We could skip the change in the resume code but it's a very simple change and adds extra robustness against problems in other drivers" * tag 'regulator-fix-v4.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: regulator: tps65910: Add missing #include <linux/of.h> regulator: core: Fix enable GPIO reference counting regulator: Only enable disabled regulators on resume
This commit is contained in:
Коммит
8e6e44fbd2
|
@ -1839,10 +1839,12 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
|
|||
}
|
||||
|
||||
if (rdev->ena_pin) {
|
||||
ret = regulator_ena_gpio_ctrl(rdev, true);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
rdev->ena_gpio_state = 1;
|
||||
if (!rdev->ena_gpio_state) {
|
||||
ret = regulator_ena_gpio_ctrl(rdev, true);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
rdev->ena_gpio_state = 1;
|
||||
}
|
||||
} else if (rdev->desc->ops->enable) {
|
||||
ret = rdev->desc->ops->enable(rdev);
|
||||
if (ret < 0)
|
||||
|
@ -1939,10 +1941,12 @@ static int _regulator_do_disable(struct regulator_dev *rdev)
|
|||
trace_regulator_disable(rdev_get_name(rdev));
|
||||
|
||||
if (rdev->ena_pin) {
|
||||
ret = regulator_ena_gpio_ctrl(rdev, false);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
rdev->ena_gpio_state = 0;
|
||||
if (rdev->ena_gpio_state) {
|
||||
ret = regulator_ena_gpio_ctrl(rdev, false);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
rdev->ena_gpio_state = 0;
|
||||
}
|
||||
|
||||
} else if (rdev->desc->ops->disable) {
|
||||
ret = rdev->desc->ops->disable(rdev);
|
||||
|
@ -3626,12 +3630,6 @@ regulator_register(const struct regulator_desc *regulator_desc,
|
|||
config->ena_gpio, ret);
|
||||
goto wash;
|
||||
}
|
||||
|
||||
if (config->ena_gpio_flags & GPIOF_OUT_INIT_HIGH)
|
||||
rdev->ena_gpio_state = 1;
|
||||
|
||||
if (config->ena_gpio_invert)
|
||||
rdev->ena_gpio_state = !rdev->ena_gpio_state;
|
||||
}
|
||||
|
||||
/* set regulator constraints */
|
||||
|
@ -3800,9 +3798,11 @@ int regulator_suspend_finish(void)
|
|||
list_for_each_entry(rdev, ®ulator_list, list) {
|
||||
mutex_lock(&rdev->mutex);
|
||||
if (rdev->use_count > 0 || rdev->constraints->always_on) {
|
||||
error = _regulator_do_enable(rdev);
|
||||
if (error)
|
||||
ret = error;
|
||||
if (!_regulator_is_enabled(rdev)) {
|
||||
error = _regulator_do_enable(rdev);
|
||||
if (error)
|
||||
ret = error;
|
||||
}
|
||||
} else {
|
||||
if (!have_full_constraints())
|
||||
goto unlock;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
|
|
Загрузка…
Ссылка в новой задаче