linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/1] gpio: pca954x: Add vcc regulator and enable it
@ 2016-07-29  3:39 Phil Reid
  2016-07-29  3:39 ` [PATCH v2 1/1] " Phil Reid
  0 siblings, 1 reply; 3+ messages in thread
From: Phil Reid @ 2016-07-29  3:39 UTC (permalink / raw)
  To: linus.walleij, gnurou, linux-gpio; +Cc: Phil Reid

I have a system where the gpio device is attached to a gpio controlled
regulator. If not enabled prior to device probe it fails to load the
driver. Marking the regulator as always on does not always work as the
probe order changes and it's suspectible to race conditions.

I'm not aware of another way around this problem.

Changes from v1:
- Use devm_regulator_get instead of devm_regulator_get_optional.
  Core returns a dummy regultor that can be used if i doesn't exist.
  Simplify inital error handling.
- Add regulator_disable to probe error path.
- Add regulator_disable to remove.


Phil Reid (1):
  gpio: pca954x: Add vcc regulator and enable it

 drivers/gpio/gpio-pca953x.c | 41 ++++++++++++++++++++++++++++++++---------
 1 file changed, 32 insertions(+), 9 deletions(-)

-- 
1.8.3.1


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

* [PATCH v2 1/1] gpio: pca954x: Add vcc regulator and enable it
  2016-07-29  3:39 [PATCH v2 0/1] gpio: pca954x: Add vcc regulator and enable it Phil Reid
@ 2016-07-29  3:39 ` Phil Reid
  2016-08-11  8:14   ` Linus Walleij
  0 siblings, 1 reply; 3+ messages in thread
From: Phil Reid @ 2016-07-29  3:39 UTC (permalink / raw)
  To: linus.walleij, gnurou, linux-gpio; +Cc: Phil Reid

Some i2c gpio devices are connected to a switchable power supply
which needs to be enabled prior to probing the device. This patch
allows the drive to enable the devices vcc regulator prior to probing.

Signed-off-by: Phil Reid <preid@electromag.com.au>
---
 drivers/gpio/gpio-pca953x.c | 41 ++++++++++++++++++++++++++++++++---------
 1 file changed, 32 insertions(+), 9 deletions(-)

diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index 5e3be32..9da8757 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -21,6 +21,7 @@
 #include <asm/unaligned.h>
 #include <linux/of_platform.h>
 #include <linux/acpi.h>
+#include <linux/regulator/consumer.h>
 
 #define PCA953X_INPUT		0
 #define PCA953X_OUTPUT		1
@@ -111,6 +112,7 @@ struct pca953x_chip {
 	const char *const *names;
 	int	chip_type;
 	unsigned long driver_data;
+	struct regulator *regulator;
 };
 
 static int pca953x_read_single(struct pca953x_chip *chip, int reg, u32 *val,
@@ -744,6 +746,7 @@ static int pca953x_probe(struct i2c_client *client,
 	int irq_base = 0;
 	int ret;
 	u32 invert = 0;
+	struct regulator *reg;
 
 	chip = devm_kzalloc(&client->dev,
 			sizeof(struct pca953x_chip), GFP_KERNEL);
@@ -763,6 +766,20 @@ static int pca953x_probe(struct i2c_client *client,
 
 	chip->client = client;
 
+	reg = devm_regulator_get(&client->dev, "vcc");
+	if (IS_ERR(reg)) {
+		ret = PTR_ERR(reg);
+		if (ret != -EPROBE_DEFER)
+			dev_err(&client->dev, "reg get err: %d\n", ret);
+		return ret;
+	}
+	ret = regulator_enable(reg);
+	if (ret) {
+		dev_err(&client->dev, "reg en err: %d\n", ret);
+		return ret;
+	}
+	chip->regulator = reg;
+
 	if (id) {
 		chip->driver_data = id->driver_data;
 	} else {
@@ -774,8 +791,10 @@ static int pca953x_probe(struct i2c_client *client,
 			chip->driver_data = (int)(uintptr_t)match->data;
 		} else {
 			id = acpi_match_device(pca953x_acpi_ids, &client->dev);
-			if (!id)
-				return -ENODEV;
+			if (!id) {
+				ret = -ENODEV;
+				goto err_exit;
+			}
 
 			chip->driver_data = id->driver_data;
 		}
@@ -795,15 +814,15 @@ static int pca953x_probe(struct i2c_client *client,
 	else
 		ret = device_pca957x_init(chip, invert);
 	if (ret)
-		return ret;
+		goto err_exit;
 
 	ret = devm_gpiochip_add_data(&client->dev, &chip->gpio_chip, chip);
 	if (ret)
-		return ret;
+		goto err_exit;
 
 	ret = pca953x_irq_setup(chip, irq_base);
 	if (ret)
-		return ret;
+		goto err_exit;
 
 	if (pdata && pdata->setup) {
 		ret = pdata->setup(client, chip->gpio_chip.base,
@@ -814,6 +833,10 @@ static int pca953x_probe(struct i2c_client *client,
 
 	i2c_set_clientdata(client, chip);
 	return 0;
+
+err_exit:
+	regulator_disable(chip->regulator);
+	return ret;
 }
 
 static int pca953x_remove(struct i2c_client *client)
@@ -825,14 +848,14 @@ static int pca953x_remove(struct i2c_client *client)
 	if (pdata && pdata->teardown) {
 		ret = pdata->teardown(client, chip->gpio_chip.base,
 				chip->gpio_chip.ngpio, pdata->context);
-		if (ret < 0) {
+		if (ret < 0)
 			dev_err(&client->dev, "%s failed, %d\n",
 					"teardown", ret);
-			return ret;
-		}
 	}
 
-	return 0;
+	regulator_disable(chip->regulator);
+
+	return ret;
 }
 
 /* convenience to stop overlong match-table lines */
-- 
1.8.3.1


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

* Re: [PATCH v2 1/1] gpio: pca954x: Add vcc regulator and enable it
  2016-07-29  3:39 ` [PATCH v2 1/1] " Phil Reid
@ 2016-08-11  8:14   ` Linus Walleij
  0 siblings, 0 replies; 3+ messages in thread
From: Linus Walleij @ 2016-08-11  8:14 UTC (permalink / raw)
  To: Phil Reid; +Cc: Alexandre Courbot, linux-gpio@vger.kernel.org

On Fri, Jul 29, 2016 at 5:39 AM, Phil Reid <preid@electromag.com.au> wrote:

> Some i2c gpio devices are connected to a switchable power supply
> which needs to be enabled prior to probing the device. This patch
> allows the drive to enable the devices vcc regulator prior to probing.
>
> Signed-off-by: Phil Reid <preid@electromag.com.au>

Patch applied!

Yours,
Linus Walleij

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

end of thread, other threads:[~2016-08-11  8:14 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-29  3:39 [PATCH v2 0/1] gpio: pca954x: Add vcc regulator and enable it Phil Reid
2016-07-29  3:39 ` [PATCH v2 1/1] " Phil Reid
2016-08-11  8:14   ` Linus Walleij

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).