public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] regulator: core: do not put managed GPIOd:s
@ 2018-11-22 16:04 Linus Walleij
  2018-11-22 17:34 ` Charles Keepax
  0 siblings, 1 reply; 2+ messages in thread
From: Linus Walleij @ 2018-11-22 16:04 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown
  Cc: linux-kernel, Linus Walleij, Marek Szyprowski, Charles Keepax

Some drivers have been converted to pass GPIO descriptors
rather than GPIO numbers to the regulator core. We should
not issue gpiod_put() on those descriptors, but rather
let the driver reference count it with devm_* if they so
desire.

Currently the regulator core issues gpiod_put() on all
descriptors as it assumes it was obtained with the
sequence gpio_request_one()/gpio_to_desc(), as
gpio_request_one() will be equivalent to gpiod_get().

We introduce a helper bool that deal with this situation
by making sure the core only issue gpiod_put() if the
GPIO was requested from within the core itself.

A subsequent patch set will delete legacy GPIO handling
and get rid of this ugliness, so it is a stepgap patch.

Fixes: e45e290a882e ("regulator: core: Support passing an initialized GPIO enable descriptor")
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Charles Keepax <ckeepax@opensource.cirrus.com>
Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
Reported-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
Mark: I will rebase my v7 series for removing legacy
GPIO on this if it solves Marek's probel, it can be applied
for fixes if need be but I don't know how big this problem is.
---
 drivers/regulator/core.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 03a03763457c..05bb2db6cff5 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -80,6 +80,7 @@ struct regulator_map {
 struct regulator_enable_gpio {
 	struct list_head list;
 	struct gpio_desc *gpiod;
+	bool gpiod_needs_put;
 	u32 enable_count;	/* a number of enabled shared GPIO */
 	u32 request_count;	/* a number of requested shared GPIO */
 	unsigned int ena_gpio_invert:1;
@@ -2247,6 +2248,8 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev,
 	}
 
 	pin->gpiod = gpiod;
+	if (!config->ena_gpiod)
+		pin->gpiod_needs_put = true;
 	pin->ena_gpio_invert = config->ena_gpio_invert;
 	list_add(&pin->list, &regulator_ena_gpio_list);
 
@@ -2268,7 +2271,8 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev)
 		if (pin->gpiod == rdev->ena_pin->gpiod) {
 			if (pin->request_count <= 1) {
 				pin->request_count = 0;
-				gpiod_put(pin->gpiod);
+				if (pin->gpiod_needs_put)
+					gpiod_put(pin->gpiod);
 				list_del(&pin->list);
 				kfree(pin);
 				rdev->ena_pin = NULL;
-- 
2.19.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2018-11-22 17:34 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-11-22 16:04 [PATCH] regulator: core: do not put managed GPIOd:s Linus Walleij
2018-11-22 17:34 ` Charles Keepax

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox