LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
To: Doug Anderson <dianders@chromium.org>, Mark Brown <broonie@kernel.org>
Cc: milo.kim@ti.com, axel.lin@ingics.com,
	Dmitry Torokhov <dmitry.torokhov@gmail.com>,
	olof@lixom.net, Paul Stewart <pstew@chromium.org>,
	stable@vger.kernel.org, lgirdwood@gmail.com,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] regulator: core: Fix enable GPIO reference counting
Date: Fri, 27 Feb 2015 22:01:23 +0100	[thread overview]
Message-ID: <54F0DB23.3010203@collabora.co.uk> (raw)
In-Reply-To: <1425066064-18920-1-git-send-email-dianders@chromium.org>

Hello Doug,

On 02/27/2015 08:41 PM, Doug Anderson wrote:
> It is possible for _regulator_do_enable() to be called for an
> already-enabled rdev, like in regulator_suspend_finish().  If we were
> using an enable pin (rdev->ena_pin is set) then we'd end up
> incrementing the reference count in regulator_ena_gpio_ctrl() over and
> over again without a decrement.  That prevented the GPIO from going to
> the "off" state even after all users were disabled.
> 
> Fix this by avoiding the call to regulator_ena_gpio_ctrl() when it's
> not needed.
>

I noticed the same problem in regulator_suspend_finish() when I was working
on S2R for Exynos a couple of months ago and had patch [0] on my local tree
but never found the time to do extensive testing so I never posted it.

In my case a tps65090 FET regulator was tried to be enabled twice and
tps65090_fet_enable() was failing printing a warning.
 
> Signed-off-by: Doug Anderson <dianders@chromium.org>
> Fixes: 967cfb18c0e3 ("regulator: core: manage enable GPIO list")
> ---
> FYI: this was developed and tested against a 3.14 kernel with
> backports; I've done basic boot testing against upstream and sanity
> checked the code but haven't done as extensive testing there.
> 
>  drivers/regulator/core.c | 20 ++++++++++++--------
>  1 file changed, 12 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
> index b899947..9daccbb 100644
> --- a/drivers/regulator/core.c
> +++ b/drivers/regulator/core.c
> @@ -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)

Your approach to check in _regulator_do_enable() is more generic though
since it covers future issues and not only regulator_suspend_finish()
but otoh it only cover the case for GPIO enabled regulators so you may
also check for other type of regulators using _regulator_is_enabled()?

I see that the check is already in _regulator_enable() so another option
is to call _regulator_enable() instead of _regulator_do_enable() in
regulator_suspend_finish().

Best regards,
Javier

[0]:
>From 71bb25eff5c2aac4a7b6878f205f3f8905c61363 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Date: Thu, 16 Oct 2014 01:31:20 +0100
Subject: [PATCH 1/1] regulator: Only enable disabled regulators on resume

After leaving from system wide suspend state, regulator_suspend_finish()
turn on regulators that might be turned off by regulator_suspend_prepare
but it tries to enable all regulators that have an enable count > 0 or
that were marked as "always-on" regardless if those were disabled or not.

Trying to enable an already enabled regulator may cause issues so is
better to skip enabling regulators that were not disabled before suspend.

Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
---
 drivers/regulator/core.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index f2452148c8da..4f1932aa10bc 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -3816,9 +3816,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;
-- 
2.1.3

  parent reply	other threads:[~2015-02-27 21:01 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-27 19:41 Doug Anderson
2015-02-27 20:08 ` Greg KH
2015-02-27 21:01 ` Javier Martinez Canillas [this message]
2015-03-02 18:57   ` Mark Brown
2015-03-02 20:21     ` Javier Martinez Canillas
2015-03-03 14:24       ` Mark Brown
2015-03-02 18:47 ` Mark Brown
2015-03-02 21:13   ` Doug Anderson
2015-03-03 14:23     ` Mark Brown
2015-03-03 23:21       ` Doug Anderson
2015-03-04 11:27         ` Mark Brown
2015-03-04 17:13           ` Doug Anderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=54F0DB23.3010203@collabora.co.uk \
    --to=javier.martinez@collabora.co.uk \
    --cc=axel.lin@ingics.com \
    --cc=broonie@kernel.org \
    --cc=dianders@chromium.org \
    --cc=dmitry.torokhov@gmail.com \
    --cc=lgirdwood@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=milo.kim@ti.com \
    --cc=olof@lixom.net \
    --cc=pstew@chromium.org \
    --cc=stable@vger.kernel.org \
    --subject='Re: [PATCH] regulator: core: Fix enable GPIO reference counting' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).