Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

usb: fusb302: Convert to use GPIO descriptors

This converts the FUSB302 driver to use GPIO descriptors.
The conversion to descriptors per se is pretty straight-forward.

In the process I discovered that:

1. The driver uses a completely undocumented device tree binding
for the interrupt GPIO line, "fcs,int_n". Ooops.

2. The undocumented binding, presumably since it has not seen
review, is just "fcs,int_n", lacking the compulsory "-gpios"
suffix and also something that is not a good name because
the "_n" implies the line is inverted which is something we
handle with flags in the device tree. Ooops.

3. Possibly the driver should not be requesting the line as a
GPIO and request the corresponding interrupt line by open
coding, the GPIO chip is very likely doubleing as an IRQ
controller and can probably provide an interrupt directly
for this line with interrupts-extended = <&gpio0 ...>;

4. Possibly the IRQ should just be tagged on the I2C client node
in the device tree like apparently ACPI does, as it overrides
this IRQ with client->irq if that exists.

But now it is too late to do much about that and as I can see
this is used like this in the Pinebook which is a shipping product
so let'a just contain the mess and move on.

The property currently appears in:
arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts

Create a quirk in the GPIO OF library to allow this property
specifically to be specified without the "-gpios" suffix, we have
other such bindings already.

Cc: Tobias Schramm <t.schramm@manjaro.org>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Cc: Yueyao Zhu <yueyao@google.com>
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: devicetree@vger.kernel.org
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20200415192448.305257-1-linus.walleij@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Linus Walleij and committed by
Greg Kroah-Hartman
6e24826d eed6ed6e

+30 -23
+21
drivers/gpio/gpiolib-of.c
··· 460 460 return of_get_named_gpiod_flags(dev->of_node, con_id, 0, of_flags); 461 461 } 462 462 463 + static struct gpio_desc *of_find_usb_gpio(struct device *dev, 464 + const char *con_id, 465 + enum of_gpio_flags *of_flags) 466 + { 467 + /* 468 + * Currently this USB quirk is only for the Fairchild FUSB302 host which is using 469 + * an undocumented DT GPIO line named "fcs,int_n" without the compulsory "-gpios" 470 + * suffix. 471 + */ 472 + if (!IS_ENABLED(CONFIG_TYPEC_FUSB302)) 473 + return ERR_PTR(-ENOENT); 474 + 475 + if (!con_id || strcmp(con_id, "fcs,int_n")) 476 + return ERR_PTR(-ENOENT); 477 + 478 + return of_get_named_gpiod_flags(dev->of_node, con_id, 0, of_flags); 479 + } 480 + 463 481 struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, 464 482 unsigned int idx, unsigned long *flags) 465 483 { ··· 521 503 522 504 if (PTR_ERR(desc) == -ENOENT) 523 505 desc = of_find_arizona_gpio(dev, con_id, &of_flags); 506 + 507 + if (PTR_ERR(desc) == -ENOENT) 508 + desc = of_find_usb_gpio(dev, con_id, &of_flags); 524 509 525 510 if (IS_ERR(desc)) 526 511 return desc;
+9 -23
drivers/usb/typec/tcpm/fusb302.c
··· 9 9 #include <linux/delay.h> 10 10 #include <linux/errno.h> 11 11 #include <linux/extcon.h> 12 - #include <linux/gpio.h> 12 + #include <linux/gpio/consumer.h> 13 13 #include <linux/i2c.h> 14 14 #include <linux/interrupt.h> 15 15 #include <linux/kernel.h> 16 16 #include <linux/module.h> 17 17 #include <linux/mutex.h> 18 18 #include <linux/of_device.h> 19 - #include <linux/of_gpio.h> 20 19 #include <linux/pinctrl/consumer.h> 21 20 #include <linux/proc_fs.h> 22 21 #include <linux/regulator/consumer.h> ··· 82 83 struct work_struct irq_work; 83 84 bool irq_suspended; 84 85 bool irq_while_suspended; 85 - int gpio_int_n; 86 + struct gpio_desc *gpio_int_n; 86 87 int gpio_int_n_irq; 87 88 struct extcon_dev *extcon; 88 89 ··· 1617 1618 1618 1619 static int init_gpio(struct fusb302_chip *chip) 1619 1620 { 1620 - struct device_node *node; 1621 + struct device *dev = chip->dev; 1621 1622 int ret = 0; 1622 1623 1623 - node = chip->dev->of_node; 1624 - chip->gpio_int_n = of_get_named_gpio(node, "fcs,int_n", 0); 1625 - if (!gpio_is_valid(chip->gpio_int_n)) { 1626 - ret = chip->gpio_int_n; 1627 - dev_err(chip->dev, "cannot get named GPIO Int_N, ret=%d", ret); 1628 - return ret; 1624 + chip->gpio_int_n = devm_gpiod_get(dev, "fcs,int_n", GPIOD_IN); 1625 + if (IS_ERR(chip->gpio_int_n)) { 1626 + dev_err(dev, "failed to request gpio_int_n\n"); 1627 + return PTR_ERR(chip->gpio_int_n); 1629 1628 } 1630 - ret = devm_gpio_request(chip->dev, chip->gpio_int_n, "fcs,int_n"); 1629 + ret = gpiod_to_irq(chip->gpio_int_n); 1631 1630 if (ret < 0) { 1632 - dev_err(chip->dev, "cannot request GPIO Int_N, ret=%d", ret); 1633 - return ret; 1634 - } 1635 - ret = gpio_direction_input(chip->gpio_int_n); 1636 - if (ret < 0) { 1637 - dev_err(chip->dev, 1638 - "cannot set GPIO Int_N to input, ret=%d", ret); 1639 - return ret; 1640 - } 1641 - ret = gpio_to_irq(chip->gpio_int_n); 1642 - if (ret < 0) { 1643 - dev_err(chip->dev, 1631 + dev_err(dev, 1644 1632 "cannot request IRQ for GPIO Int_N, ret=%d", ret); 1645 1633 return ret; 1646 1634 }