dwc3-generic: Add select_dr_mode operation
authorJean-Jacques Hiblot <jjhiblot@ti.com>
Thu, 29 Nov 2018 09:52:49 +0000 (10:52 +0100)
committerMarek Vasut <marex@denx.de>
Fri, 7 Dec 2018 15:31:45 +0000 (16:31 +0100)
The select_dr_mode operation is executed when the glue driver is probed.
The role of this optional function is to configure the operating mode
of the controller at the glue level.

Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
drivers/usb/dwc3/dwc3-generic.c

index 7be0187d21c57050c721fdb7c9d91bd777125c14..6d9be9b2459648a095edd0b38006e2f582d1a299 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <common.h>
+#include <asm-generic/io.h>
 #include <dm.h>
 #include <dm/device-internal.h>
 #include <dm/lists.h>
@@ -110,6 +111,12 @@ U_BOOT_DRIVER(dwc3_generic_peripheral) = {
 struct dwc3_glue_data {
        struct clk_bulk         clks;
        struct reset_ctl_bulk   resets;
+       fdt_addr_t regs;
+};
+
+struct dwc3_glue_ops {
+       void (*select_dr_mode)(struct udevice *dev, int index,
+                              enum usb_dr_mode mode);
 };
 
 static int dwc3_glue_bind(struct udevice *parent)
@@ -205,9 +212,14 @@ static int dwc3_glue_clk_init(struct udevice *dev,
 
 static int dwc3_glue_probe(struct udevice *dev)
 {
+       struct dwc3_glue_ops *ops = (struct dwc3_glue_ops *)dev_get_driver_data(dev);
        struct dwc3_glue_data *glue = dev_get_platdata(dev);
+       struct udevice *child = NULL;
+       int index = 0;
        int ret;
 
+       glue->regs = dev_read_addr(dev);
+
        ret = dwc3_glue_clk_init(dev, glue);
        if (ret)
                return ret;
@@ -216,6 +228,20 @@ static int dwc3_glue_probe(struct udevice *dev)
        if (ret)
                return ret;
 
+       ret = device_find_first_child(dev, &child);
+       if (ret)
+               return ret;
+
+       while (child) {
+               enum usb_dr_mode dr_mode;
+
+               dr_mode = usb_get_dr_mode(dev_of_offset(child));
+               device_find_next_child(&child);
+               if (ops && ops->select_dr_mode)
+                       ops->select_dr_mode(dev, index, dr_mode);
+               index++;
+       }
+
        return 0;
 }