Some USB phy drivers have different handling for the controller in each
dr_mode. But the phy driver does not have visibility to the dr_mode of
the controller.

This adds an api to return the dr_mode of the controller which
associates the given phy node.

Signed-off-by: Bin Liu <b-...@ti.com>
---
v2: move drivers/usb/phy/phy-am335x.c changes into patch 3/3.

 drivers/usb/common/common.c | 27 +++++++++++++++++++++++++++
 include/linux/usb/of.h      |  6 ++++++
 2 files changed, 33 insertions(+)

diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c
index b530fd4..3c7dee8 100644
--- a/drivers/usb/common/common.c
+++ b/drivers/usb/common/common.c
@@ -114,6 +114,33 @@ enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np)
 EXPORT_SYMBOL_GPL(of_usb_get_dr_mode);
 
 /**
+ * of_usb_get_dr_mode_by_phy - Get dual role mode for the controller device
+ * which is associated with the given phy device_node
+ * @np:        Pointer to the given phy device_node
+ *
+ * In dts a usb controller associates with a phy device.  The function gets
+ * the string from property 'dr_mode' of the controller associated with the
+ * given phy device node, and returns the correspondig enum usb_dr_mode.
+ */
+enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np)
+{
+       struct device_node *controller;
+       struct device_node *phy;
+
+       controller = of_get_parent(phy_np);
+       do {
+               controller = of_find_node_with_property(controller, "phys");
+               if (!controller)
+                       return USB_DR_MODE_UNKNOWN;
+
+               phy = of_parse_phandle(controller, "phys", 0);
+       } while (phy != phy_np);
+
+       return of_usb_get_dr_mode(controller);
+}
+EXPORT_SYMBOL_GPL(of_usb_get_dr_mode_by_phy);
+
+/**
  * of_usb_get_maximum_speed - Get maximum requested speed for a given USB
  * controller.
  * @np: Pointer to the given device_node
diff --git a/include/linux/usb/of.h b/include/linux/usb/of.h
index cfe0528..14ebd5a 100644
--- a/include/linux/usb/of.h
+++ b/include/linux/usb/of.h
@@ -13,6 +13,7 @@
 
 #if IS_ENABLED(CONFIG_OF)
 enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np);
+enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np);
 enum usb_device_speed of_usb_get_maximum_speed(struct device_node *np);
 bool of_usb_host_tpl_support(struct device_node *np);
 #else
@@ -21,6 +22,11 @@ static inline enum usb_dr_mode of_usb_get_dr_mode(struct 
device_node *np)
        return USB_DR_MODE_UNKNOWN;
 }
 
+enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np)
+{
+       return USB_DR_MODE_UNKNOWN;
+}
+
 static inline enum usb_device_speed
 of_usb_get_maximum_speed(struct device_node *np)
 {
-- 
1.8.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to