linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Eddie James <eajames@linux.ibm.com>
To: linux-i2c@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, peda@axentia.se, joel@jms.id.au,
	Eddie James <eajames@linux.ibm.com>
Subject: [PATCH] i2c: mux: pca954x: Support multiple devices on a single reset line
Date: Wed,  5 May 2021 16:59:18 -0500	[thread overview]
Message-ID: <20210505215918.45720-1-eajames@linux.ibm.com> (raw)

Some systems connect several PCA954x devices to a single reset GPIO. For
these devices to get out of reset and probe successfully, only the first
device probed should change the GPIO. Add this functionality by checking
for EBUSY when getting the GPIO fails. Then, retry getting the GPIO with
the non-exclusive flag and wait for the reset line to drop. This prevents
the later probes from proceding while the device is still reset.

Signed-off-by: Eddie James <eajames@linux.ibm.com>
---
 drivers/i2c/muxes/i2c-mux-pca954x.c | 43 +++++++++++++++++++++++++++--
 1 file changed, 40 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index 4ad665757dd8..840667a82f71 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -39,6 +39,7 @@
 #include <linux/i2c-mux.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/ktime.h>
 #include <linux/module.h>
 #include <linux/pm.h>
 #include <linux/property.h>
@@ -414,6 +415,8 @@ static int pca954x_init(struct i2c_client *client, struct pca954x *data)
 static int pca954x_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
+	enum gpiod_flags flags = GPIOD_OUT_HIGH;
+	const char *reset_gpio_name = "reset";
 	struct i2c_adapter *adap = client->adapter;
 	struct device *dev = &client->dev;
 	struct gpio_desc *gpio;
@@ -435,9 +438,43 @@ static int pca954x_probe(struct i2c_client *client,
 	data->client = client;
 
 	/* Reset the mux if a reset GPIO is specified. */
-	gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
-	if (IS_ERR(gpio))
-		return PTR_ERR(gpio);
+	gpio = devm_gpiod_get_optional(dev, reset_gpio_name, flags);
+	if (IS_ERR(gpio)) {
+		ret = PTR_ERR(gpio);
+		/*
+		 * In the case that multiple muxes share a single reset line,
+		 * only one should toggle the reset. The other muxes should
+		 * continue probing, waiting for the reset line to drop.
+		 */
+		if (ret == -EBUSY) {
+			ktime_t exp;
+
+			flags |= GPIOD_FLAGS_BIT_NONEXCLUSIVE;
+			gpio = gpiod_get(dev, reset_gpio_name, flags);
+			if (IS_ERR(gpio))
+				return PTR_ERR(gpio);
+
+			exp = ktime_add_us(ktime_get(), 1000);
+			do {
+				ret = gpiod_get_value_cansleep(gpio);
+				if (ret <= 0)
+					break;
+				usleep_range(5, 50);
+			} while (ktime_before(ktime_get(), exp));
+
+			gpiod_put(gpio);
+			if (ret) {
+				if (ret > 0)
+					ret = -ETIMEDOUT;
+
+				return ret;
+			}
+
+			gpio = NULL;
+		} else {
+			return ret;
+		}
+	}
 	if (gpio) {
 		udelay(1);
 		gpiod_set_value_cansleep(gpio, 0);
-- 
2.27.0


             reply	other threads:[~2021-05-05 21:59 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-05 21:59 Eddie James [this message]
2021-05-06 22:08 ` [PATCH] i2c: mux: pca954x: Support multiple devices on a single reset line Peter Rosin
2021-07-27 15:59   ` Eddie James

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=20210505215918.45720-1-eajames@linux.ibm.com \
    --to=eajames@linux.ibm.com \
    --cc=joel@jms.id.au \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=peda@axentia.se \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).