summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCharles Keepax <ckeepax@opensource.cirrus.com>2018-06-19 17:10:00 +0200
committerMark Brown <broonie@kernel.org>2018-06-19 17:12:01 +0200
commita9191579ba1086d91842199263e6fe6bb5eec1ba (patch)
treece16f61a9e60460a84b13ff630030ca09fc8bb00
parentMerge branch 'regulator-4.17' into regulator-4.18 merge window (diff)
downloadlinux-a9191579ba1086d91842199263e6fe6bb5eec1ba.tar.xz
linux-a9191579ba1086d91842199263e6fe6bb5eec1ba.zip
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 <hias@horus.com> Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/regulator/arizona-ldo1.c27
1 files 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",
},