59aac79
From 2c36867719d93db8d7f365310587578ab980762c Mon Sep 17 00:00:00 2001
71893eb
From: Linus Walleij <linus.walleij@linaro.org>
59aac79
Date: Wed, 15 Apr 2020 21:24:48 +0200
71893eb
Subject: [PATCH] usb: fusb302: Convert to use GPIO descriptors
71893eb
71893eb
This converts the FUSB302 driver to use GPIO descriptors.
71893eb
The conversion to descriptors per se is pretty straight-forward.
71893eb
71893eb
In the process I discovered that:
71893eb
71893eb
1. The driver uses a completely undocumented device tree binding
71893eb
   for the interrupt GPIO line, "fcs,int_n". Ooops.
71893eb
71893eb
2. The undocumented binding, presumably since it has not seen
71893eb
   review, is just "fcs,int_n", lacking the compulsory "-gpios"
71893eb
   suffix and also something that is not a good name because
71893eb
   the "_n" implies the line is inverted which is something we
71893eb
   handle with flags in the device tree. Ooops.
71893eb
71893eb
3. Possibly the driver should not be requesting the line as a
71893eb
   GPIO and request the corresponding interrupt line by open
71893eb
   coding, the GPIO chip is very likely doubleing as an IRQ
71893eb
   controller and can probably provide an interrupt directly
71893eb
   for this line with interrupts-extended = <&gpio0 ...>;
71893eb
71893eb
4. Possibly the IRQ should just be tagged on the I2C client node
71893eb
   in the device tree like apparently ACPI does, as it overrides
71893eb
   this IRQ with client->irq if that exists.
71893eb
71893eb
But now it is too late to do much about that and as I can see
71893eb
this is used like this in the Pinebook which is a shipping product
71893eb
so let'a just contain the mess and move on.
71893eb
71893eb
The property currently appears in:
71893eb
arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
71893eb
71893eb
Create a quirk in the GPIO OF library to allow this property
71893eb
specifically to be specified without the "-gpios" suffix, we have
71893eb
other such bindings already.
71893eb
59aac79
Cc: Tobias Schramm <t.schramm@manjaro.org>
59aac79
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
59aac79
Cc: Yueyao Zhu <yueyao@google.com>
59aac79
Cc: Guenter Roeck <linux@roeck-us.net>
59aac79
Cc: devicetree@vger.kernel.org
71893eb
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
59aac79
Link: https://lore.kernel.org/r/20200415192448.305257-1-linus.walleij@linaro.org
59aac79
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
71893eb
---
71893eb
 drivers/gpio/gpiolib-of.c        | 21 +++++++++++++++++++++
71893eb
 drivers/usb/typec/tcpm/fusb302.c | 32 +++++++++-----------------------
71893eb
 2 files changed, 30 insertions(+), 23 deletions(-)
71893eb
71893eb
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
59aac79
index ccc449df3792a..20c2c428168e4 100644
71893eb
--- a/drivers/gpio/gpiolib-of.c
71893eb
+++ b/drivers/gpio/gpiolib-of.c
71893eb
@@ -460,6 +460,24 @@ static struct gpio_desc *of_find_arizona_gpio(struct device *dev,
71893eb
 	return of_get_named_gpiod_flags(dev->of_node, con_id, 0, of_flags);
71893eb
 }
71893eb
 
71893eb
+static struct gpio_desc *of_find_usb_gpio(struct device *dev,
71893eb
+					  const char *con_id,
71893eb
+					  enum of_gpio_flags *of_flags)
71893eb
+{
71893eb
+	/*
71893eb
+	 * Currently this USB quirk is only for the Fairchild FUSB302 host which is using
71893eb
+	 * an undocumented DT GPIO line named "fcs,int_n" without the compulsory "-gpios"
71893eb
+	 * suffix.
71893eb
+	 */
71893eb
+	if (!IS_ENABLED(CONFIG_TYPEC_FUSB302))
71893eb
+		return ERR_PTR(-ENOENT);
71893eb
+
71893eb
+	if (!con_id || strcmp(con_id, "fcs,int_n"))
71893eb
+		return ERR_PTR(-ENOENT);
71893eb
+
71893eb
+	return of_get_named_gpiod_flags(dev->of_node, con_id, 0, of_flags);
71893eb
+}
71893eb
+
71893eb
 struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
71893eb
 			       unsigned int idx, unsigned long *flags)
71893eb
 {
71893eb
@@ -504,6 +522,9 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
71893eb
 	if (PTR_ERR(desc) == -ENOENT)
71893eb
 		desc = of_find_arizona_gpio(dev, con_id, &of_flags);
71893eb
 
71893eb
+	if (PTR_ERR(desc) == -ENOENT)
71893eb
+		desc = of_find_usb_gpio(dev, con_id, &of_flags);
71893eb
+
71893eb
 	if (IS_ERR(desc))
71893eb
 		return desc;
71893eb
 
71893eb
diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c
59aac79
index b498960ff72b5..b28facece43c4 100644
71893eb
--- a/drivers/usb/typec/tcpm/fusb302.c
71893eb
+++ b/drivers/usb/typec/tcpm/fusb302.c
71893eb
@@ -9,14 +9,13 @@
71893eb
 #include <linux/delay.h>
71893eb
 #include <linux/errno.h>
71893eb
 #include <linux/extcon.h>
71893eb
-#include <linux/gpio.h>
71893eb
+#include <linux/gpio/consumer.h>
71893eb
 #include <linux/i2c.h>
71893eb
 #include <linux/interrupt.h>
71893eb
 #include <linux/kernel.h>
71893eb
 #include <linux/module.h>
71893eb
 #include <linux/mutex.h>
71893eb
 #include <linux/of_device.h>
71893eb
-#include <linux/of_gpio.h>
71893eb
 #include <linux/pinctrl/consumer.h>
71893eb
 #include <linux/proc_fs.h>
71893eb
 #include <linux/regulator/consumer.h>
71893eb
@@ -83,7 +82,7 @@ struct fusb302_chip {
71893eb
 	struct work_struct irq_work;
71893eb
 	bool irq_suspended;
71893eb
 	bool irq_while_suspended;
71893eb
-	int gpio_int_n;
71893eb
+	struct gpio_desc *gpio_int_n;
71893eb
 	int gpio_int_n_irq;
71893eb
 	struct extcon_dev *extcon;
71893eb
 
71893eb
@@ -1618,30 +1617,17 @@ static void fusb302_irq_work(struct work_struct *work)
71893eb
 
71893eb
 static int init_gpio(struct fusb302_chip *chip)
71893eb
 {
71893eb
-	struct device_node *node;
71893eb
+	struct device *dev = chip->dev;
71893eb
 	int ret = 0;
71893eb
 
71893eb
-	node = chip->dev->of_node;
71893eb
-	chip->gpio_int_n = of_get_named_gpio(node, "fcs,int_n", 0);
71893eb
-	if (!gpio_is_valid(chip->gpio_int_n)) {
71893eb
-		ret = chip->gpio_int_n;
71893eb
-		dev_err(chip->dev, "cannot get named GPIO Int_N, ret=%d", ret);
71893eb
-		return ret;
71893eb
-	}
71893eb
-	ret = devm_gpio_request(chip->dev, chip->gpio_int_n, "fcs,int_n");
71893eb
-	if (ret < 0) {
71893eb
-		dev_err(chip->dev, "cannot request GPIO Int_N, ret=%d", ret);
71893eb
-		return ret;
71893eb
-	}
71893eb
-	ret = gpio_direction_input(chip->gpio_int_n);
71893eb
-	if (ret < 0) {
71893eb
-		dev_err(chip->dev,
71893eb
-			"cannot set GPIO Int_N to input, ret=%d", ret);
71893eb
-		return ret;
71893eb
+	chip->gpio_int_n = devm_gpiod_get(dev, "fcs,int_n", GPIOD_IN);
71893eb
+	if (IS_ERR(chip->gpio_int_n)) {
71893eb
+		dev_err(dev, "failed to request gpio_int_n\n");
71893eb
+		return PTR_ERR(chip->gpio_int_n);
71893eb
 	}
71893eb
-	ret = gpio_to_irq(chip->gpio_int_n);
71893eb
+	ret = gpiod_to_irq(chip->gpio_int_n);
71893eb
 	if (ret < 0) {
71893eb
-		dev_err(chip->dev,
71893eb
+		dev_err(dev,
71893eb
 			"cannot request IRQ for GPIO Int_N, ret=%d", ret);
71893eb
 		return ret;
71893eb
 	}
71893eb
-- 
59aac79
2.26.2
71893eb