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