* [PATCH v2] regulator: core: Fix enable GPIO reference counting
@ 2015-03-03 23:20 Doug Anderson
2015-03-08 19:44 ` Mark Brown
0 siblings, 1 reply; 2+ messages in thread
From: Doug Anderson @ 2015-03-03 23:20 UTC (permalink / raw)
To: Mark Brown
Cc: milo.kim, axel.lin, Dmitry Torokhov, olof, javier.martinez,
Paul Stewart, Doug Anderson, lgirdwood, linux-kernel
Normally _regulator_do_enable() isn't called on an already-enabled
rdev. That's because the main caller, _regulator_enable() always
calls _regulator_is_enabled() and only calls _regulator_do_enable() if
the rdev was not already enabled.
However, there is one caller of _regulator_do_enable() that doesn't
check: regulator_suspend_finish(). While we might want to make
regulator_suspend_finish() behave more like _regulator_enable(), it's
probably also a good idea to make _regulator_do_enable() robust if it
is called on an already enabled rdev.
At the moment, _regulator_do_enable() is _not_ robust for already
enabled rdevs if we're using an ena_pin. Each time
_regulator_do_enable() is called for an rdev using an ena_pin the
reference count of the ena_pin is incremented even if the rdev was
already enabled. This is not as intended because the ena_pin is for
something else: for keeping track of how many active rdevs there are
sharing the same ena_pin.
Here's how the reference counting works here:
* Each time _regulator_enable() is called we increment
rdev->use_count, so _regulator_enable() calls need to be balanced
with _regulator_disable() calls.
* There is no explicit reference counting in _regulator_do_enable()
which is normally just a warapper around rdev->desc->ops->enable()
with code for supporting delays. It's not expected that the
"ops->enable()" call do reference counting.
* Since regulator_ena_gpio_ctrl() does have reference counting
(handling the sharing of the pin amongst multiple rdevs), we
shouldn't call it if the current rdev is already enabled.
Note that as part of this we cleanup (remove) the initting of
ena_gpio_state in regulator_register(). In _regulator_do_enable(),
_regulator_do_disable() and _regulator_is_enabled() is is clear that
ena_gpio_state should be the state of whether this particular rdev has
requested the GPIO be enabled. regulator_register() was initting it
as the actual state of the pin.
Fixes: 967cfb18c0e3 ("regulator: core: manage enable GPIO list")
Signed-off-by: Doug Anderson <dianders@chromium.org>
---
Changes in v2:
- Rewrote commit message
- Avoid initting ena_gpio_state in regulator_register()
drivers/regulator/core.c | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index f245214..ae16a2d 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1848,10 +1848,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)
@@ -1948,10 +1950,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);
@@ -3642,12 +3646,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 */
--
2.2.0.rc0.207.ga3a616c
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [PATCH v2] regulator: core: Fix enable GPIO reference counting
2015-03-03 23:20 [PATCH v2] regulator: core: Fix enable GPIO reference counting Doug Anderson
@ 2015-03-08 19:44 ` Mark Brown
0 siblings, 0 replies; 2+ messages in thread
From: Mark Brown @ 2015-03-08 19:44 UTC (permalink / raw)
To: Doug Anderson
Cc: milo.kim, axel.lin, Dmitry Torokhov, olof, javier.martinez,
Paul Stewart, lgirdwood, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 327 bytes --]
On Tue, Mar 03, 2015 at 03:20:47PM -0800, Doug Anderson wrote:
> Normally _regulator_do_enable() isn't called on an already-enabled
> rdev. That's because the main caller, _regulator_enable() always
> calls _regulator_is_enabled() and only calls _regulator_do_enable() if
> the rdev was not already enabled.
Applied, thanks.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2015-03-08 19:44 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-03 23:20 [PATCH v2] regulator: core: Fix enable GPIO reference counting Doug Anderson
2015-03-08 19:44 ` Mark Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®