Commit 8e6e44fb authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'regulator-fix-v4.0-rc4' of...

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
parents 529d2eb6 8ca8f326
......@@ -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, &regulator_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>
......
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