]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
usb: dwc3: Fix ULPI reset when resetting usb
authorT Karthik Reddy <t.karthik.reddy@xilinx.com>
Tue, 7 Dec 2021 10:36:40 +0000 (03:36 -0700)
committerMichal Simek <michal.simek@xilinx.com>
Tue, 7 Dec 2021 12:03:55 +0000 (13:03 +0100)
In the current ULPI reset implementation, when a usb reset is issued
gpio_request_by_name() returns -EBUSY as the gpio is already requested
and failing to set gpio descriptor flags(active low) and failing to
bring the ULPI out of reset.

Fix this issue by freeing the gpio when a usb reset is issued and
request gpio again when usb starts.

Signed-off-by: T Karthik Reddy <t.karthik.reddy@xilinx.com>
drivers/usb/dwc3/dwc3-generic.c

index 0a8a776b1b89ca2e219899e80eb0bfdae9783923..ce4fe0f246d93009fc8b8d17a686b7ad863ea544 100644 (file)
@@ -43,6 +43,7 @@ struct dwc3_generic_priv {
        void *base;
        struct dwc3 dwc3;
        struct phy_bulk phys;
+       struct gpio_desc ulpi_reset;
 };
 
 struct dwc3_generic_host_priv {
@@ -86,7 +87,6 @@ static int dwc3_generic_probe(struct udevice *dev,
        struct dwc3_generic_plat *plat = dev_get_plat(dev);
        struct dwc3 *dwc3 = &priv->dwc3;
        struct dwc3_glue_data *glue = dev_get_plat(dev->parent);
-       struct gpio_desc reset_gpio;
 
        dwc3->dev = dev;
        dwc3->maximum_speed = plat->maximum_speed;
@@ -110,14 +110,14 @@ static int dwc3_generic_probe(struct udevice *dev,
 
        if (device_is_compatible(dev->parent, "xlnx,zynqmp-dwc3")) {
                ret = gpio_request_by_name(dev->parent, "reset-gpios", 0,
-                                          &reset_gpio, GPIOD_ACTIVE_LOW);
+                                          &priv->ulpi_reset, GPIOD_ACTIVE_LOW);
                if (ret != -EBUSY && ret)
                        return ret;
 
                /* Toggle ulpi to reset the phy. */
-               dm_gpio_set_value(&reset_gpio, 1);
+               dm_gpio_set_value(&priv->ulpi_reset, 1);
                mdelay(5);
-               dm_gpio_set_value(&reset_gpio, 0);
+               dm_gpio_set_value(&priv->ulpi_reset, 0);
                mdelay(5);
        }
 
@@ -146,6 +146,11 @@ static int dwc3_generic_remove(struct udevice *dev,
 {
        struct dwc3 *dwc3 = &priv->dwc3;
 
+       if (device_is_compatible(dev->parent, "xlnx,zynqmp-dwc3")) {
+               struct gpio_desc *ulpi_reset = &priv->ulpi_reset;
+
+               dm_gpio_free(ulpi_reset->dev, ulpi_reset);
+       }
        dwc3_remove(dwc3);
        dwc3_shutdown_phy(dev, &priv->phys);
        unmap_physmem(dwc3->regs, MAP_NOCACHE);