summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2019-02-21 10:46:32 -0500
committerKishon Vijay Abraham I <kishon@ti.com>2019-04-17 04:42:43 -0400
commit5311a7b89502592045812f97294f756b1fca132b (patch)
treecd68e9bdd9c2836fefa65bd151a96441006965ce
parent3cffa0818dc82a90d1a3df5ea7111999cb7b8646 (diff)
phy: tegra: xusb: Parse dual-role mode property
The device tree bindings document the "mode" property of "ports" subnodes, but the driver was not parsing the property. In preparation for adding role switching, parse the property at probe time. Based on work by JC Kuo <jckuo@nvidia.com>. Reviewed-by: JC Kuo <jckuo@nvidia.com> Signed-off-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
-rw-r--r--drivers/phy/tegra/xusb.c21
-rw-r--r--drivers/phy/tegra/xusb.h3
2 files changed, 24 insertions, 0 deletions
diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c
index e3bc60cfe6a1..57a2d08ef6da 100644
--- a/drivers/phy/tegra/xusb.c
+++ b/drivers/phy/tegra/xusb.c
@@ -546,13 +546,34 @@ static void tegra_xusb_port_unregister(struct tegra_xusb_port *port)
546 device_unregister(&port->dev); 546 device_unregister(&port->dev);
547} 547}
548 548
549static const char *const modes[] = {
550 [USB_DR_MODE_UNKNOWN] = "",
551 [USB_DR_MODE_HOST] = "host",
552 [USB_DR_MODE_PERIPHERAL] = "peripheral",
553 [USB_DR_MODE_OTG] = "otg",
554};
555
549static int tegra_xusb_usb2_port_parse_dt(struct tegra_xusb_usb2_port *usb2) 556static int tegra_xusb_usb2_port_parse_dt(struct tegra_xusb_usb2_port *usb2)
550{ 557{
551 struct tegra_xusb_port *port = &usb2->base; 558 struct tegra_xusb_port *port = &usb2->base;
552 struct device_node *np = port->dev.of_node; 559 struct device_node *np = port->dev.of_node;
560 const char *mode;
553 561
554 usb2->internal = of_property_read_bool(np, "nvidia,internal"); 562 usb2->internal = of_property_read_bool(np, "nvidia,internal");
555 563
564 if (!of_property_read_string(np, "mode", &mode)) {
565 int err = match_string(modes, ARRAY_SIZE(modes), mode);
566 if (err < 0) {
567 dev_err(&port->dev, "invalid value %s for \"mode\"\n",
568 mode);
569 usb2->mode = USB_DR_MODE_UNKNOWN;
570 } else {
571 usb2->mode = err;
572 }
573 } else {
574 usb2->mode = USB_DR_MODE_HOST;
575 }
576
556 usb2->supply = devm_regulator_get(&port->dev, "vbus"); 577 usb2->supply = devm_regulator_get(&port->dev, "vbus");
557 return PTR_ERR_OR_ZERO(usb2->supply); 578 return PTR_ERR_OR_ZERO(usb2->supply);
558} 579}
diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h
index b49dbc36efa3..bb60fc09c752 100644
--- a/drivers/phy/tegra/xusb.h
+++ b/drivers/phy/tegra/xusb.h
@@ -19,6 +19,8 @@
19#include <linux/mutex.h> 19#include <linux/mutex.h>
20#include <linux/workqueue.h> 20#include <linux/workqueue.h>
21 21
22#include <linux/usb/otg.h>
23
22/* legacy entry points for backwards-compatibility */ 24/* legacy entry points for backwards-compatibility */
23int tegra_xusb_padctl_legacy_probe(struct platform_device *pdev); 25int tegra_xusb_padctl_legacy_probe(struct platform_device *pdev);
24int tegra_xusb_padctl_legacy_remove(struct platform_device *pdev); 26int tegra_xusb_padctl_legacy_remove(struct platform_device *pdev);
@@ -271,6 +273,7 @@ struct tegra_xusb_usb2_port {
271 struct tegra_xusb_port base; 273 struct tegra_xusb_port base;
272 274
273 struct regulator *supply; 275 struct regulator *supply;
276 enum usb_dr_mode mode;
274 bool internal; 277 bool internal;
275}; 278};
276 279