2018-06-19 15:12:57

by Charles Keepax

[permalink] [raw]
Subject: [PATCH v2] regulator: arizona-ldo1: Use correct device to get enable GPIO

Currently the enable GPIO is being looked up on the regulator
device itself but that does not have its own DT node, this causes
the lookup to fail and the regulator not to get its GPIO. The DT
node is shared across the whole MFD and as such the lookup needs
to happen on that parent device. Moving the lookup to the parent
device also means devres can no longer be used as the life time
would attach to the wrong device.

Additionally, the enable GPIO is active high so we should be passing
GPIOD_OUT_LOW to ensure the regulator starts in its off state allowing
the driver to enable it when it is ready.

Fixes: e1739e86f0cb ("regulator: arizona-ldo1: Look up a descriptor and pass to the core")
Reported-by: Matthias Reichl <[email protected]>
Signed-off-by: Charles Keepax <[email protected]>
---

Changes since v1:
- Pass GPIOD_OUT_LOW to gpiod_get_optional

Thanks,
Charles

drivers/regulator/arizona-ldo1.c | 27 ++++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c
index f6d6a4ad9e8a..e976d073f28d 100644
--- a/drivers/regulator/arizona-ldo1.c
+++ b/drivers/regulator/arizona-ldo1.c
@@ -36,6 +36,8 @@ struct arizona_ldo1 {

struct regulator_consumer_supply supply;
struct regulator_init_data init_data;
+
+ struct gpio_desc *ena_gpiod;
};

static int arizona_ldo1_hc_list_voltage(struct regulator_dev *rdev,
@@ -253,12 +255,17 @@ static int arizona_ldo1_common_init(struct platform_device *pdev,
}
}

- /* We assume that high output = regulator off */
- config.ena_gpiod = devm_gpiod_get_optional(&pdev->dev, "wlf,ldoena",
- GPIOD_OUT_HIGH);
+ /* We assume that high output = regulator off
+ * Don't use devm, since we need to get against the parent device
+ * so clean up would happen at the wrong time
+ */
+ config.ena_gpiod = gpiod_get_optional(parent_dev, "wlf,ldoena",
+ GPIOD_OUT_LOW);
if (IS_ERR(config.ena_gpiod))
return PTR_ERR(config.ena_gpiod);

+ ldo1->ena_gpiod = config.ena_gpiod;
+
if (pdata->init_data)
config.init_data = pdata->init_data;
else
@@ -276,6 +283,9 @@ static int arizona_ldo1_common_init(struct platform_device *pdev,
of_node_put(config.of_node);

if (IS_ERR(ldo1->regulator)) {
+ if (config.ena_gpiod)
+ gpiod_put(config.ena_gpiod);
+
ret = PTR_ERR(ldo1->regulator);
dev_err(&pdev->dev, "Failed to register LDO1 supply: %d\n",
ret);
@@ -334,8 +344,19 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
return ret;
}

+static int arizona_ldo1_remove(struct platform_device *pdev)
+{
+ struct arizona_ldo1 *ldo1 = platform_get_drvdata(pdev);
+
+ if (ldo1->ena_gpiod)
+ gpiod_put(ldo1->ena_gpiod);
+
+ return 0;
+}
+
static struct platform_driver arizona_ldo1_driver = {
.probe = arizona_ldo1_probe,
+ .remove = arizona_ldo1_remove,
.driver = {
.name = "arizona-ldo1",
},
--
2.11.0



2018-06-19 15:26:06

by Mark Brown

[permalink] [raw]
Subject: Applied "regulator: arizona-ldo1: Use correct device to get enable GPIO" to the regulator tree

The patch

regulator: arizona-ldo1: Use correct device to get enable GPIO

has been applied to the regulator tree at

https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

From a9191579ba1086d91842199263e6fe6bb5eec1ba Mon Sep 17 00:00:00 2001
From: Charles Keepax <[email protected]>
Date: Tue, 19 Jun 2018 16:10:00 +0100
Subject: [PATCH] regulator: arizona-ldo1: Use correct device to get enable
GPIO

Currently the enable GPIO is being looked up on the regulator
device itself but that does not have its own DT node, this causes
the lookup to fail and the regulator not to get its GPIO. The DT
node is shared across the whole MFD and as such the lookup needs
to happen on that parent device. Moving the lookup to the parent
device also means devres can no longer be used as the life time
would attach to the wrong device.

Additionally, the enable GPIO is active high so we should be passing
GPIOD_OUT_LOW to ensure the regulator starts in its off state allowing
the driver to enable it when it is ready.

Fixes: e1739e86f0cb ("regulator: arizona-ldo1: Look up a descriptor and pass to the core")
Reported-by: Matthias Reichl <[email protected]>
Signed-off-by: Charles Keepax <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
---
drivers/regulator/arizona-ldo1.c | 27 ++++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c
index f6d6a4ad9e8a..e976d073f28d 100644
--- a/drivers/regulator/arizona-ldo1.c
+++ b/drivers/regulator/arizona-ldo1.c
@@ -36,6 +36,8 @@ struct arizona_ldo1 {

struct regulator_consumer_supply supply;
struct regulator_init_data init_data;
+
+ struct gpio_desc *ena_gpiod;
};

static int arizona_ldo1_hc_list_voltage(struct regulator_dev *rdev,
@@ -253,12 +255,17 @@ static int arizona_ldo1_common_init(struct platform_device *pdev,
}
}

- /* We assume that high output = regulator off */
- config.ena_gpiod = devm_gpiod_get_optional(&pdev->dev, "wlf,ldoena",
- GPIOD_OUT_HIGH);
+ /* We assume that high output = regulator off
+ * Don't use devm, since we need to get against the parent device
+ * so clean up would happen at the wrong time
+ */
+ config.ena_gpiod = gpiod_get_optional(parent_dev, "wlf,ldoena",
+ GPIOD_OUT_LOW);
if (IS_ERR(config.ena_gpiod))
return PTR_ERR(config.ena_gpiod);

+ ldo1->ena_gpiod = config.ena_gpiod;
+
if (pdata->init_data)
config.init_data = pdata->init_data;
else
@@ -276,6 +283,9 @@ static int arizona_ldo1_common_init(struct platform_device *pdev,
of_node_put(config.of_node);

if (IS_ERR(ldo1->regulator)) {
+ if (config.ena_gpiod)
+ gpiod_put(config.ena_gpiod);
+
ret = PTR_ERR(ldo1->regulator);
dev_err(&pdev->dev, "Failed to register LDO1 supply: %d\n",
ret);
@@ -334,8 +344,19 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
return ret;
}

+static int arizona_ldo1_remove(struct platform_device *pdev)
+{
+ struct arizona_ldo1 *ldo1 = platform_get_drvdata(pdev);
+
+ if (ldo1->ena_gpiod)
+ gpiod_put(ldo1->ena_gpiod);
+
+ return 0;
+}
+
static struct platform_driver arizona_ldo1_driver = {
.probe = arizona_ldo1_probe,
+ .remove = arizona_ldo1_remove,
.driver = {
.name = "arizona-ldo1",
},
--
2.17.1


2018-06-19 20:47:42

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v2] regulator: arizona-ldo1: Use correct device to get enable GPIO

On Tue, Jun 19, 2018 at 6:10 PM, Charles Keepax
<[email protected]> wrote:
> Currently the enable GPIO is being looked up on the regulator
> device itself but that does not have its own DT node, this causes
> the lookup to fail and the regulator not to get its GPIO. The DT
> node is shared across the whole MFD and as such the lookup needs
> to happen on that parent device.

> Moving the lookup to the parent
> device also means devres can no longer be used as the life time
> would attach to the wrong device.

This part I didn't get.
Why we can't use devm_...(parent_dev, ...) instead?

>
> Additionally, the enable GPIO is active high so we should be passing
> GPIOD_OUT_LOW to ensure the regulator starts in its off state allowing
> the driver to enable it when it is ready.

--
With Best Regards,
Andy Shevchenko

2018-06-20 09:44:49

by Charles Keepax

[permalink] [raw]
Subject: Re: [PATCH v2] regulator: arizona-ldo1: Use correct device to get enable GPIO

On Tue, Jun 19, 2018 at 11:46:36PM +0300, Andy Shevchenko wrote:
> On Tue, Jun 19, 2018 at 6:10 PM, Charles Keepax
> <[email protected]> wrote:
> > Currently the enable GPIO is being looked up on the regulator
> > device itself but that does not have its own DT node, this causes
> > the lookup to fail and the regulator not to get its GPIO. The DT
> > node is shared across the whole MFD and as such the lookup needs
> > to happen on that parent device.
>
> > Moving the lookup to the parent
> > device also means devres can no longer be used as the life time
> > would attach to the wrong device.
>
> This part I didn't get.
> Why we can't use devm_...(parent_dev, ...) instead?
>

Because it is possible to unbind the regulator driver itself,
which would leave the GPIO as acquired, since the MFD is never
unbound. Then when you rebind the regulator the GPIO would
already be held by the previous instantiation of the regulator
driver.

Thanks,
Charles

2018-06-29 12:32:42

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH v2] regulator: arizona-ldo1: Use correct device to get enable GPIO

On Tue, Jun 19, 2018 at 5:10 PM Charles Keepax
<[email protected]> wrote:

> Currently the enable GPIO is being looked up on the regulator
> device itself but that does not have its own DT node, this causes
> the lookup to fail and the regulator not to get its GPIO. The DT
> node is shared across the whole MFD and as such the lookup needs
> to happen on that parent device. Moving the lookup to the parent
> device also means devres can no longer be used as the life time
> would attach to the wrong device.
>
> Additionally, the enable GPIO is active high so we should be passing
> GPIOD_OUT_LOW to ensure the regulator starts in its off state allowing
> the driver to enable it when it is ready.
>
> Fixes: e1739e86f0cb ("regulator: arizona-ldo1: Look up a descriptor and pass to the core")
> Reported-by: Matthias Reichl <[email protected]>
> Signed-off-by: Charles Keepax <[email protected]>
> ---
>
> Changes since v1:
> - Pass GPIOD_OUT_LOW to gpiod_get_optional

Nice, thanks for fixing this!
Sorry for screwing it up :(

I wish I could be more careful, but without access to the
hardware it is sometimes pretty tricky not to break things
by mistake.

Reviewed-by: Linus Walleij <[email protected]>

Yours,
Linus Walleij