aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-03-17 13:47:06 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-03-17 13:47:06 -0400
commit8e6e44fbd230b12c34c9166ec49f63a5bd6018b7 (patch)
treef1aa2952cbbf337520856e21914a1609c6ae09ab
parent529d2eb6795cf899c1c5fd419c3313a94ca5ba4d (diff)
parent8ca8f32666d2a655e274836400e1a7f7fa313502 (diff)
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
-rw-r--r--drivers/regulator/core.c34
-rw-r--r--drivers/regulator/tps65910-regulator.c1
2 files changed, 18 insertions, 17 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 1245dca79009..a4a8a6dc60c4 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1839,10 +1839,12 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
1839 } 1839 }
1840 1840
1841 if (rdev->ena_pin) { 1841 if (rdev->ena_pin) {
1842 ret = regulator_ena_gpio_ctrl(rdev, true); 1842 if (!rdev->ena_gpio_state) {
1843 if (ret < 0) 1843 ret = regulator_ena_gpio_ctrl(rdev, true);
1844 return ret; 1844 if (ret < 0)
1845 rdev->ena_gpio_state = 1; 1845 return ret;
1846 rdev->ena_gpio_state = 1;
1847 }
1846 } else if (rdev->desc->ops->enable) { 1848 } else if (rdev->desc->ops->enable) {
1847 ret = rdev->desc->ops->enable(rdev); 1849 ret = rdev->desc->ops->enable(rdev);
1848 if (ret < 0) 1850 if (ret < 0)
@@ -1939,10 +1941,12 @@ static int _regulator_do_disable(struct regulator_dev *rdev)
1939 trace_regulator_disable(rdev_get_name(rdev)); 1941 trace_regulator_disable(rdev_get_name(rdev));
1940 1942
1941 if (rdev->ena_pin) { 1943 if (rdev->ena_pin) {
1942 ret = regulator_ena_gpio_ctrl(rdev, false); 1944 if (rdev->ena_gpio_state) {
1943 if (ret < 0) 1945 ret = regulator_ena_gpio_ctrl(rdev, false);
1944 return ret; 1946 if (ret < 0)
1945 rdev->ena_gpio_state = 0; 1947 return ret;
1948 rdev->ena_gpio_state = 0;
1949 }
1946 1950
1947 } else if (rdev->desc->ops->disable) { 1951 } else if (rdev->desc->ops->disable) {
1948 ret = rdev->desc->ops->disable(rdev); 1952 ret = rdev->desc->ops->disable(rdev);
@@ -3626,12 +3630,6 @@ regulator_register(const struct regulator_desc *regulator_desc,
3626 config->ena_gpio, ret); 3630 config->ena_gpio, ret);
3627 goto wash; 3631 goto wash;
3628 } 3632 }
3629
3630 if (config->ena_gpio_flags & GPIOF_OUT_INIT_HIGH)
3631 rdev->ena_gpio_state = 1;
3632
3633 if (config->ena_gpio_invert)
3634 rdev->ena_gpio_state = !rdev->ena_gpio_state;
3635 } 3633 }
3636 3634
3637 /* set regulator constraints */ 3635 /* set regulator constraints */
@@ -3800,9 +3798,11 @@ int regulator_suspend_finish(void)
3800 list_for_each_entry(rdev, &regulator_list, list) { 3798 list_for_each_entry(rdev, &regulator_list, list) {
3801 mutex_lock(&rdev->mutex); 3799 mutex_lock(&rdev->mutex);
3802 if (rdev->use_count > 0 || rdev->constraints->always_on) { 3800 if (rdev->use_count > 0 || rdev->constraints->always_on) {
3803 error = _regulator_do_enable(rdev); 3801 if (!_regulator_is_enabled(rdev)) {
3804 if (error) 3802 error = _regulator_do_enable(rdev);
3805 ret = error; 3803 if (error)
3804 ret = error;
3805 }
3806 } else { 3806 } else {
3807 if (!have_full_constraints()) 3807 if (!have_full_constraints())
3808 goto unlock; 3808 goto unlock;
diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c
index e2cffe01b807..fb991ec76423 100644
--- a/drivers/regulator/tps65910-regulator.c
+++ b/drivers/regulator/tps65910-regulator.c
@@ -17,6 +17,7 @@
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/err.h> 19#include <linux/err.h>
20#include <linux/of.h>
20#include <linux/platform_device.h> 21#include <linux/platform_device.h>
21#include <linux/regulator/driver.h> 22#include <linux/regulator/driver.h>
22#include <linux/regulator/machine.h> 23#include <linux/regulator/machine.h>