From: Mehmet Fide <[email protected]>

The driver parses the dr_mode property itself, through the flat tree,
into an enum of its own that mirrors enum usb_dr_mode. Use
usb_get_dr_mode() and USB_DR_MODE_* instead, as ehci-mx6 does. A
missing property still means host, for legacy device trees.
usb_get_dr_mode() does not tell it from a value it does not know, so
such a value now means host as well instead of failing the probe.

Signed-off-by: Mehmet Fide <[email protected]>
---

Notes:
    Changes in v8:
    - usb_get_dr_mode() is read once and USB_DR_MODE_UNKNOWN falls back to
      host, as Marek proposed; an unknown value now means host too, as in
      v6, instead of failing with -EINVAL as in v7
    
    Changes in v7:
    - Marek's review: this patch only replaces the private enum and the
      strcmp() chain; the ID detect gpio moves to the next patch
    - a missing dr_mode property means host and an unknown value fails with
      -EINVAL again, as before the series; v6 made an unknown value host
    
    Changes in v6:
    - new patch, from the review of the register base patch in v5: the
      private enum duplicated USB_DR_MODE_*

 drivers/usb/host/ehci-vf.c | 62 +++++++++++++++-----------------------
 1 file changed, 25 insertions(+), 37 deletions(-)

diff --git a/drivers/usb/host/ehci-vf.c b/drivers/usb/host/ehci-vf.c
index e5f9ec0fdbb..90840cea92d 100644
--- a/drivers/usb/host/ehci-vf.c
+++ b/drivers/usb/host/ehci-vf.c
@@ -21,8 +21,8 @@
 #include <asm/mach-imx/regs-usbphy.h>
 #include <linux/delay.h>
 #include <usb/ehci-ci.h>
-#include <linux/libfdt.h>
 #include <fdtdec.h>
+#include <linux/usb/otg.h>
 
 #include "ehci.h"
 
@@ -150,29 +150,19 @@ int ehci_vf_common_init(struct usb_ehci *ehci, int index)
        return 0;
 }
 
-/* Possible port types (dual role mode) */
-enum dr_mode {
-       DR_MODE_NONE = 0,
-       DR_MODE_HOST,           /* supports host operation */
-       DR_MODE_DEVICE,         /* supports device operation */
-       DR_MODE_OTG,            /* supports both */
-};
-
 struct ehci_vf_priv_data {
        struct ehci_ctrl ctrl;
        struct usb_ehci *ehci;
        struct gpio_desc cdet_gpio;
        enum usb_init_type init_type;
-       enum dr_mode dr_mode;
+       enum usb_dr_mode dr_mode;
        u32 portnr;
 };
 
 static int vf_usb_of_to_plat(struct udevice *dev)
 {
        struct ehci_vf_priv_data *priv = dev_get_priv(dev);
-       const void *dt_blob = gd->fdt_blob;
        int node = dev_of_offset(dev);
-       const char *mode;
        fdt_addr_t phy_addr;
        ofnode phy_node;
        int i;
@@ -192,34 +182,32 @@ static int vf_usb_of_to_plat(struct udevice *dev)
        priv->portnr = i;
 
        priv->ehci = dev_read_addr_ptr(dev);
-       mode = fdt_getprop(dt_blob, node, "dr_mode", NULL);
-       if (mode) {
-               if (0 == strcmp(mode, "host")) {
-                       priv->dr_mode = DR_MODE_HOST;
-                       priv->init_type = USB_INIT_HOST;
-               } else if (0 == strcmp(mode, "peripheral")) {
-                       priv->dr_mode = DR_MODE_DEVICE;
-                       priv->init_type = USB_INIT_DEVICE;
-               } else if (0 == strcmp(mode, "otg")) {
-                       priv->dr_mode = DR_MODE_OTG;
-                       /*
-                        * We set init_type to device by default when OTG
-                        * mode is requested. If a valid gpio is provided
-                        * we will switch the init_type based on the state
-                        * of the gpio pin.
-                        */
-                       priv->init_type = USB_INIT_DEVICE;
-               } else {
-                       debug("%s: Cannot decode dr_mode '%s'\n",
-                             __func__, mode);
-                       return -EINVAL;
-               }
-       } else {
-               priv->dr_mode = DR_MODE_HOST;
+       priv->dr_mode = usb_get_dr_mode(dev_ofnode(dev));
+       /* Handle legacy DTs without dr_mode property, fall back to host */
+       if (priv->dr_mode == USB_DR_MODE_UNKNOWN)
+               priv->dr_mode = USB_DR_MODE_HOST;
+
+       switch (priv->dr_mode) {
+       case USB_DR_MODE_HOST:
                priv->init_type = USB_INIT_HOST;
+               break;
+       case USB_DR_MODE_PERIPHERAL:
+               priv->init_type = USB_INIT_DEVICE;
+               break;
+       case USB_DR_MODE_OTG:
+               /*
+                * We set init_type to device by default when OTG
+                * mode is requested. If a valid gpio is provided
+                * we will switch the init_type based on the state
+                * of the gpio pin.
+                */
+               priv->init_type = USB_INIT_DEVICE;
+               break;
+       default:
+               return -EINVAL;
        }
 
-       if (priv->dr_mode == DR_MODE_OTG) {
+       if (priv->dr_mode == USB_DR_MODE_OTG) {
                gpio_request_by_name_nodev(offset_to_ofnode(node),
                                           "fsl,cdet-gpio", 0, &priv->cdet_gpio,
                                           GPIOD_IS_IN);
-- 
2.55.0

Reply via email to