Re: [PATCH v5] usb: of: add an api to get dr_mode by the phy node

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 11/20/2015 03:24 PM, John Youn wrote:
On 11/20/2015 1:19 PM, John Youn wrote:
On 11/3/2015 9:49 AM, Bin Liu wrote:
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-liu@xxxxxx>
---
v5: - to simplify the code, add usb_get_dr_mode_from_string() to query
       dr_mode from string

v4: - iterating all phy nodes in the associated controller
     - add of_node_put() to decrement refcount

v3: search controller node from dt root, as the phy and controller nodes
     might not have the same parent.

v2: move drivers/usb/phy/phy-am335x.c changes into patch 3/3.

  drivers/usb/common/common.c | 60 ++++++++++++++++++++++++++++++++++++++++-----
  include/linux/usb/of.h      |  5 ++++
  2 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c
index 673d530..a11bb15 100644
--- a/drivers/usb/common/common.c
+++ b/drivers/usb/common/common.c
@@ -17,6 +17,7 @@
  #include <linux/usb/ch9.h>
  #include <linux/usb/of.h>
  #include <linux/usb/otg.h>
+#include <linux/of_platform.h>

  const char *usb_otg_state_string(enum usb_otg_state state)
  {
@@ -106,23 +107,70 @@ static const char *const usb_dr_modes[] = {
  	[USB_DR_MODE_OTG]		= "otg",
  };

+static enum usb_dr_mode usb_get_dr_mode_from_string(const char *str)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(usb_dr_modes); i++)
+		if (!strcmp(usb_dr_modes[i], str))
+			return i;
+
+	return USB_DR_MODE_UNKNOWN;
+}
+
  enum usb_dr_mode usb_get_dr_mode(struct device *dev)
  {
  	const char *dr_mode;
-	int err, i;
+	int err;

  	err = device_property_read_string(dev, "dr_mode", &dr_mode);
  	if (err < 0)
  		return USB_DR_MODE_UNKNOWN;

-	for (i = 0; i < ARRAY_SIZE(usb_dr_modes); i++)
-		if (!strcmp(dr_mode, usb_dr_modes[i]))
-			return i;
-
-	return USB_DR_MODE_UNKNOWN;
+	return usb_get_dr_mode_from_string(dr_mode);
  }
  EXPORT_SYMBOL_GPL(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 phy devices.  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 = NULL;
+	struct device_node *phy;
+	const char *dr_mode;
+	int index;
+	int err;
+
+	do {
+		controller = of_find_node_with_property(controller, "phys");
+		index = 0;
+		do {
+			phy = of_parse_phandle(controller, "phys", index);
+			of_node_put(phy);
+			if (phy == phy_np)
+				goto finish;
+			index++;
+		} while (phy);
+	} while (controller);
+
+finish:
+	err = of_property_read_string(controller, "dr_mode", &dr_mode);
+	of_node_put(controller);
+
+	if (err < 0)
+		return USB_DR_MODE_UNKNOWN;
+
+	return usb_get_dr_mode_from_string(dr_mode);
+}
+EXPORT_SYMBOL_GPL(of_usb_get_dr_mode_by_phy);
+
  #ifdef CONFIG_OF
  /**
   * of_usb_host_tpl_support - to get if Targeted Peripheral List is supported
diff --git a/include/linux/usb/of.h b/include/linux/usb/of.h
index c3fe9e4..3805757 100644
--- a/include/linux/usb/of.h
+++ b/include/linux/usb/of.h
@@ -12,10 +12,15 @@
  #include <linux/usb/phy.h>

  #if IS_ENABLED(CONFIG_OF)
+enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np);
  bool of_usb_host_tpl_support(struct device_node *np);
  int of_usb_update_otg_caps(struct device_node *np,
  			struct usb_otg_caps *otg_caps);
  #else
+enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np)
+{
+	return USB_DR_MODE_UNKNOWN;
+}
  static inline bool of_usb_host_tpl_support(struct device_node *np)
  {
  	return false;



Hi Felipe,

This commit in your testing/next causes compilation error:

/home/johnyoun/linux/linux-usb/drivers/usb/common/common.c:143:18: error: redefinition of ‘of_usb_get_dr_mode_by_phy’
  enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np)
                   ^
In file included from /home/johnyoun/linux/linux-usb/drivers/usb/common/common.c:18:0:
/home/johnyoun/linux/linux-usb/include/linux/usb/of.h:20:18: note: previous definition of ‘of_usb_get_dr_mode_by_phy’ was here
  enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np)
                   ^
make[4]: *** [drivers/usb/common/common.o] Error 1




I'm on non-OF config.

Looks like the #ifdef CONFIG_OF should encompass the new function
in the .c file.


Thanks John for pointing it out.

Felipe,

Do you want me to send v6 or you will fix it in your tree?

Thanks,
-Bin.

Regards,
John

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



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux