Restore the dwc3 source files to the state of the original import in
commit 85d5e7075f33 ("usb: dwc3: add dwc3 folder from linux kernel to
u-boot").

The following files are preserved accross the import:
Makefile Kconfig dwc3-meson-g12a.c dwc3-meson-gxl.c dwc3-omap.c
dwc3-uniphier.c dwc3-generic.h dwc3-generic.c dwc3-generic-sti.c
dwc3-layerscape.c ti_usb_phy.c

Note that this is a raw import and doesn't build.
A fixup commit at the end of the series fixes that.

Signed-off-by: Jens Wiklander <[email protected]>
---
 drivers/usb/dwc3/core.c            | 1002 +++++++++++++---------------
 drivers/usb/dwc3/core.h            |  171 ++---
 drivers/usb/dwc3/debug.c           |   32 +
 drivers/usb/dwc3/debug.h           |  228 +++++++
 drivers/usb/dwc3/dwc3-am62.c       |  125 ----
 drivers/usb/dwc3/ep0.c             |  217 +++---
 drivers/usb/dwc3/gadget.c          |  482 +++++++------
 drivers/usb/dwc3/gadget.h          |   16 +-
 drivers/usb/dwc3/io.h              |   54 +-
 drivers/usb/dwc3/linux-compat.h    |   16 -
 drivers/usb/dwc3/platform_data.h   |   47 ++
 drivers/usb/dwc3/samsung_usb_phy.c |   77 ---
 12 files changed, 1211 insertions(+), 1256 deletions(-)
 create mode 100644 drivers/usb/dwc3/debug.c
 create mode 100644 drivers/usb/dwc3/debug.h
 delete mode 100644 drivers/usb/dwc3/dwc3-am62.c
 delete mode 100644 drivers/usb/dwc3/linux-compat.h
 create mode 100644 drivers/usb/dwc3/platform_data.h
 delete mode 100644 drivers/usb/dwc3/samsung_usb_phy.c

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 847fa1f82c37..25ddc39efad8 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1,48 +1,55 @@
-// SPDX-License-Identifier: GPL-2.0
 /**
  * core.c - DesignWare USB3 DRD Controller Core file
  *
- * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com
+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
  *
  * Authors: Felipe Balbi <[email protected]>,
  *         Sebastian Andrzej Siewior <[email protected]>
  *
- * Taken from Linux Kernel v3.19-rc1 (drivers/usb/dwc3/core.c) and ported
- * to uboot.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2  of
+ * the License as published by the Free Software Foundation.
  *
- * commit cd72f890d2 : usb: dwc3: core: enable phy suspend quirk on non-FPGA
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <clk.h>
-#include <cpu_func.h>
-#include <malloc.h>
-#include <dwc3-uboot.h>
-#include <dm/device_compat.h>
-#include <dm/devres.h>
-#include <linux/bug.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/list.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
-#include <linux/err.h>
-#include <linux/iopoll.h>
-#include <linux/ioport.h>
-#include <dm.h>
-#include <generic-phy.h>
+#include <linux/of.h>
+#include <linux/acpi.h>
+
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
-#include <linux/bitfield.h>
-#include <linux/math64.h>
-#include <linux/time.h>
+#include <linux/usb/of.h>
+#include <linux/usb/otg.h>
 
+#include "platform_data.h"
 #include "core.h"
 #include "gadget.h"
 #include "io.h"
 
-#include "linux-compat.h"
+#include "debug.h"
 
-static LIST_HEAD(dwc3_list);
 /* -------------------------------------------------------------------------- 
*/
 
-static void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
+void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
 {
        u32 reg;
 
@@ -59,6 +66,7 @@ static void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
 static int dwc3_core_soft_reset(struct dwc3 *dwc)
 {
        u32             reg;
+       int             ret;
 
        /* Before Resetting PHY, put Core in Reset */
        reg = dwc3_readl(dwc->regs, DWC3_GCTL);
@@ -75,6 +83,17 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
        reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST;
        dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
 
+       usb_phy_init(dwc->usb2_phy);
+       usb_phy_init(dwc->usb3_phy);
+       ret = phy_init(dwc->usb2_generic_phy);
+       if (ret < 0)
+               return ret;
+
+       ret = phy_init(dwc->usb3_generic_phy);
+       if (ret < 0) {
+               phy_exit(dwc->usb2_generic_phy);
+               return ret;
+       }
        mdelay(100);
 
        /* Clear USB3 PHY reset */
@@ -97,94 +116,6 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
        return 0;
 }
 
-/*
- * dwc3_frame_length_adjustment - Adjusts frame length if required
- * @dwc3: Pointer to our controller context structure
- * @fladj: Value of GFLADJ_30MHZ to adjust frame length
- */
-static void dwc3_frame_length_adjustment(struct dwc3 *dwc, u32 fladj)
-{
-       u32 reg;
-
-       if (dwc->revision < DWC3_REVISION_250A)
-               return;
-
-       if (fladj == 0)
-               return;
-
-       reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
-       reg &= ~DWC3_GFLADJ_30MHZ_MASK;
-       reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | fladj;
-       dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
-}
-
-/**
- * dwc3_ref_clk_period - Reference clock period configuration
- *             Default reference clock period depends on hardware
- *             configuration. For systems with reference clock that differs
- *             from the default, this will set clock period in DWC3_GUCTL
- *             register.
- * @dwc: Pointer to our controller context structure
- * @ref_clk_per: reference clock period in ns
- */
-static void dwc3_ref_clk_period(struct dwc3 *dwc)
-{
-       unsigned long period;
-       unsigned long fladj;
-       unsigned long decr;
-       unsigned long rate;
-       u32 reg;
-
-       if (dwc->ref_clk) {
-               rate = clk_get_rate(dwc->ref_clk);
-               if (!rate)
-                       return;
-               period = NSEC_PER_SEC / rate;
-       } else {
-               return;
-       }
-
-       reg = dwc3_readl(dwc->regs, DWC3_GUCTL);
-       reg &= ~DWC3_GUCTL_REFCLKPER_MASK;
-       reg |=  FIELD_PREP(DWC3_GUCTL_REFCLKPER_MASK, period);
-       dwc3_writel(dwc->regs, DWC3_GUCTL, reg);
-
-       if (dwc->revision <= DWC3_REVISION_250A)
-               return;
-
-       /*
-        * The calculation below is
-        *
-        * 125000 * (NSEC_PER_SEC / (rate * period) - 1)
-        *
-        * but rearranged for fixed-point arithmetic. The division must be
-        * 64-bit because 125000 * NSEC_PER_SEC doesn't fit in 32 bits (and
-        * neither does rate * period).
-        *
-        * Note that rate * period ~= NSEC_PER_SECOND, minus the number of
-        * nanoseconds of error caused by the truncation which happened during
-        * the division when calculating rate or period (whichever one was
-        * derived from the other). We first calculate the relative error, then
-        * scale it to units of 8 ppm.
-        */
-       fladj = div64_u64(125000ULL * NSEC_PER_SEC, (u64)rate * period);
-       fladj -= 125000;
-
-       /*
-        * The documented 240MHz constant is scaled by 2 to get PLS1 as well.
-        */
-       decr = 480000000 / rate;
-
-       reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
-       reg &= ~DWC3_GFLADJ_REFCLK_FLADJ_MASK
-           &  ~DWC3_GFLADJ_240MHZDECR
-           &  ~DWC3_GFLADJ_240MHZDECR_PLS1;
-       reg |= FIELD_PREP(DWC3_GFLADJ_REFCLK_FLADJ_MASK, fladj)
-           |  FIELD_PREP(DWC3_GFLADJ_240MHZDECR, decr >> 1)
-           |  FIELD_PREP(DWC3_GFLADJ_240MHZDECR_PLS1, decr & 1);
-       dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
-}
-
 /**
  * dwc3_free_one_event_buffer - Frees one event buffer
  * @dwc: Pointer to our controller context structure
@@ -193,7 +124,7 @@ static void dwc3_ref_clk_period(struct dwc3 *dwc)
 static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
                struct dwc3_event_buffer *evt)
 {
-       dma_free_coherent(evt->buf);
+       dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
 }
 
 /**
@@ -209,20 +140,17 @@ static struct dwc3_event_buffer 
*dwc3_alloc_one_event_buffer(struct dwc3 *dwc,
 {
        struct dwc3_event_buffer        *evt;
 
-       evt = devm_kzalloc((struct udevice *)dwc->dev, sizeof(*evt),
-                          GFP_KERNEL);
+       evt = devm_kzalloc(dwc->dev, sizeof(*evt), GFP_KERNEL);
        if (!evt)
                return ERR_PTR(-ENOMEM);
 
        evt->dwc        = dwc;
        evt->length     = length;
-       evt->buf        = dma_alloc_coherent(length,
-                                            (unsigned long *)&evt->dma);
+       evt->buf        = dma_alloc_coherent(dwc->dev, length,
+                       &evt->dma, GFP_KERNEL);
        if (!evt->buf)
                return ERR_PTR(-ENOMEM);
 
-       dwc3_flush_cache((uintptr_t)evt->buf, evt->length);
-
        return evt;
 }
 
@@ -258,8 +186,8 @@ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, 
unsigned length)
        num = DWC3_NUM_INT(dwc->hwparams.hwparams1);
        dwc->num_event_buffers = num;
 
-       dwc->ev_buffs = memalign(CONFIG_SYS_CACHELINE_SIZE,
-                                sizeof(*dwc->ev_buffs) * num);
+       dwc->ev_buffs = devm_kzalloc(dwc->dev, sizeof(*dwc->ev_buffs) * num,
+                       GFP_KERNEL);
        if (!dwc->ev_buffs)
                return -ENOMEM;
 
@@ -354,9 +282,13 @@ static int dwc3_setup_scratch_buffers(struct dwc3 *dwc)
        if (!dwc->nr_scratch)
                return 0;
 
-       scratch_addr = dma_map_single(dwc->scratchbuf,
-                                     dwc->nr_scratch * DWC3_SCRATCHBUF_SIZE,
-                                     DMA_BIDIRECTIONAL);
+        /* should never fall here */
+       if (!WARN_ON(dwc->scratchbuf))
+               return 0;
+
+       scratch_addr = dma_map_single(dwc->dev, dwc->scratchbuf,
+                       dwc->nr_scratch * DWC3_SCRATCHBUF_SIZE,
+                       DMA_BIDIRECTIONAL);
        if (dma_mapping_error(dwc->dev, scratch_addr)) {
                dev_err(dwc->dev, "failed to map scratch buffer\n");
                ret = -EFAULT;
@@ -382,8 +314,8 @@ static int dwc3_setup_scratch_buffers(struct dwc3 *dwc)
        return 0;
 
 err1:
-       dma_unmap_single(scratch_addr, dwc->nr_scratch * DWC3_SCRATCHBUF_SIZE,
-                        DMA_BIDIRECTIONAL);
+       dma_unmap_single(dwc->dev, dwc->scratch_addr, dwc->nr_scratch *
+                       DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
 
 err0:
        return ret;
@@ -397,8 +329,12 @@ static void dwc3_free_scratch_buffers(struct dwc3 *dwc)
        if (!dwc->nr_scratch)
                return;
 
-       dma_unmap_single(dwc->scratch_addr, dwc->nr_scratch *
-                        DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
+        /* should never fall here */
+       if (!WARN_ON(dwc->scratchbuf))
+               return;
+
+       dma_unmap_single(dwc->dev, dwc->scratch_addr, dwc->nr_scratch *
+                       DWC3_SCRATCHBUF_SIZE, DMA_BIDIRECTIONAL);
        kfree(dwc->scratchbuf);
 }
 
@@ -428,34 +364,6 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
        parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8);
 }
 
-static void dwc3_hsphy_mode_setup(struct dwc3 *dwc)
-{
-       enum usb_phy_interface hsphy_mode = dwc->hsphy_mode;
-       u32 reg;
-
-       /* Set dwc3 usb2 phy config */
-       reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
-
-       switch (hsphy_mode) {
-       case USBPHY_INTERFACE_MODE_UTMI:
-               reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
-                       DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
-               reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_8_BIT) |
-                       DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_8_BIT);
-               break;
-       case USBPHY_INTERFACE_MODE_UTMIW:
-               reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
-                       DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
-               reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_16_BIT) |
-                       DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_16_BIT);
-               break;
-       default:
-               break;
-       }
-
-       dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
-}
-
 /**
  * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
  * @dwc: Pointer to our controller context structure
@@ -499,13 +407,8 @@ static void dwc3_phy_setup(struct dwc3 *dwc)
        if (dwc->dis_u3_susphy_quirk)
                reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
 
-       if (dwc->dis_del_phy_power_chg_quirk)
-               reg &= ~DWC3_GUSB3PIPECTL_DEPOCHANGE;
-
        dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
 
-       dwc3_hsphy_mode_setup(dwc);
-
        mdelay(100);
 
        reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
@@ -522,64 +425,11 @@ static void dwc3_phy_setup(struct dwc3 *dwc)
        if (dwc->dis_u2_susphy_quirk)
                reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
 
-       if (dwc->dis_enblslpm_quirk)
-               reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
-
-       if (dwc->dis_u2_freeclk_exists_quirk)
-               reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS;
-
        dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
 
        mdelay(100);
 }
 
-/* set global incr burst type configuration registers */
-static void dwc3_set_incr_burst_type(struct dwc3 *dwc)
-{
-       struct udevice *dev = dwc->dev;
-       u32 cfg;
-
-       if (!dwc->incrx_size)
-               return;
-
-       cfg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0);
-
-       /* Enable Undefined Length INCR Burst and Enable INCRx Burst */
-       cfg &= ~DWC3_GSBUSCFG0_INCRBRST_MASK;
-       if (dwc->incrx_mode)
-               cfg |= DWC3_GSBUSCFG0_INCRBRSTENA;
-       switch (dwc->incrx_size) {
-       case 256:
-               cfg |= DWC3_GSBUSCFG0_INCR256BRSTENA;
-               break;
-       case 128:
-               cfg |= DWC3_GSBUSCFG0_INCR128BRSTENA;
-               break;
-       case 64:
-               cfg |= DWC3_GSBUSCFG0_INCR64BRSTENA;
-               break;
-       case 32:
-               cfg |= DWC3_GSBUSCFG0_INCR32BRSTENA;
-               break;
-       case 16:
-               cfg |= DWC3_GSBUSCFG0_INCR16BRSTENA;
-               break;
-       case 8:
-               cfg |= DWC3_GSBUSCFG0_INCR8BRSTENA;
-               break;
-       case 4:
-               cfg |= DWC3_GSBUSCFG0_INCR4BRSTENA;
-               break;
-       case 1:
-               break;
-       default:
-               dev_err(dev, "Invalid property\n");
-               break;
-       }
-
-       dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, cfg);
-}
-
 /**
  * dwc3_core_init - Low-level initialization of DWC3 Core
  * @dwc: Pointer to our controller context structure
@@ -588,20 +438,26 @@ static void dwc3_set_incr_burst_type(struct dwc3 *dwc)
  */
 static int dwc3_core_init(struct dwc3 *dwc)
 {
+       unsigned long           timeout;
        u32                     hwparams4 = dwc->hwparams.hwparams4;
        u32                     reg;
        int                     ret;
 
        reg = dwc3_readl(dwc->regs, DWC3_GSNPSID);
        /* This should read as U3 followed by revision number */
-       if ((reg & DWC3_GSNPSID_MASK) != 0x55330000 &&
-           (reg & DWC3_GSNPSID_MASK) != 0x33310000) {
+       if ((reg & DWC3_GSNPSID_MASK) != 0x55330000) {
                dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n");
                ret = -ENODEV;
                goto err0;
        }
        dwc->revision = reg;
 
+       /*
+        * Write Linux Version Code to our GUID register so it's easy to figure
+        * out which kernel version a bug was found.
+        */
+       dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE);
+
        /* Handle USB2.0-only core configuration */
        if (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) ==
                        DWC3_GHWPARAMS3_SSPHY_IFC_DIS) {
@@ -610,17 +466,21 @@ static int dwc3_core_init(struct dwc3 *dwc)
        }
 
        /* issue device SoftReset too */
+       timeout = jiffies + msecs_to_jiffies(500);
        dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST);
-       ret = read_poll_timeout(dwc3_readl, reg,
-                               !(reg & DWC3_DCTL_CSFTRST),
-                               1, 5000, dwc->regs, DWC3_DCTL);
-       if (ret) {
-               dev_err(dwc->dev, "Reset Timed Out\n");
-               ret = -ETIMEDOUT;
-               goto err0;
-       }
+       do {
+               reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+               if (!(reg & DWC3_DCTL_CSFTRST))
+                       break;
 
-       dwc3_phy_setup(dwc);
+               if (time_after(jiffies, timeout)) {
+                       dev_err(dwc->dev, "Reset Timed Out\n");
+                       ret = -ETIMEDOUT;
+                       goto err0;
+               }
+
+               cpu_relax();
+       } while (true);
 
        ret = dwc3_core_soft_reset(dwc);
        if (ret)
@@ -671,9 +531,8 @@ static int dwc3_core_init(struct dwc3 *dwc)
                dwc->is_fpga = true;
        }
 
-       if(dwc->disable_scramble_quirk && !dwc->is_fpga)
-               WARN(true,
-                    "disable_scramble cannot be used on non-FPGA builds\n");
+       WARN_ONCE(dwc->disable_scramble_quirk && !dwc->is_fpga,
+                       "disable_scramble cannot be used on non-FPGA builds\n");
 
        if (dwc->disable_scramble_quirk && dwc->is_fpga)
                reg |= DWC3_GCTL_DISSCRAMBLE;
@@ -696,27 +555,27 @@ static int dwc3_core_init(struct dwc3 *dwc)
 
        dwc3_writel(dwc->regs, DWC3_GCTL, reg);
 
+       dwc3_phy_setup(dwc);
+
        ret = dwc3_alloc_scratch_buffers(dwc);
        if (ret)
-               goto err0;
+               goto err1;
 
        ret = dwc3_setup_scratch_buffers(dwc);
        if (ret)
-               goto err1;
-
-       /* Adjust Frame Length */
-       dwc3_frame_length_adjustment(dwc, dwc->fladj);
-
-       /* Adjust Reference Clock Period */
-       dwc3_ref_clk_period(dwc);
-
-       dwc3_set_incr_burst_type(dwc);
+               goto err2;
 
        return 0;
 
-err1:
+err2:
        dwc3_free_scratch_buffers(dwc);
 
+err1:
+       usb_phy_shutdown(dwc->usb2_phy);
+       usb_phy_shutdown(dwc->usb3_phy);
+       phy_exit(dwc->usb2_generic_phy);
+       phy_exit(dwc->usb3_generic_phy);
+
 err0:
        return ret;
 }
@@ -724,10 +583,82 @@ err0:
 static void dwc3_core_exit(struct dwc3 *dwc)
 {
        dwc3_free_scratch_buffers(dwc);
+       usb_phy_shutdown(dwc->usb2_phy);
+       usb_phy_shutdown(dwc->usb3_phy);
+       phy_exit(dwc->usb2_generic_phy);
+       phy_exit(dwc->usb3_generic_phy);
+}
+
+static int dwc3_core_get_phy(struct dwc3 *dwc)
+{
+       struct device           *dev = dwc->dev;
+       struct device_node      *node = dev->of_node;
+       int ret;
+
+       if (node) {
+               dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
+               dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
+       } else {
+               dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
+               dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
+       }
+
+       if (IS_ERR(dwc->usb2_phy)) {
+               ret = PTR_ERR(dwc->usb2_phy);
+               if (ret == -ENXIO || ret == -ENODEV) {
+                       dwc->usb2_phy = NULL;
+               } else if (ret == -EPROBE_DEFER) {
+                       return ret;
+               } else {
+                       dev_err(dev, "no usb2 phy configured\n");
+                       return ret;
+               }
+       }
+
+       if (IS_ERR(dwc->usb3_phy)) {
+               ret = PTR_ERR(dwc->usb3_phy);
+               if (ret == -ENXIO || ret == -ENODEV) {
+                       dwc->usb3_phy = NULL;
+               } else if (ret == -EPROBE_DEFER) {
+                       return ret;
+               } else {
+                       dev_err(dev, "no usb3 phy configured\n");
+                       return ret;
+               }
+       }
+
+       dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy");
+       if (IS_ERR(dwc->usb2_generic_phy)) {
+               ret = PTR_ERR(dwc->usb2_generic_phy);
+               if (ret == -ENOSYS || ret == -ENODEV) {
+                       dwc->usb2_generic_phy = NULL;
+               } else if (ret == -EPROBE_DEFER) {
+                       return ret;
+               } else {
+                       dev_err(dev, "no usb2 phy configured\n");
+                       return ret;
+               }
+       }
+
+       dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy");
+       if (IS_ERR(dwc->usb3_generic_phy)) {
+               ret = PTR_ERR(dwc->usb3_generic_phy);
+               if (ret == -ENOSYS || ret == -ENODEV) {
+                       dwc->usb3_generic_phy = NULL;
+               } else if (ret == -EPROBE_DEFER) {
+                       return ret;
+               } else {
+                       dev_err(dev, "no usb3 phy configured\n");
+                       return ret;
+               }
+       }
+
+       return 0;
 }
 
 static int dwc3_core_init_mode(struct dwc3 *dwc)
 {
+       struct device *dev = dwc->dev;
        int ret;
 
        switch (dwc->dr_mode) {
@@ -735,7 +666,7 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
                dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE);
                ret = dwc3_gadget_init(dwc);
                if (ret) {
-                       dev_err(dwc->dev, "failed to initialize gadget\n");
+                       dev_err(dev, "failed to initialize gadget\n");
                        return ret;
                }
                break;
@@ -743,7 +674,7 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
                dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST);
                ret = dwc3_host_init(dwc);
                if (ret) {
-                       dev_err(dwc->dev, "failed to initialize host\n");
+                       dev_err(dev, "failed to initialize host\n");
                        return ret;
                }
                break;
@@ -751,39 +682,24 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
                dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
                ret = dwc3_host_init(dwc);
                if (ret) {
-                       dev_err(dwc->dev, "failed to initialize host\n");
+                       dev_err(dev, "failed to initialize host\n");
                        return ret;
                }
 
                ret = dwc3_gadget_init(dwc);
                if (ret) {
-                       dev_err(dwc->dev, "failed to initialize gadget\n");
+                       dev_err(dev, "failed to initialize gadget\n");
                        return ret;
                }
                break;
        default:
-               dev_err(dwc->dev,
-                       "Unsupported mode of operation %d\n", dwc->dr_mode);
+               dev_err(dev, "Unsupported mode of operation %d\n", 
dwc->dr_mode);
                return -EINVAL;
        }
 
        return 0;
 }
 
-static void dwc3_gadget_run(struct dwc3 *dwc)
-{
-       dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_RUN_STOP);
-       mdelay(100);
-}
-
-static void dwc3_core_stop(struct dwc3 *dwc)
-{
-       u32 reg;
-
-       reg = dwc3_readl(dwc->regs, DWC3_DCTL);
-       dwc3_writel(dwc->regs, DWC3_DCTL, reg & ~(DWC3_DCTL_RUN_STOP));
-}
-
 static void dwc3_core_exit_mode(struct dwc3 *dwc)
 {
        switch (dwc->dr_mode) {
@@ -801,50 +717,74 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc)
                /* do nothing */
                break;
        }
-
-       /*
-        * switch back to peripheral mode
-        * This enables the phy to enter idle and then, if enabled, suspend.
-        */
-       dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE);
-       dwc3_gadget_run(dwc);
 }
 
 #define DWC3_ALIGN_MASK                (16 - 1)
 
-/**
- * dwc3_uboot_init - dwc3 core uboot initialization code
- * @dwc3_dev: struct dwc3_device containing initialization data
- *
- * Entry point for dwc3 driver (equivalent to dwc3_probe in linux
- * kernel driver). Pointer to dwc3_device should be passed containing
- * base address and other initialization data. Returns '0' on success and
- * a negative value on failure.
- *
- * Generally called from board_usb_init() implemented in board file.
- */
-int dwc3_uboot_init(struct dwc3_device *dwc3_dev)
+static int dwc3_probe(struct platform_device *pdev)
 {
+       struct device           *dev = &pdev->dev;
+       struct dwc3_platform_data *pdata = dev_get_platdata(dev);
+       struct device_node      *node = dev->of_node;
+       struct resource         *res;
        struct dwc3             *dwc;
-       struct device           *dev = NULL;
        u8                      lpm_nyet_threshold;
        u8                      tx_de_emphasis;
        u8                      hird_threshold;
 
        int                     ret;
 
+       void __iomem            *regs;
        void                    *mem;
 
-       mem = devm_kzalloc((struct udevice *)dev,
-                          sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);
+       mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);
        if (!mem)
                return -ENOMEM;
 
        dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
        dwc->mem = mem;
+       dwc->dev = dev;
+
+       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (!res) {
+               dev_err(dev, "missing IRQ\n");
+               return -ENODEV;
+       }
+       dwc->xhci_resources[1].start = res->start;
+       dwc->xhci_resources[1].end = res->end;
+       dwc->xhci_resources[1].flags = res->flags;
+       dwc->xhci_resources[1].name = res->name;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(dev, "missing memory resource\n");
+               return -ENODEV;
+       }
+
+       dwc->xhci_resources[0].start = res->start;
+       dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
+                                       DWC3_XHCI_REGS_END;
+       dwc->xhci_resources[0].flags = res->flags;
+       dwc->xhci_resources[0].name = res->name;
 
-       dwc->regs = (void *)(uintptr_t)(dwc3_dev->base +
-                                       DWC3_GLOBALS_REGS_START);
+       res->start += DWC3_GLOBALS_REGS_START;
+
+       /*
+        * Request memory region but exclude xHCI regs,
+        * since it will be requested by the xhci-plat driver.
+        */
+       regs = devm_ioremap_resource(dev, res);
+       if (IS_ERR(regs))
+               return PTR_ERR(regs);
+
+       dwc->regs       = regs;
+       dwc->regs_size  = resource_size(res);
+       /*
+        * restore res->start back to its original value so that,
+        * in case the probe is deferred, we don't end up getting error in
+        * request the memory region the next time probe is called.
+        */
+       res->start -= DWC3_GLOBALS_REGS_START;
 
        /* default to highest possible threshold */
        lpm_nyet_threshold = 0xff;
@@ -858,35 +798,73 @@ int dwc3_uboot_init(struct dwc3_device *dwc3_dev)
         */
        hird_threshold = 12;
 
-       dwc->maximum_speed = dwc3_dev->maximum_speed;
-       dwc->has_lpm_erratum = dwc3_dev->has_lpm_erratum;
-       if (dwc3_dev->lpm_nyet_threshold)
-               lpm_nyet_threshold = dwc3_dev->lpm_nyet_threshold;
-       dwc->is_utmi_l1_suspend = dwc3_dev->is_utmi_l1_suspend;
-       if (dwc3_dev->hird_threshold)
-               hird_threshold = dwc3_dev->hird_threshold;
-
-       dwc->needs_fifo_resize = dwc3_dev->tx_fifo_resize;
-       dwc->dr_mode = dwc3_dev->dr_mode;
-
-       dwc->disable_scramble_quirk = dwc3_dev->disable_scramble_quirk;
-       dwc->u2exit_lfps_quirk = dwc3_dev->u2exit_lfps_quirk;
-       dwc->u2ss_inp3_quirk = dwc3_dev->u2ss_inp3_quirk;
-       dwc->req_p1p2p3_quirk = dwc3_dev->req_p1p2p3_quirk;
-       dwc->del_p1p2p3_quirk = dwc3_dev->del_p1p2p3_quirk;
-       dwc->del_phy_power_chg_quirk = dwc3_dev->del_phy_power_chg_quirk;
-       dwc->lfps_filter_quirk = dwc3_dev->lfps_filter_quirk;
-       dwc->rx_detect_poll_quirk = dwc3_dev->rx_detect_poll_quirk;
-       dwc->dis_u3_susphy_quirk = dwc3_dev->dis_u3_susphy_quirk;
-       dwc->dis_u2_susphy_quirk = dwc3_dev->dis_u2_susphy_quirk;
-       dwc->dis_del_phy_power_chg_quirk = 
dwc3_dev->dis_del_phy_power_chg_quirk;
-       dwc->dis_tx_ipgap_linecheck_quirk = 
dwc3_dev->dis_tx_ipgap_linecheck_quirk;
-       dwc->dis_enblslpm_quirk = dwc3_dev->dis_enblslpm_quirk;
-       dwc->dis_u2_freeclk_exists_quirk = 
dwc3_dev->dis_u2_freeclk_exists_quirk;
-
-       dwc->tx_de_emphasis_quirk = dwc3_dev->tx_de_emphasis_quirk;
-       if (dwc3_dev->tx_de_emphasis)
-               tx_de_emphasis = dwc3_dev->tx_de_emphasis;
+       if (node) {
+               dwc->maximum_speed = of_usb_get_maximum_speed(node);
+               dwc->has_lpm_erratum = of_property_read_bool(node,
+                               "snps,has-lpm-erratum");
+               of_property_read_u8(node, "snps,lpm-nyet-threshold",
+                               &lpm_nyet_threshold);
+               dwc->is_utmi_l1_suspend = of_property_read_bool(node,
+                               "snps,is-utmi-l1-suspend");
+               of_property_read_u8(node, "snps,hird-threshold",
+                               &hird_threshold);
+
+               dwc->needs_fifo_resize = of_property_read_bool(node,
+                               "tx-fifo-resize");
+               dwc->dr_mode = of_usb_get_dr_mode(node);
+
+               dwc->disable_scramble_quirk = of_property_read_bool(node,
+                               "snps,disable_scramble_quirk");
+               dwc->u2exit_lfps_quirk = of_property_read_bool(node,
+                               "snps,u2exit_lfps_quirk");
+               dwc->u2ss_inp3_quirk = of_property_read_bool(node,
+                               "snps,u2ss_inp3_quirk");
+               dwc->req_p1p2p3_quirk = of_property_read_bool(node,
+                               "snps,req_p1p2p3_quirk");
+               dwc->del_p1p2p3_quirk = of_property_read_bool(node,
+                               "snps,del_p1p2p3_quirk");
+               dwc->del_phy_power_chg_quirk = of_property_read_bool(node,
+                               "snps,del_phy_power_chg_quirk");
+               dwc->lfps_filter_quirk = of_property_read_bool(node,
+                               "snps,lfps_filter_quirk");
+               dwc->rx_detect_poll_quirk = of_property_read_bool(node,
+                               "snps,rx_detect_poll_quirk");
+               dwc->dis_u3_susphy_quirk = of_property_read_bool(node,
+                               "snps,dis_u3_susphy_quirk");
+               dwc->dis_u2_susphy_quirk = of_property_read_bool(node,
+                               "snps,dis_u2_susphy_quirk");
+
+               dwc->tx_de_emphasis_quirk = of_property_read_bool(node,
+                               "snps,tx_de_emphasis_quirk");
+               of_property_read_u8(node, "snps,tx_de_emphasis",
+                               &tx_de_emphasis);
+       } else if (pdata) {
+               dwc->maximum_speed = pdata->maximum_speed;
+               dwc->has_lpm_erratum = pdata->has_lpm_erratum;
+               if (pdata->lpm_nyet_threshold)
+                       lpm_nyet_threshold = pdata->lpm_nyet_threshold;
+               dwc->is_utmi_l1_suspend = pdata->is_utmi_l1_suspend;
+               if (pdata->hird_threshold)
+                       hird_threshold = pdata->hird_threshold;
+
+               dwc->needs_fifo_resize = pdata->tx_fifo_resize;
+               dwc->dr_mode = pdata->dr_mode;
+
+               dwc->disable_scramble_quirk = pdata->disable_scramble_quirk;
+               dwc->u2exit_lfps_quirk = pdata->u2exit_lfps_quirk;
+               dwc->u2ss_inp3_quirk = pdata->u2ss_inp3_quirk;
+               dwc->req_p1p2p3_quirk = pdata->req_p1p2p3_quirk;
+               dwc->del_p1p2p3_quirk = pdata->del_p1p2p3_quirk;
+               dwc->del_phy_power_chg_quirk = pdata->del_phy_power_chg_quirk;
+               dwc->lfps_filter_quirk = pdata->lfps_filter_quirk;
+               dwc->rx_detect_poll_quirk = pdata->rx_detect_poll_quirk;
+               dwc->dis_u3_susphy_quirk = pdata->dis_u3_susphy_quirk;
+               dwc->dis_u2_susphy_quirk = pdata->dis_u2_susphy_quirk;
+
+               dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk;
+               if (pdata->tx_de_emphasis)
+                       tx_de_emphasis = pdata->tx_de_emphasis;
+       }
 
        /* default to superspeed if no maximum_speed passed */
        if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
@@ -898,21 +876,35 @@ int dwc3_uboot_init(struct dwc3_device *dwc3_dev)
        dwc->hird_threshold = hird_threshold
                | (dwc->is_utmi_l1_suspend << 4);
 
-       dwc->hsphy_mode = dwc3_dev->hsphy_mode;
+       ret = dwc3_core_get_phy(dwc);
+       if (ret)
+               return ret;
+
+       spin_lock_init(&dwc->lock);
+       platform_set_drvdata(pdev, dwc);
 
-       dwc->index = dwc3_dev->index;
+       if (!dev->dma_mask) {
+               dev->dma_mask = dev->parent->dma_mask;
+               dev->dma_parms = dev->parent->dma_parms;
+               dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask);
+       }
+
+       pm_runtime_enable(dev);
+       pm_runtime_get_sync(dev);
+       pm_runtime_forbid(dev);
 
        dwc3_cache_hwparams(dwc);
 
        ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
        if (ret) {
                dev_err(dwc->dev, "failed to allocate event buffers\n");
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto err0;
        }
 
-       if (!IS_ENABLED(CONFIG_USB_DWC3_GADGET))
+       if (IS_ENABLED(CONFIG_USB_DWC3_HOST))
                dwc->dr_mode = USB_DR_MODE_HOST;
-       else if (!IS_ENABLED(CONFIG_USB_HOST))
+       else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET))
                dwc->dr_mode = USB_DR_MODE_PERIPHERAL;
 
        if (dwc->dr_mode == USB_DR_MODE_UNKNOWN)
@@ -920,28 +912,55 @@ int dwc3_uboot_init(struct dwc3_device *dwc3_dev)
 
        ret = dwc3_core_init(dwc);
        if (ret) {
-               dev_err(dwc->dev, "failed to initialize core\n");
+               dev_err(dev, "failed to initialize core\n");
                goto err0;
        }
 
+       usb_phy_set_suspend(dwc->usb2_phy, 0);
+       usb_phy_set_suspend(dwc->usb3_phy, 0);
+       ret = phy_power_on(dwc->usb2_generic_phy);
+       if (ret < 0)
+               goto err1;
+
+       ret = phy_power_on(dwc->usb3_generic_phy);
+       if (ret < 0)
+               goto err_usb2phy_power;
+
        ret = dwc3_event_buffers_setup(dwc);
        if (ret) {
                dev_err(dwc->dev, "failed to setup event buffers\n");
-               goto err1;
+               goto err_usb3phy_power;
        }
 
        ret = dwc3_core_init_mode(dwc);
        if (ret)
                goto err2;
 
-       list_add_tail(&dwc->list, &dwc3_list);
+       ret = dwc3_debugfs_init(dwc);
+       if (ret) {
+               dev_err(dev, "failed to initialize debugfs\n");
+               goto err3;
+       }
+
+       pm_runtime_allow(dev);
 
        return 0;
 
+err3:
+       dwc3_core_exit_mode(dwc);
+
 err2:
        dwc3_event_buffers_cleanup(dwc);
 
+err_usb3phy_power:
+       phy_power_off(dwc->usb3_generic_phy);
+
+err_usb2phy_power:
+       phy_power_off(dwc->usb2_generic_phy);
+
 err1:
+       usb_phy_set_suspend(dwc->usb2_phy, 1);
+       usb_phy_set_suspend(dwc->usb3_phy, 1);
        dwc3_core_exit(dwc);
 
 err0:
@@ -950,276 +969,151 @@ err0:
        return ret;
 }
 
-/**
- * dwc3_uboot_exit - dwc3 core uboot cleanup code
- * @index: index of this controller
- *
- * Performs cleanup of memory allocated in dwc3_uboot_init and other misc
- * cleanups (equivalent to dwc3_remove in linux). index of _this_ controller
- * should be passed and should match with the index passed in
- * dwc3_device during init.
- *
- * Generally called from board file.
- */
-void dwc3_uboot_exit(int index)
-{
-       struct dwc3 *dwc;
-
-       list_for_each_entry(dwc, &dwc3_list, list) {
-               if (dwc->index != index)
-                       continue;
-
-               dwc3_core_exit_mode(dwc);
-               dwc3_event_buffers_cleanup(dwc);
-               dwc3_free_event_buffers(dwc);
-               dwc3_core_exit(dwc);
-               list_del(&dwc->list);
-               kfree(dwc->mem);
-               break;
-       }
-}
-
-MODULE_ALIAS("platform:dwc3");
-MODULE_AUTHOR("Felipe Balbi <[email protected]>");
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");
-
-#if !CONFIG_IS_ENABLED(DM_USB_GADGET)
-__weak int dwc3_uboot_interrupt_status(struct udevice *dev)
+static int dwc3_remove(struct platform_device *pdev)
 {
-       return 1;
-}
+       struct dwc3     *dwc = platform_get_drvdata(pdev);
 
-/**
- * dm_usb_gadget_handle_interrupts - handle dwc3 core interrupt
- * @dev: device of this controller
- *
- * Invokes dwc3 gadget interrupts.
- *
- * Generally called from board file.
- */
-int dm_usb_gadget_handle_interrupts(struct udevice *dev)
-{
-       struct dwc3 *dwc = NULL;
+       dwc3_debugfs_exit(dwc);
+       dwc3_core_exit_mode(dwc);
+       dwc3_event_buffers_cleanup(dwc);
+       dwc3_free_event_buffers(dwc);
 
-       if (!dwc3_uboot_interrupt_status(dev))
-               return 0;
+       usb_phy_set_suspend(dwc->usb2_phy, 1);
+       usb_phy_set_suspend(dwc->usb3_phy, 1);
+       phy_power_off(dwc->usb2_generic_phy);
+       phy_power_off(dwc->usb3_generic_phy);
 
-       list_for_each_entry(dwc, &dwc3_list, list) {
-               if (dwc->dev != dev)
-                       continue;
+       dwc3_core_exit(dwc);
 
-               dwc3_gadget_uboot_handle_interrupt(dwc);
-               break;
-       }
+       pm_runtime_put_sync(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
 
        return 0;
 }
-#endif
 
-#if CONFIG_IS_ENABLED(PHY) && CONFIG_IS_ENABLED(DM_USB)
-int dwc3_setup_phy(struct udevice *dev, struct phy_bulk *phys)
+#ifdef CONFIG_PM_SLEEP
+static int dwc3_suspend(struct device *dev)
 {
-       int ret;
-
-       ret = generic_phy_get_bulk(dev, phys);
-       if (ret)
-               return ret;
+       struct dwc3     *dwc = dev_get_drvdata(dev);
+       unsigned long   flags;
 
-       ret = generic_phy_init_bulk(phys);
-       if (ret)
-               return ret;
+       spin_lock_irqsave(&dwc->lock, flags);
 
-       ret = generic_phy_power_on_bulk(phys);
-       if (ret)
-               generic_phy_exit_bulk(phys);
+       switch (dwc->dr_mode) {
+       case USB_DR_MODE_PERIPHERAL:
+       case USB_DR_MODE_OTG:
+               dwc3_gadget_suspend(dwc);
+               /* FALLTHROUGH */
+       case USB_DR_MODE_HOST:
+       default:
+               dwc3_event_buffers_cleanup(dwc);
+               break;
+       }
 
-       return ret;
-}
+       dwc->gctl = dwc3_readl(dwc->regs, DWC3_GCTL);
+       spin_unlock_irqrestore(&dwc->lock, flags);
 
-int dwc3_shutdown_phy(struct udevice *dev, struct phy_bulk *phys)
-{
-       int ret;
+       usb_phy_shutdown(dwc->usb3_phy);
+       usb_phy_shutdown(dwc->usb2_phy);
+       phy_exit(dwc->usb2_generic_phy);
+       phy_exit(dwc->usb3_generic_phy);
 
-       ret = generic_phy_power_off_bulk(phys);
-       ret |= generic_phy_exit_bulk(phys);
-       return ret;
+       return 0;
 }
-#endif
 
-#if CONFIG_IS_ENABLED(DM_USB)
-void dwc3_of_parse(struct dwc3 *dwc)
+static int dwc3_resume(struct device *dev)
 {
-       const u8 *tmp;
-       struct udevice *dev = dwc->dev;
-       u8 lpm_nyet_threshold;
-       u8 tx_de_emphasis;
-       u8 hird_threshold;
-       u32 val;
-       int i;
+       struct dwc3     *dwc = dev_get_drvdata(dev);
+       unsigned long   flags;
+       int             ret;
 
-       /* default to highest possible threshold */
-       lpm_nyet_threshold = 0xff;
-
-       /* default to -3.5dB de-emphasis */
-       tx_de_emphasis = 1;
-
-       /*
-        * default to assert utmi_sleep_n and use maximum allowed HIRD
-        * threshold value of 0b1100
-        */
-       hird_threshold = 12;
-
-       dwc->hsphy_mode = usb_get_phy_mode(dev_ofnode(dev));
-
-       dwc->has_lpm_erratum = dev_read_bool(dev,
-                               "snps,has-lpm-erratum");
-       tmp = dev_read_u8_array_ptr(dev, "snps,lpm-nyet-threshold", 1);
-       if (tmp)
-               lpm_nyet_threshold = *tmp;
-
-       dwc->is_utmi_l1_suspend = dev_read_bool(dev,
-                               "snps,is-utmi-l1-suspend");
-       tmp = dev_read_u8_array_ptr(dev, "snps,hird-threshold", 1);
-       if (tmp)
-               hird_threshold = *tmp;
-
-       dwc->disable_scramble_quirk = dev_read_bool(dev,
-                               "snps,disable_scramble_quirk");
-       dwc->u2exit_lfps_quirk = dev_read_bool(dev,
-                               "snps,u2exit_lfps_quirk");
-       dwc->u2ss_inp3_quirk = dev_read_bool(dev,
-                               "snps,u2ss_inp3_quirk");
-       dwc->req_p1p2p3_quirk = dev_read_bool(dev,
-                               "snps,req_p1p2p3_quirk");
-       dwc->del_p1p2p3_quirk = dev_read_bool(dev,
-                               "snps,del_p1p2p3_quirk");
-       dwc->del_phy_power_chg_quirk = dev_read_bool(dev,
-                               "snps,del_phy_power_chg_quirk");
-       dwc->lfps_filter_quirk = dev_read_bool(dev,
-                               "snps,lfps_filter_quirk");
-       dwc->rx_detect_poll_quirk = dev_read_bool(dev,
-                               "snps,rx_detect_poll_quirk");
-       dwc->dis_u3_susphy_quirk = dev_read_bool(dev,
-                               "snps,dis_u3_susphy_quirk");
-       dwc->dis_u2_susphy_quirk = dev_read_bool(dev,
-                               "snps,dis_u2_susphy_quirk");
-       dwc->dis_del_phy_power_chg_quirk = dev_read_bool(dev,
-                               "snps,dis-del-phy-power-chg-quirk");
-       dwc->dis_tx_ipgap_linecheck_quirk = dev_read_bool(dev,
-                               "snps,dis-tx-ipgap-linecheck-quirk");
-       dwc->dis_enblslpm_quirk = dev_read_bool(dev,
-                               "snps,dis_enblslpm_quirk");
-       dwc->dis_u2_freeclk_exists_quirk = dev_read_bool(dev,
-                               "snps,dis-u2-freeclk-exists-quirk");
-       dwc->tx_de_emphasis_quirk = dev_read_bool(dev,
-                               "snps,tx_de_emphasis_quirk");
-       tmp = dev_read_u8_array_ptr(dev, "snps,tx_de_emphasis", 1);
-       if (tmp)
-               tx_de_emphasis = *tmp;
-
-       dwc->lpm_nyet_threshold = lpm_nyet_threshold;
-       dwc->tx_de_emphasis = tx_de_emphasis;
-
-       dwc->hird_threshold = hird_threshold
-               | (dwc->is_utmi_l1_suspend << 4);
-
-       dev_read_u32(dev, "snps,quirk-frame-length-adjustment", &dwc->fladj);
-
-       /*
-        * Handle property "snps,incr-burst-type-adjustment".
-        * Get the number of value from this property:
-        * result <= 0, means this property is not supported.
-        * result = 1, means INCRx burst mode supported.
-        * result > 1, means undefined length burst mode supported.
-        */
-       dwc->incrx_mode = INCRX_BURST_MODE;
-       dwc->incrx_size = 0;
-       for (i = 0; i < 8; i++) {
-               if (dev_read_u32_index(dev, "snps,incr-burst-type-adjustment",
-                                      i, &val))
-                       break;
-
-               dwc->incrx_mode = INCRX_UNDEF_LENGTH_BURST_MODE;
-               dwc->incrx_size = max(dwc->incrx_size, val);
-       }
-}
-
-int dwc3_init(struct dwc3 *dwc)
-{
-       int ret;
-       u32 reg;
+       usb_phy_init(dwc->usb3_phy);
+       usb_phy_init(dwc->usb2_phy);
+       ret = phy_init(dwc->usb2_generic_phy);
+       if (ret < 0)
+               return ret;
 
-       dwc3_cache_hwparams(dwc);
+       ret = phy_init(dwc->usb3_generic_phy);
+       if (ret < 0)
+               goto err_usb2phy_init;
 
-       ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
-       if (ret) {
-               dev_err(dwc->dev, "failed to allocate event buffers\n");
-               return -ENOMEM;
-       }
+       spin_lock_irqsave(&dwc->lock, flags);
 
-       ret = dwc3_core_init(dwc);
-       if (ret) {
-               dev_err(dwc->dev, "failed to initialize core\n");
-               goto core_fail;
-       }
+       dwc3_event_buffers_setup(dwc);
+       dwc3_writel(dwc->regs, DWC3_GCTL, dwc->gctl);
 
-       ret = dwc3_event_buffers_setup(dwc);
-       if (ret) {
-               dev_err(dwc->dev, "failed to setup event buffers\n");
-               goto event_fail;
+       switch (dwc->dr_mode) {
+       case USB_DR_MODE_PERIPHERAL:
+       case USB_DR_MODE_OTG:
+               dwc3_gadget_resume(dwc);
+               /* FALLTHROUGH */
+       case USB_DR_MODE_HOST:
+       default:
+               /* do nothing */
+               break;
        }
 
-       if (dwc->revision >= DWC3_REVISION_250A) {
-               reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
+       spin_unlock_irqrestore(&dwc->lock, flags);
 
-               /*
-                * Enable hardware control of sending remote wakeup
-                * in HS when the device is in the L1 state.
-                */
-               if (dwc->revision >= DWC3_REVISION_290A)
-                       reg |= DWC3_GUCTL1_DEV_L1_EXIT_BY_HW;
+       pm_runtime_disable(dev);
+       pm_runtime_set_active(dev);
+       pm_runtime_enable(dev);
 
-               if (dwc->dis_tx_ipgap_linecheck_quirk)
-                       reg |= DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS;
+       return 0;
 
-               dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
-       }
+err_usb2phy_init:
+       phy_exit(dwc->usb2_generic_phy);
 
-       if (dwc->dr_mode == USB_DR_MODE_HOST ||
-           dwc->dr_mode == USB_DR_MODE_OTG) {
-               reg = dwc3_readl(dwc->regs, DWC3_GUCTL);
+       return ret;
+}
 
-               reg |= DWC3_GUCTL_HSTINAUTORETRY;
+static const struct dev_pm_ops dwc3_dev_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume)
+};
 
-               dwc3_writel(dwc->regs, DWC3_GUCTL, reg);
-       }
+#define DWC3_PM_OPS    &(dwc3_dev_pm_ops)
+#else
+#define DWC3_PM_OPS    NULL
+#endif
 
-       ret = dwc3_core_init_mode(dwc);
-       if (ret)
-               goto mode_fail;
+#ifdef CONFIG_OF
+static const struct of_device_id of_dwc3_match[] = {
+       {
+               .compatible = "snps,dwc3"
+       },
+       {
+               .compatible = "synopsys,dwc3"
+       },
+       { },
+};
+MODULE_DEVICE_TABLE(of, of_dwc3_match);
+#endif
 
-       return 0;
+#ifdef CONFIG_ACPI
 
-mode_fail:
-       dwc3_event_buffers_cleanup(dwc);
+#define ACPI_ID_INTEL_BSW      "808622B7"
 
-event_fail:
-       dwc3_core_exit(dwc);
+static const struct acpi_device_id dwc3_acpi_match[] = {
+       { ACPI_ID_INTEL_BSW, 0 },
+       { },
+};
+MODULE_DEVICE_TABLE(acpi, dwc3_acpi_match);
+#endif
 
-core_fail:
-       dwc3_free_event_buffers(dwc);
+static struct platform_driver dwc3_driver = {
+       .probe          = dwc3_probe,
+       .remove         = dwc3_remove,
+       .driver         = {
+               .name   = "dwc3",
+               .of_match_table = of_match_ptr(of_dwc3_match),
+               .acpi_match_table = ACPI_PTR(dwc3_acpi_match),
+               .pm     = DWC3_PM_OPS,
+       },
+};
 
-       return ret;
-}
+module_platform_driver(dwc3_driver);
 
-void dwc3_remove(struct dwc3 *dwc)
-{
-       dwc3_core_exit_mode(dwc);
-       dwc3_event_buffers_cleanup(dwc);
-       dwc3_free_event_buffers(dwc);
-       dwc3_core_stop(dwc);
-       dwc3_core_exit(dwc);
-       kfree(dwc->mem);
-}
-#endif
+MODULE_ALIAS("platform:dwc3");
+MODULE_AUTHOR("Felipe Balbi <[email protected]>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index b572ea340c8c..4bb9aa696ede 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -1,28 +1,37 @@
-/* SPDX-License-Identifier: GPL-2.0 */
 /**
  * core.h - DesignWare USB3 DRD Core Header
  *
- * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com
+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
  *
  * Authors: Felipe Balbi <[email protected]>,
  *         Sebastian Andrzej Siewior <[email protected]>
  *
- * Taken from Linux Kernel v3.19-rc1 (drivers/usb/dwc3/core.h) and ported
- * to uboot.
- *
- * commit 460d098cb6 : usb: dwc3: make HIRD threshold configurable
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2  of
+ * the License as published by the Free Software Foundation.
  *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 #ifndef __DRIVERS_USB_DWC3_CORE_H
 #define __DRIVERS_USB_DWC3_CORE_H
 
-#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/spinlock.h>
 #include <linux/ioport.h>
+#include <linux/list.h>
+#include <linux/dma-mapping.h>
+#include <linux/mm.h>
+#include <linux/debugfs.h>
 
 #include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
 #include <linux/usb/otg.h>
-#include <linux/usb/phy.h>
+
+#include <linux/phy/phy.h>
 
 #define DWC3_MSG_MAX   500
 
@@ -75,7 +84,6 @@
 #define DWC3_GCTL              0xc110
 #define DWC3_GEVTEN            0xc114
 #define DWC3_GSTS              0xc118
-#define DWC3_GUCTL1            0xc11c
 #define DWC3_GSNPSID           0xc120
 #define DWC3_GGPIO             0xc124
 #define DWC3_GUID              0xc128
@@ -115,7 +123,6 @@
 #define DWC3_GEVNTCOUNT(n)     (0xc40c + (n * 0x10))
 
 #define DWC3_GHWPARAMS8                0xc600
-#define DWC3_GFLADJ            0xc630
 
 /* Device Registers */
 #define DWC3_DCFG              0xc700
@@ -139,17 +146,6 @@
 
 /* Bit fields */
 
-/* Global SoC Bus Configuration INCRx Register 0 */
-#define DWC3_GSBUSCFG0_INCR256BRSTENA  (1 << 7) /* INCR256 burst */
-#define DWC3_GSBUSCFG0_INCR128BRSTENA  (1 << 6) /* INCR128 burst */
-#define DWC3_GSBUSCFG0_INCR64BRSTENA   (1 << 5) /* INCR64 burst */
-#define DWC3_GSBUSCFG0_INCR32BRSTENA   (1 << 4) /* INCR32 burst */
-#define DWC3_GSBUSCFG0_INCR16BRSTENA   (1 << 3) /* INCR16 burst */
-#define DWC3_GSBUSCFG0_INCR8BRSTENA    (1 << 2) /* INCR8 burst */
-#define DWC3_GSBUSCFG0_INCR4BRSTENA    (1 << 1) /* INCR4 burst */
-#define DWC3_GSBUSCFG0_INCRBRSTENA     (1 << 0) /* undefined length enable */
-#define DWC3_GSBUSCFG0_INCRBRST_MASK   0xff
-
 /* Global Configuration Register */
 #define DWC3_GCTL_PWRDNSCALE(n)        ((n) << 19)
 #define DWC3_GCTL_U2RSTECN     (1 << 16)
@@ -174,26 +170,9 @@
 #define DWC3_GCTL_GBLHIBERNATIONEN     (1 << 1)
 #define DWC3_GCTL_DSBLCLKGTNG          (1 << 0)
 
-/* Global User Control Register */
-#define DWC3_GUCTL_HSTINAUTORETRY      BIT(14)
-
-/* Global User Control 1 Register */
-#define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS     BIT(28)
-#define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW  BIT(24)
-
 /* Global USB2 PHY Configuration Register */
 #define DWC3_GUSB2PHYCFG_PHYSOFTRST    (1 << 31)
-#define DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS     (1 << 30)
 #define DWC3_GUSB2PHYCFG_SUSPHY                (1 << 6)
-#define DWC3_GUSB2PHYCFG_ENBLSLPM      (1 << 8)
-#define DWC3_GUSB2PHYCFG_PHYIF(n)      ((n) << 3)
-#define DWC3_GUSB2PHYCFG_PHYIF_MASK    DWC3_GUSB2PHYCFG_PHYIF(1)
-#define DWC3_GUSB2PHYCFG_USBTRDTIM(n)  ((n) << 10)
-#define DWC3_GUSB2PHYCFG_USBTRDTIM_MASK        DWC3_GUSB2PHYCFG_USBTRDTIM(0xf)
-#define USBTRDTIM_UTMI_8_BIT           9
-#define USBTRDTIM_UTMI_16_BIT          5
-#define UTMI_PHYIF_16_BIT              1
-#define UTMI_PHYIF_8_BIT               0
 
 /* Global USB3 PIPE Control Register */
 #define DWC3_GUSB3PIPECTL_PHYSOFTRST   (1 << 31)
@@ -245,17 +224,6 @@
 /* Global HWPARAMS6 Register */
 #define DWC3_GHWPARAMS6_EN_FPGA                        (1 << 7)
 
-/* Global Frame Length Adjustment Register */
-#define DWC3_GFLADJ_30MHZ_SDBND_SEL            (1 << 7)
-#define DWC3_GFLADJ_30MHZ_MASK                 0x3f
-#define DWC3_GFLADJ_REFCLK_FLADJ_MASK          GENMASK(21, 8)
-#define DWC3_GFLADJ_240MHZDECR                 GENMASK(30, 24)
-#define DWC3_GFLADJ_240MHZDECR_PLS1            BIT(31)
-
-/* Global User Control Register*/
-#define DWC3_GUCTL_REFCLKPER_MASK              0xffc00000
-#define DWC3_GUCTL_REFCLKPER_SEL               22
-
 /* Device Configuration Register */
 #define DWC3_DCFG_DEVADDR(addr)        ((addr) << 3)
 #define DWC3_DCFG_DEVADDR_MASK DWC3_DCFG_DEVADDR(0x7f)
@@ -405,8 +373,6 @@
 #define DWC3_DEPCMD_SETTRANSFRESOURCE  (0x02 << 0)
 #define DWC3_DEPCMD_SETEPCONFIG                (0x01 << 0)
 
-#define DWC3_DEPCMD_CMD(x)             ((x) & 0xf)
-
 /* The EP number goes 0..31 so ep0 is always out and ep1 is always in */
 #define DWC3_DALEPENA_EP(n)            (1 << n)
 
@@ -436,7 +402,7 @@ struct dwc3_event_buffer {
        unsigned int            count;
        unsigned int            flags;
 
-#define DWC3_EVENT_PENDING     (1UL << 0)
+#define DWC3_EVENT_PENDING     BIT(0)
 
        dma_addr_t              dma;
 
@@ -670,7 +636,6 @@ struct dwc3_scratchpad_array {
  * @ep0_trb: dma address of ep0_trb
  * @ep0_usb_req: dummy req used while handling STD USB requests
  * @ep0_bounce_addr: dma address of ep0_bounce
- * @setup_buf_addr: dma address of setup_buf
  * @scratch_addr: dma address of scratchbuf
  * @lock: for synchronizing
  * @dev: pointer to our struct device
@@ -678,19 +643,18 @@ struct dwc3_scratchpad_array {
  * @event_buffer_list: a list of event buffers
  * @gadget: device side representation of the peripheral controller
  * @gadget_driver: pointer to the gadget driver
- * @ref_clk: reference clock
  * @regs: base address for our registers
  * @regs_size: address space size
- * @ref_clk_per: reference clock period configuration
  * @nr_scratch: number of scratch buffers
  * @num_event_buffers: calculated number of event buffers
  * @u1u2: only used on revisions <1.83a for workaround
  * @maximum_speed: maximum speed requested (mainly for testing purposes)
  * @revision: revision register contents
  * @dr_mode: requested mode of operation
- * @hsphy_mode: UTMI phy mode, one of following:
- *             - USBPHY_INTERFACE_MODE_UTMI
- *             - USBPHY_INTERFACE_MODE_UTMIW
+ * @usb2_phy: pointer to USB2 PHY
+ * @usb3_phy: pointer to USB3 PHY
+ * @usb2_generic_phy: pointer to USB2 PHY
+ * @usb3_generic_phy: pointer to USB3 PHY
  * @dcfg: saved contents of DCFG register
  * @gctl: saved contents of GCTL register
  * @isoch_delay: wValue from Set Isochronous Delay request;
@@ -719,8 +683,8 @@ struct dwc3_scratchpad_array {
  * @has_lpm_erratum: true when core was configured with LPM Erratum. Note that
  *                     there's now way for software to detect this in runtime.
  * @is_utmi_l1_suspend: the core asserts output signal
- *     0       - utmi_sleep_n
- *     1       - utmi_l1_suspend_n
+ *     0       - utmi_sleep_n
+ *     1       - utmi_l1_suspend_n
  * @is_selfpowered: true when we are selfpowered
  * @is_fpga: true when we are using the FPGA board
  * @needs_fifo_resize: not all users might want fifo resizing, flag it
@@ -741,12 +705,10 @@ struct dwc3_scratchpad_array {
  * @dis_u2_susphy_quirk: set if we disable usb2 suspend phy
  * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
  * @tx_de_emphasis: Tx de-emphasis value
- *     0       - -6dB de-emphasis
- *     1       - -3.5dB de-emphasis
- *     2       - No de-emphasis
- *     3       - Reserved
- * @index: index of _this_ controller
- * @list: to maintain the list of dwc3 controllers
+ *     0       - -6dB de-emphasis
+ *     1       - -3.5dB de-emphasis
+ *     2       - No de-emphasis
+ *     3       - Reserved
  */
 struct dwc3 {
        struct usb_ctrlrequest  *ctrl_req;
@@ -758,17 +720,12 @@ struct dwc3 {
        dma_addr_t              ep0_trb_addr;
        dma_addr_t              ep0_bounce_addr;
        dma_addr_t              scratch_addr;
-       dma_addr_t              setup_buf_addr;
        struct dwc3_request     ep0_usb_req;
 
        /* device lock */
        spinlock_t              lock;
 
-#if defined(__UBOOT__) && CONFIG_IS_ENABLED(DM_USB)
-       struct udevice          *dev;
-#else
        struct device           *dev;
-#endif
 
        struct platform_device  *xhci;
        struct resource         xhci_resources[DWC3_XHCI_RESOURCES_NUM];
@@ -779,13 +736,16 @@ struct dwc3 {
        struct usb_gadget       gadget;
        struct usb_gadget_driver *gadget_driver;
 
-       struct clk              *ref_clk;
+       struct usb_phy          *usb2_phy;
+       struct usb_phy          *usb3_phy;
+
+       struct phy              *usb2_generic_phy;
+       struct phy              *usb3_generic_phy;
 
        void __iomem            *regs;
        size_t                  regs_size;
 
        enum usb_dr_mode        dr_mode;
-       enum usb_phy_interface  hsphy_mode;
 
        /* used for suspend/resume */
        u32                     dcfg;
@@ -816,7 +776,6 @@ struct dwc3 {
 #define DWC3_REVISION_260A     0x5533260a
 #define DWC3_REVISION_270A     0x5533270a
 #define DWC3_REVISION_280A     0x5533280a
-#define DWC3_REVISION_290A     0x5533290a
 
        enum dwc3_ep0_next      ep0_next_event;
        enum dwc3_ep0_state     ep0state;
@@ -843,10 +802,6 @@ struct dwc3 {
        u8                      test_mode_nr;
        u8                      lpm_nyet_threshold;
        u8                      hird_threshold;
-       u32                     fladj;
-       u32                     ref_clk_per;
-       u8                      incrx_mode;
-       u32                     incrx_size;
 
        unsigned                delayed_status:1;
        unsigned                ep0_bounced:1;
@@ -873,20 +828,11 @@ struct dwc3 {
        unsigned                rx_detect_poll_quirk:1;
        unsigned                dis_u3_susphy_quirk:1;
        unsigned                dis_u2_susphy_quirk:1;
-       unsigned                dis_del_phy_power_chg_quirk:1;
-       unsigned                dis_tx_ipgap_linecheck_quirk:1;
-       unsigned                dis_enblslpm_quirk:1;
-       unsigned                dis_u2_freeclk_exists_quirk:1;
 
        unsigned                tx_de_emphasis_quirk:1;
        unsigned                tx_de_emphasis:2;
-       int                     index;
-       struct list_head        list;
 };
 
-#define INCRX_BURST_MODE 0
-#define INCRX_UNDEF_LENGTH_BURST_MODE 1
-
 /* -------------------------------------------------------------------------- 
*/
 
 /* -------------------------------------------------------------------------- 
*/
@@ -904,30 +850,6 @@ struct dwc3_event_type {
 #define DWC3_DEPEVT_STREAMEVT          0x06
 #define DWC3_DEPEVT_EPCMDCMPLT         0x07
 
-/**
- * dwc3_ep_event_string - returns event name
- * @event: then event code
- */
-static inline const char *dwc3_ep_event_string(u8 event)
-{
-       switch (event) {
-       case DWC3_DEPEVT_XFERCOMPLETE:
-               return "Transfer Complete";
-       case DWC3_DEPEVT_XFERINPROGRESS:
-               return "Transfer In-Progress";
-       case DWC3_DEPEVT_XFERNOTREADY:
-               return "Transfer Not Ready";
-       case DWC3_DEPEVT_RXTXFIFOEVT:
-               return "FIFO";
-       case DWC3_DEPEVT_STREAMEVT:
-               return "Stream";
-       case DWC3_DEPEVT_EPCMDCMPLT:
-               return "Endpoint Command Complete";
-       }
-
-       return "UNKNOWN";
-}
-
 /**
  * struct dwc3_event_depvt - Device Endpoint Events
  * @one_bit: indicates this is an endpoint event (not used)
@@ -1057,17 +979,20 @@ struct dwc3_gadget_ep_cmd_params {
 #define DWC3_HAS_OTG                   BIT(3)
 
 /* prototypes */
+void dwc3_set_mode(struct dwc3 *dwc, u32 mode);
 int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc);
-void dwc3_of_parse(struct dwc3 *dwc);
-int dwc3_init(struct dwc3 *dwc);
-void dwc3_remove(struct dwc3 *dwc);
 
+#if IS_ENABLED(CONFIG_USB_DWC3_HOST) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)
+int dwc3_host_init(struct dwc3 *dwc);
+void dwc3_host_exit(struct dwc3 *dwc);
+#else
 static inline int dwc3_host_init(struct dwc3 *dwc)
 { return 0; }
 static inline void dwc3_host_exit(struct dwc3 *dwc)
 { }
+#endif
 
-#ifdef CONFIG_USB_DWC3_GADGET
+#if IS_ENABLED(CONFIG_USB_DWC3_GADGET) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)
 int dwc3_gadget_init(struct dwc3 *dwc);
 void dwc3_gadget_exit(struct dwc3 *dwc);
 int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode);
@@ -1097,4 +1022,20 @@ static inline int 
dwc3_send_gadget_generic_command(struct dwc3 *dwc,
 { return 0; }
 #endif
 
+/* power management interface */
+#if !IS_ENABLED(CONFIG_USB_DWC3_HOST)
+int dwc3_gadget_suspend(struct dwc3 *dwc);
+int dwc3_gadget_resume(struct dwc3 *dwc);
+#else
+static inline int dwc3_gadget_suspend(struct dwc3 *dwc)
+{
+       return 0;
+}
+
+static inline int dwc3_gadget_resume(struct dwc3 *dwc)
+{
+       return 0;
+}
+#endif /* !IS_ENABLED(CONFIG_USB_DWC3_HOST) */
+
 #endif /* __DRIVERS_USB_DWC3_CORE_H */
diff --git a/drivers/usb/dwc3/debug.c b/drivers/usb/dwc3/debug.c
new file mode 100644
index 000000000000..0be6885bc370
--- /dev/null
+++ b/drivers/usb/dwc3/debug.c
@@ -0,0 +1,32 @@
+/**
+ * debug.c - DesignWare USB3 DRD Controller Debug/Trace Support
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Author: Felipe Balbi <[email protected]>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2  of
+ * the License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "debug.h"
+
+void dwc3_trace(void (*trace)(struct va_format *), const char *fmt, ...)
+{
+       struct va_format vaf;
+       va_list args;
+
+       va_start(args, fmt);
+       vaf.fmt = fmt;
+       vaf.va = &args;
+
+       trace(&vaf);
+
+       va_end(args);
+}
diff --git a/drivers/usb/dwc3/debug.h b/drivers/usb/dwc3/debug.h
new file mode 100644
index 000000000000..07fbc2d94fd4
--- /dev/null
+++ b/drivers/usb/dwc3/debug.h
@@ -0,0 +1,228 @@
+/**
+ * debug.h - DesignWare USB3 DRD Controller Debug Header
+ *
+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Authors: Felipe Balbi <[email protected]>,
+ *         Sebastian Andrzej Siewior <[email protected]>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2  of
+ * the License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __DWC3_DEBUG_H
+#define __DWC3_DEBUG_H
+
+#include "core.h"
+
+/**
+ * dwc3_gadget_ep_cmd_string - returns endpoint command string
+ * @cmd: command code
+ */
+static inline const char *
+dwc3_gadget_ep_cmd_string(u8 cmd)
+{
+       switch (cmd) {
+       case DWC3_DEPCMD_DEPSTARTCFG:
+               return "Start New Configuration";
+       case DWC3_DEPCMD_ENDTRANSFER:
+               return "End Transfer";
+       case DWC3_DEPCMD_UPDATETRANSFER:
+               return "Update Transfer";
+       case DWC3_DEPCMD_STARTTRANSFER:
+               return "Start Transfer";
+       case DWC3_DEPCMD_CLEARSTALL:
+               return "Clear Stall";
+       case DWC3_DEPCMD_SETSTALL:
+               return "Set Stall";
+       case DWC3_DEPCMD_GETEPSTATE:
+               return "Get Endpoint State";
+       case DWC3_DEPCMD_SETTRANSFRESOURCE:
+               return "Set Endpoint Transfer Resource";
+       case DWC3_DEPCMD_SETEPCONFIG:
+               return "Set Endpoint Configuration";
+       default:
+               return "UNKNOWN command";
+       }
+}
+
+/**
+ * dwc3_gadget_generic_cmd_string - returns generic command string
+ * @cmd: command code
+ */
+static inline const char *
+dwc3_gadget_generic_cmd_string(u8 cmd)
+{
+       switch (cmd) {
+       case DWC3_DGCMD_SET_LMP:
+               return "Set LMP";
+       case DWC3_DGCMD_SET_PERIODIC_PAR:
+               return "Set Periodic Parameters";
+       case DWC3_DGCMD_XMIT_FUNCTION:
+               return "Transmit Function Wake Device Notification";
+       case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_LO:
+               return "Set Scratchpad Buffer Array Address Lo";
+       case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_HI:
+               return "Set Scratchpad Buffer Array Address Hi";
+       case DWC3_DGCMD_SELECTED_FIFO_FLUSH:
+               return "Selected FIFO Flush";
+       case DWC3_DGCMD_ALL_FIFO_FLUSH:
+               return "All FIFO Flush";
+       case DWC3_DGCMD_SET_ENDPOINT_NRDY:
+               return "Set Endpoint NRDY";
+       case DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK:
+               return "Run SoC Bus Loopback Test";
+       default:
+               return "UNKNOWN";
+       }
+}
+
+/**
+ * dwc3_gadget_link_string - returns link name
+ * @link_state: link state code
+ */
+static inline const char *
+dwc3_gadget_link_string(enum dwc3_link_state link_state)
+{
+       switch (link_state) {
+       case DWC3_LINK_STATE_U0:
+               return "U0";
+       case DWC3_LINK_STATE_U1:
+               return "U1";
+       case DWC3_LINK_STATE_U2:
+               return "U2";
+       case DWC3_LINK_STATE_U3:
+               return "U3";
+       case DWC3_LINK_STATE_SS_DIS:
+               return "SS.Disabled";
+       case DWC3_LINK_STATE_RX_DET:
+               return "RX.Detect";
+       case DWC3_LINK_STATE_SS_INACT:
+               return "SS.Inactive";
+       case DWC3_LINK_STATE_POLL:
+               return "Polling";
+       case DWC3_LINK_STATE_RECOV:
+               return "Recovery";
+       case DWC3_LINK_STATE_HRESET:
+               return "Hot Reset";
+       case DWC3_LINK_STATE_CMPLY:
+               return "Compliance";
+       case DWC3_LINK_STATE_LPBK:
+               return "Loopback";
+       case DWC3_LINK_STATE_RESET:
+               return "Reset";
+       case DWC3_LINK_STATE_RESUME:
+               return "Resume";
+       default:
+               return "UNKNOWN link state\n";
+       }
+}
+
+/**
+ * dwc3_gadget_event_string - returns event name
+ * @event: the event code
+ */
+static inline const char *dwc3_gadget_event_string(u8 event)
+{
+       switch (event) {
+       case DWC3_DEVICE_EVENT_DISCONNECT:
+               return "Disconnect";
+       case DWC3_DEVICE_EVENT_RESET:
+               return "Reset";
+       case DWC3_DEVICE_EVENT_CONNECT_DONE:
+               return "Connection Done";
+       case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:
+               return "Link Status Change";
+       case DWC3_DEVICE_EVENT_WAKEUP:
+               return "WakeUp";
+       case DWC3_DEVICE_EVENT_EOPF:
+               return "End-Of-Frame";
+       case DWC3_DEVICE_EVENT_SOF:
+               return "Start-Of-Frame";
+       case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
+               return "Erratic Error";
+       case DWC3_DEVICE_EVENT_CMD_CMPL:
+               return "Command Complete";
+       case DWC3_DEVICE_EVENT_OVERFLOW:
+               return "Overflow";
+       }
+
+       return "UNKNOWN";
+}
+
+/**
+ * dwc3_ep_event_string - returns event name
+ * @event: then event code
+ */
+static inline const char *dwc3_ep_event_string(u8 event)
+{
+       switch (event) {
+       case DWC3_DEPEVT_XFERCOMPLETE:
+               return "Transfer Complete";
+       case DWC3_DEPEVT_XFERINPROGRESS:
+               return "Transfer In-Progress";
+       case DWC3_DEPEVT_XFERNOTREADY:
+               return "Transfer Not Ready";
+       case DWC3_DEPEVT_RXTXFIFOEVT:
+               return "FIFO";
+       case DWC3_DEPEVT_STREAMEVT:
+               return "Stream";
+       case DWC3_DEPEVT_EPCMDCMPLT:
+               return "Endpoint Command Complete";
+       }
+
+       return "UNKNOWN";
+}
+
+/**
+ * dwc3_gadget_event_type_string - return event name
+ * @event: the event code
+ */
+static inline const char *dwc3_gadget_event_type_string(u8 event)
+{
+       switch (event) {
+       case DWC3_DEVICE_EVENT_DISCONNECT:
+               return "Disconnect";
+       case DWC3_DEVICE_EVENT_RESET:
+               return "Reset";
+       case DWC3_DEVICE_EVENT_CONNECT_DONE:
+               return "Connect Done";
+       case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:
+               return "Link Status Change";
+       case DWC3_DEVICE_EVENT_WAKEUP:
+               return "Wake-Up";
+       case DWC3_DEVICE_EVENT_HIBER_REQ:
+               return "Hibernation";
+       case DWC3_DEVICE_EVENT_EOPF:
+               return "End of Periodic Frame";
+       case DWC3_DEVICE_EVENT_SOF:
+               return "Start of Frame";
+       case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
+               return "Erratic Error";
+       case DWC3_DEVICE_EVENT_CMD_CMPL:
+               return "Command Complete";
+       case DWC3_DEVICE_EVENT_OVERFLOW:
+               return "Overflow";
+       default:
+               return "UNKNOWN";
+       }
+}
+
+void dwc3_trace(void (*trace)(struct va_format *), const char *fmt, ...);
+
+#ifdef CONFIG_DEBUG_FS
+extern int dwc3_debugfs_init(struct dwc3 *);
+extern void dwc3_debugfs_exit(struct dwc3 *);
+#else
+static inline int dwc3_debugfs_init(struct dwc3 *d)
+{  return 0;  }
+static inline void dwc3_debugfs_exit(struct dwc3 *d)
+{  }
+#endif
+#endif /* __DWC3_DEBUG_H */
diff --git a/drivers/usb/dwc3/dwc3-am62.c b/drivers/usb/dwc3/dwc3-am62.c
deleted file mode 100644
index 99519602eb2c..000000000000
--- a/drivers/usb/dwc3/dwc3-am62.c
+++ /dev/null
@@ -1,125 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * TI AM62 specific glue layer for DWC3
- */
-
-#include <dm.h>
-#include <dm/device_compat.h>
-#include <regmap.h>
-#include <syscon.h>
-#include <asm/io.h>
-
-#include "dwc3-generic.h"
-
-#define USBSS_MODE_CONTROL             0x1c
-#define USBSS_PHY_CONFIG               0x8
-#define USBSS_PHY_VBUS_SEL_MASK                GENMASK(2, 1)
-#define USBSS_PHY_VBUS_SEL_SHIFT       1
-#define USBSS_MODE_VALID       BIT(0)
-#define PHY_PLL_REFCLK_MASK    GENMASK(3, 0)
-static const int dwc3_ti_am62_rate_table[] = { /* in KHZ */
-       9600,
-       10000,
-       12000,
-       19200,
-       20000,
-       24000,
-       25000,
-       26000,
-       38400,
-       40000,
-       58000,
-       50000,
-       52000,
-};
-
-static void dwc3_ti_am62_glue_configure(struct udevice *dev, int index,
-                                       enum usb_dr_mode mode)
-{
-       struct clk usb2_refclk;
-       int rate_code, i, ret;
-       unsigned long rate;
-       u32 reg;
-       void *usbss;
-       bool vbus_divider;
-       struct regmap *syscon;
-       struct ofnode_phandle_args args;
-
-       usbss = dev_remap_addr_index(dev, 0);
-       if (IS_ERR(usbss)) {
-               dev_err(dev, "can't map IOMEM resource\n");
-               return;
-       }
-
-       ret = clk_get_by_name(dev, "ref", &usb2_refclk);
-       if (ret) {
-               dev_err(dev, "can't get usb2_refclk\n");
-               return;
-       }
-
-       /* Calculate the rate code */
-       rate = clk_get_rate(&usb2_refclk);
-       rate /= 1000;   /* To KHz */
-       for (i = 0; i < ARRAY_SIZE(dwc3_ti_am62_rate_table); i++) {
-               if (dwc3_ti_am62_rate_table[i] == rate)
-                       break;
-       }
-
-       if (i == ARRAY_SIZE(dwc3_ti_am62_rate_table)) {
-               dev_err(dev, "unsupported usb2_refclk rate: %lu KHz\n", rate);
-               return;
-       }
-
-       rate_code = i;
-
-       /* Read the syscon property */
-       syscon = syscon_regmap_lookup_by_phandle(dev, 
"ti,syscon-phy-pll-refclk");
-       if (IS_ERR(syscon)) {
-               dev_err(dev, "unable to get ti,syscon-phy-pll-refclk regmap\n");
-               return;
-       }
-
-       ret = ofnode_parse_phandle_with_args(dev_ofnode(dev), 
"ti,syscon-phy-pll-refclk", NULL, 1,
-                                            0, &args);
-       if (ret)
-               return;
-
-       /* Program PHY PLL refclk by reading syscon property */
-       ret = regmap_update_bits(syscon, args.args[0], PHY_PLL_REFCLK_MASK, 
rate_code);
-       if (ret) {
-               dev_err(dev, "failed to set phy pll reference clock rate\n");
-               return;
-       }
-
-       /* VBUS divider select */
-       reg = readl(usbss + USBSS_PHY_CONFIG);
-       vbus_divider = dev_read_bool(dev, "ti,vbus-divider");
-       if (vbus_divider)
-               reg |= 1 << USBSS_PHY_VBUS_SEL_SHIFT;
-
-       writel(reg, usbss + USBSS_PHY_CONFIG);
-
-       /* Set mode valid */
-       reg = readl(usbss + USBSS_MODE_CONTROL);
-       reg |= USBSS_MODE_VALID;
-       writel(reg, usbss + USBSS_MODE_CONTROL);
-}
-
-struct dwc3_glue_ops ti_am62_ops = {
-       .glue_configure = dwc3_ti_am62_glue_configure,
-};
-
-static const struct udevice_id dwc3_am62_match[] = {
-       { .compatible = "ti,am62-usb", .data = (ulong)&ti_am62_ops },
-       { /* sentinel */ }
-};
-
-U_BOOT_DRIVER(dwc3_am62_wrapper) = {
-       .name   = "dwc3-am62",
-       .id     = UCLASS_SIMPLE_BUS,
-       .of_match = dwc3_am62_match,
-       .bind = dwc3_glue_bind,
-       .probe = dwc3_glue_probe,
-       .remove = dwc3_glue_remove,
-       .plat_auto      = sizeof(struct dwc3_glue_data),
-};
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 680756532f0d..1bc77a3b4997 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -1,34 +1,40 @@
-// SPDX-License-Identifier: GPL-2.0
 /**
  * ep0.c - DesignWare USB3 DRD Controller Endpoint 0 Handling
  *
- * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com
+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
  *
  * Authors: Felipe Balbi <[email protected]>,
  *         Sebastian Andrzej Siewior <[email protected]>
  *
- * Taken from Linux Kernel v3.19-rc1 (drivers/usb/dwc3/ep0.c) and ported
- * to uboot.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2  of
+ * the License as published by the Free Software Foundation.
  *
- * commit c00552ebaf : Merge 3.18-rc7 into usb-next
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
-#include <cpu_func.h>
-#include <dm.h>
-#include <dm/device_compat.h>
-#include <linux/bug.h>
+
 #include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/list.h>
+#include <linux/dma-mapping.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb/composite.h>
 
 #include "core.h"
+#include "debug.h"
 #include "gadget.h"
 #include "io.h"
 
-#include "linux-compat.h"
-
 static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep 
*dep);
 static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
                struct dwc3_ep *dep, struct dwc3_request *req);
@@ -50,7 +56,7 @@ static const char *dwc3_ep0_state_string(enum dwc3_ep0_state 
state)
 }
 
 static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
-                               u32 len, u32 type, unsigned chain)
+               u32 len, u32 type)
 {
        struct dwc3_gadget_ep_cmd_params params;
        struct dwc3_trb                 *trb;
@@ -60,14 +66,11 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, 
dma_addr_t buf_dma,
 
        dep = dwc->eps[epnum];
        if (dep->flags & DWC3_EP_BUSY) {
-               dev_vdbg(dwc->dev, "%s still busy\n", dep->name);
+               dwc3_trace(trace_dwc3_ep0, "%s still busy", dep->name);
                return 0;
        }
 
-       trb = &dwc->ep0_trb[dep->free_slot];
-
-       if (chain)
-               dep->free_slot++;
+       trb = dwc->ep0_trb;
 
        trb->bpl = lower_32_bits(buf_dma);
        trb->bph = upper_32_bits(buf_dma);
@@ -75,28 +78,21 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, 
dma_addr_t buf_dma,
        trb->ctrl = type;
 
        trb->ctrl |= (DWC3_TRB_CTRL_HWO
+                       | DWC3_TRB_CTRL_LST
+                       | DWC3_TRB_CTRL_IOC
                        | DWC3_TRB_CTRL_ISP_IMI);
 
-       if (chain)
-               trb->ctrl |= DWC3_TRB_CTRL_CHN;
-       else
-               trb->ctrl |= (DWC3_TRB_CTRL_IOC
-                               | DWC3_TRB_CTRL_LST);
-
-       dwc3_flush_cache((uintptr_t)buf_dma, len);
-       dwc3_flush_cache((uintptr_t)trb, sizeof(*trb));
-
-       if (chain)
-               return 0;
-
        memset(&params, 0, sizeof(params));
        params.param0 = upper_32_bits(dwc->ep0_trb_addr);
        params.param1 = lower_32_bits(dwc->ep0_trb_addr);
 
+       trace_dwc3_prepare_trb(dep, trb);
+
        ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,
                        DWC3_DEPCMD_STARTTRANSFER, &params);
        if (ret < 0) {
-               dev_dbg(dwc->dev, "%s STARTTRANSFER failed", dep->name);
+               dwc3_trace(trace_dwc3_ep0, "%s STARTTRANSFER failed",
+                               dep->name);
                return ret;
        }
 
@@ -161,7 +157,8 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep,
                if (dwc->ep0state == EP0_STATUS_PHASE)
                        __dwc3_ep0_do_control_status(dwc, dwc->eps[direction]);
                else
-                       dev_dbg(dwc->dev, "too early for delayed status");
+                       dwc3_trace(trace_dwc3_ep0,
+                                       "too early for delayed status");
 
                return 0;
        }
@@ -225,7 +222,8 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct 
usb_request *request,
 
        spin_lock_irqsave(&dwc->lock, flags);
        if (!dep->endpoint.desc) {
-               dev_dbg(dwc->dev, "trying to queue request %p to disabled %s",
+               dwc3_trace(trace_dwc3_ep0,
+                               "trying to queue request %p to disabled %s",
                                request, dep->name);
                ret = -ESHUTDOWN;
                goto out;
@@ -237,9 +235,10 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct 
usb_request *request,
                goto out;
        }
 
-       dev_vdbg(dwc->dev, "queueing request %p to %s length %d state '%s\n'",
-                request, dep->name, request->length,
-                dwc3_ep0_state_string(dwc->ep0state));
+       dwc3_trace(trace_dwc3_ep0,
+                       "queueing request %p to %s length %d state '%s'",
+                       request, dep->name, request->length,
+                       dwc3_ep0_state_string(dwc->ep0state));
 
        ret = __dwc3_gadget_ep0_queue(dep, req);
 
@@ -286,6 +285,8 @@ int __dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value)
 
 int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value)
 {
+       struct dwc3_ep                  *dep = to_dwc3_ep(ep);
+       struct dwc3                     *dwc = dep->dwc;
        unsigned long                   flags;
        int                             ret;
 
@@ -301,7 +302,7 @@ void dwc3_ep0_out_start(struct dwc3 *dwc)
        int                             ret;
 
        ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8,
-                                  DWC3_TRBCTL_CONTROL_SETUP, 0);
+                       DWC3_TRBCTL_CONTROL_SETUP);
        WARN_ON(ret < 0);
 }
 
@@ -380,7 +381,7 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc,
        dep = dwc->eps[0];
        dwc->ep0_usb_req.dep = dep;
        dwc->ep0_usb_req.request.length = sizeof(*response_pkt);
-       dwc->ep0_usb_req.request.buf = (void *)(uintptr_t)dwc->setup_buf_addr;
+       dwc->ep0_usb_req.request.buf = dwc->setup_buf;
        dwc->ep0_usb_req.request.complete = dwc3_ep0_status_cmpl;
 
        return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req);
@@ -504,12 +505,13 @@ static int dwc3_ep0_set_address(struct dwc3 *dwc, struct 
usb_ctrlrequest *ctrl)
 
        addr = le16_to_cpu(ctrl->wValue);
        if (addr > 127) {
-               dev_dbg(dwc->dev, "invalid device address %d", addr);
+               dwc3_trace(trace_dwc3_ep0, "invalid device address %d", addr);
                return -EINVAL;
        }
 
        if (state == USB_STATE_CONFIGURED) {
-               dev_dbg(dwc->dev, "trying to set address when configured");
+               dwc3_trace(trace_dwc3_ep0,
+                               "trying to set address when configured");
                return -EINVAL;
        }
 
@@ -574,7 +576,7 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct 
usb_ctrlrequest *ctrl)
                        dwc3_writel(dwc->regs, DWC3_DCTL, reg);
 
                        dwc->resize_fifos = true;
-                       dev_dbg(dwc->dev, "resize FIFOs flag SET");
+                       dwc3_trace(trace_dwc3_ep0, "resize FIFOs flag SET");
                }
                break;
 
@@ -639,10 +641,12 @@ static int dwc3_ep0_set_sel(struct dwc3 *dwc, struct 
usb_ctrlrequest *ctrl)
        struct dwc3_ep  *dep;
        enum usb_device_state state = dwc->gadget.state;
        u16             wLength;
+       u16             wValue;
 
        if (state == USB_STATE_DEFAULT)
                return -EINVAL;
 
+       wValue = le16_to_cpu(ctrl->wValue);
        wLength = le16_to_cpu(ctrl->wLength);
 
        if (wLength != 6) {
@@ -662,7 +666,7 @@ static int dwc3_ep0_set_sel(struct dwc3 *dwc, struct 
usb_ctrlrequest *ctrl)
        dep = dwc->eps[0];
        dwc->ep0_usb_req.dep = dep;
        dwc->ep0_usb_req.request.length = dep->endpoint.maxpacket;
-       dwc->ep0_usb_req.request.buf = (void *)(uintptr_t)dwc->setup_buf_addr;
+       dwc->ep0_usb_req.request.buf = dwc->setup_buf;
        dwc->ep0_usb_req.request.complete = dwc3_ep0_set_sel_cmpl;
 
        return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req);
@@ -696,35 +700,35 @@ static int dwc3_ep0_std_request(struct dwc3 *dwc, struct 
usb_ctrlrequest *ctrl)
 
        switch (ctrl->bRequest) {
        case USB_REQ_GET_STATUS:
-               dev_vdbg(dwc->dev, "USB_REQ_GET_STATUS\n");
+               dwc3_trace(trace_dwc3_ep0, "USB_REQ_GET_STATUS");
                ret = dwc3_ep0_handle_status(dwc, ctrl);
                break;
        case USB_REQ_CLEAR_FEATURE:
-               dev_vdbg(dwc->dev, "USB_REQ_CLEAR_FEATURE\n");
+               dwc3_trace(trace_dwc3_ep0, "USB_REQ_CLEAR_FEATURE");
                ret = dwc3_ep0_handle_feature(dwc, ctrl, 0);
                break;
        case USB_REQ_SET_FEATURE:
-               dev_vdbg(dwc->dev, "USB_REQ_SET_FEATURE\n");
+               dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_FEATURE");
                ret = dwc3_ep0_handle_feature(dwc, ctrl, 1);
                break;
        case USB_REQ_SET_ADDRESS:
-               dev_vdbg(dwc->dev, "USB_REQ_SET_ADDRESS\n");
+               dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_ADDRESS");
                ret = dwc3_ep0_set_address(dwc, ctrl);
                break;
        case USB_REQ_SET_CONFIGURATION:
-               dev_vdbg(dwc->dev, "USB_REQ_SET_CONFIGURATION\n");
+               dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_CONFIGURATION");
                ret = dwc3_ep0_set_config(dwc, ctrl);
                break;
        case USB_REQ_SET_SEL:
-               dev_vdbg(dwc->dev, "USB_REQ_SET_SEL\n");
+               dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_SEL");
                ret = dwc3_ep0_set_sel(dwc, ctrl);
                break;
        case USB_REQ_SET_ISOCH_DELAY:
-               dev_vdbg(dwc->dev, "USB_REQ_SET_ISOCH_DELAY\n");
+               dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_ISOCH_DELAY");
                ret = dwc3_ep0_set_isoch_delay(dwc, ctrl);
                break;
        default:
-               dev_vdbg(dwc->dev, "Forwarding to gadget driver\n");
+               dwc3_trace(trace_dwc3_ep0, "Forwarding to gadget driver");
                ret = dwc3_ep0_delegate_req(dwc, ctrl);
                break;
        }
@@ -742,7 +746,7 @@ static void dwc3_ep0_inspect_setup(struct dwc3 *dwc,
        if (!dwc->gadget_driver)
                goto out;
 
-       dwc3_invalidate_cache((uintptr_t)ctrl, sizeof(*ctrl));
+       trace_dwc3_ctrl_req(ctrl);
 
        len = le16_to_cpu(ctrl->wLength);
        if (!len) {
@@ -775,10 +779,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
        struct usb_request      *ur;
        struct dwc3_trb         *trb;
        struct dwc3_ep          *ep0;
-       unsigned                transfer_size = 0;
-       unsigned                maxp;
-       void                    *buf;
-       u32                     transferred = 0;
+       u32                     transferred;
        u32                     status;
        u32                     length;
        u8                      epnum;
@@ -790,50 +791,34 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
 
        trb = dwc->ep0_trb;
 
+       trace_dwc3_complete_trb(ep0, trb);
+
        r = next_request(&ep0->request_list);
        if (!r)
                return;
 
-       dwc3_flush_cache((uintptr_t)trb, sizeof(*trb));
-
        status = DWC3_TRB_SIZE_TRBSTS(trb->size);
        if (status == DWC3_TRBSTS_SETUP_PENDING) {
-               dev_dbg(dwc->dev, "Setup Pending received");
-               dwc3_gadget_giveback(ep0, r, -ECONNRESET);
+               dwc3_trace(trace_dwc3_ep0, "Setup Pending received");
+
+               if (r)
+                       dwc3_gadget_giveback(ep0, r, -ECONNRESET);
+
                return;
        }
 
        ur = &r->request;
-       buf = ur->buf;
 
        length = trb->size & DWC3_TRB_SIZE_MASK;
 
-       maxp = ep0->endpoint.maxpacket;
-
        if (dwc->ep0_bounced) {
-               /*
-                * Handle the first TRB before handling the bounce buffer if
-                * the request length is greater than the bounce buffer size.
-                */
-               if (ur->length > DWC3_EP0_BOUNCE_SIZE) {
-                       transfer_size = (ur->length / maxp) * maxp;
-                       transferred = transfer_size - length;
-                       buf = (u8 *)buf + transferred;
-                       ur->actual += transferred;
+               unsigned transfer_size = ur->length;
+               unsigned maxp = ep0->endpoint.maxpacket;
 
-                       trb++;
-                       dwc3_flush_cache((uintptr_t)trb, sizeof(*trb));
-                       length = trb->size & DWC3_TRB_SIZE_MASK;
-
-                       ep0->free_slot = 0;
-               }
-
-               transfer_size = roundup((ur->length - transfer_size),
-                                       maxp);
-               transferred = min_t(u32, ur->length - transferred,
-                                   transfer_size - length);
-               dwc3_flush_cache((uintptr_t)dwc->ep0_bounce, 
DWC3_EP0_BOUNCE_SIZE);
-               memcpy(buf, dwc->ep0_bounce, transferred);
+               transfer_size += (maxp - (transfer_size % maxp));
+               transferred = min_t(u32, ur->length,
+                               transfer_size - length);
+               memcpy(ur->buf, dwc->ep0_bounce, transferred);
        } else {
                transferred = ur->length - length;
        }
@@ -855,7 +840,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
 
                        ret = dwc3_ep0_start_trans(dwc, epnum,
                                        dwc->ctrl_req_addr, 0,
-                                       DWC3_TRBCTL_CONTROL_DATA, 0);
+                                       DWC3_TRBCTL_CONTROL_DATA);
                        WARN_ON(ret < 0);
                }
        }
@@ -872,6 +857,8 @@ static void dwc3_ep0_complete_status(struct dwc3 *dwc,
        dep = dwc->eps[0];
        trb = dwc->ep0_trb;
 
+       trace_dwc3_complete_trb(dep, trb);
+
        if (!list_empty(&dep->request_list)) {
                r = next_request(&dep->request_list);
 
@@ -883,7 +870,7 @@ static void dwc3_ep0_complete_status(struct dwc3 *dwc,
 
                ret = dwc3_gadget_set_test_mode(dwc, dwc->test_mode_nr);
                if (ret < 0) {
-                       dev_dbg(dwc->dev, "Invalid Test #%d",
+                       dwc3_trace(trace_dwc3_ep0, "Invalid Test #%d",
                                        dwc->test_mode_nr);
                        dwc3_ep0_stall_and_restart(dwc);
                        return;
@@ -892,7 +879,7 @@ static void dwc3_ep0_complete_status(struct dwc3 *dwc,
 
        status = DWC3_TRB_SIZE_TRBSTS(trb->size);
        if (status == DWC3_TRBSTS_SETUP_PENDING)
-               dev_dbg(dwc->dev, "Setup Pending received");
+               dwc3_trace(trace_dwc3_ep0, "Setup Pending received");
 
        dwc->ep0state = EP0_SETUP_PHASE;
        dwc3_ep0_out_start(dwc);
@@ -909,17 +896,17 @@ static void dwc3_ep0_xfer_complete(struct dwc3 *dwc,
 
        switch (dwc->ep0state) {
        case EP0_SETUP_PHASE:
-               dev_vdbg(dwc->dev, "Setup Phase\n");
+               dwc3_trace(trace_dwc3_ep0, "Setup Phase");
                dwc3_ep0_inspect_setup(dwc, event);
                break;
 
        case EP0_DATA_PHASE:
-               dev_vdbg(dwc->dev, "Data Phase\n");
+               dwc3_trace(trace_dwc3_ep0, "Data Phase");
                dwc3_ep0_complete_data(dwc, event);
                break;
 
        case EP0_STATUS_PHASE:
-               dev_vdbg(dwc->dev, "Status Phase\n");
+               dwc3_trace(trace_dwc3_ep0, "Status Phase");
                dwc3_ep0_complete_status(dwc, event);
                break;
        default:
@@ -936,11 +923,11 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
 
        if (req->request.length == 0) {
                ret = dwc3_ep0_start_trans(dwc, dep->number,
-                                          dwc->ctrl_req_addr, 0,
-                                          DWC3_TRBCTL_CONTROL_DATA, 0);
-       } else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket) &&
-                       (dep->number == 0)) {
-               u32     transfer_size = 0;
+                               dwc->ctrl_req_addr, 0,
+                               DWC3_TRBCTL_CONTROL_DATA);
+       } else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket)
+                       && (dep->number == 0)) {
+               u32     transfer_size;
                u32     maxpacket;
 
                ret = usb_gadget_map_request(&dwc->gadget, &req->request,
@@ -950,18 +937,10 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
                        return;
                }
 
-               maxpacket = dep->endpoint.maxpacket;
-               if (req->request.length > DWC3_EP0_BOUNCE_SIZE) {
-                       transfer_size = (req->request.length / maxpacket) *
-                                               maxpacket;
-                       ret = dwc3_ep0_start_trans(dwc, dep->number,
-                                                  req->request.dma,
-                                                  transfer_size,
-                                                  DWC3_TRBCTL_CONTROL_DATA, 1);
-               }
+               WARN_ON(req->request.length > DWC3_EP0_BOUNCE_SIZE);
 
-               transfer_size = roundup((req->request.length - transfer_size),
-                                       maxpacket);
+               maxpacket = dep->endpoint.maxpacket;
+               transfer_size = roundup(req->request.length, maxpacket);
 
                dwc->ep0_bounced = true;
 
@@ -971,8 +950,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
                 * TRBs to handle the transfer.
                 */
                ret = dwc3_ep0_start_trans(dwc, dep->number,
-                                          dwc->ep0_bounce_addr, transfer_size,
-                                          DWC3_TRBCTL_CONTROL_DATA, 0);
+                               dwc->ep0_bounce_addr, transfer_size,
+                               DWC3_TRBCTL_CONTROL_DATA);
        } else {
                ret = usb_gadget_map_request(&dwc->gadget, &req->request,
                                dep->number);
@@ -982,8 +961,7 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
                }
 
                ret = dwc3_ep0_start_trans(dwc, dep->number, req->request.dma,
-                                          req->request.length,
-                                          DWC3_TRBCTL_CONTROL_DATA, 0);
+                               req->request.length, DWC3_TRBCTL_CONTROL_DATA);
        }
 
        WARN_ON(ret < 0);
@@ -998,13 +976,13 @@ static int dwc3_ep0_start_control_status(struct dwc3_ep 
*dep)
                : DWC3_TRBCTL_CONTROL_STATUS2;
 
        return dwc3_ep0_start_trans(dwc, dep->number,
-                       dwc->ctrl_req_addr, 0, type, 0);
+                       dwc->ctrl_req_addr, 0, type);
 }
 
 static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep)
 {
        if (dwc->resize_fifos) {
-               dev_dbg(dwc->dev, "Resizing FIFOs");
+               dwc3_trace(trace_dwc3_ep0, "Resizing FIFOs");
                dwc3_gadget_resize_tx_fifos(dwc);
                dwc->resize_fifos = 0;
        }
@@ -1045,7 +1023,7 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
 
        switch (event->status) {
        case DEPEVT_STATUS_CONTROL_DATA:
-               dev_vdbg(dwc->dev, "Control Data\n");
+               dwc3_trace(trace_dwc3_ep0, "Control Data");
 
                /*
                 * We already have a DATA transfer in the controller's cache,
@@ -1059,7 +1037,8 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
                if (dwc->ep0_expect_in != event->endpoint_number) {
                        struct dwc3_ep  *dep = dwc->eps[dwc->ep0_expect_in];
 
-                       dev_vdbg(dwc->dev, "Wrong direction for Data phase\n");
+                       dwc3_trace(trace_dwc3_ep0,
+                                       "Wrong direction for Data phase");
                        dwc3_ep0_end_control_data(dwc, dep);
                        dwc3_ep0_stall_and_restart(dwc);
                        return;
@@ -1071,13 +1050,13 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
                if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS)
                        return;
 
-               dev_vdbg(dwc->dev, "Control Status\n");
+               dwc3_trace(trace_dwc3_ep0, "Control Status");
 
                dwc->ep0state = EP0_STATUS_PHASE;
 
                if (dwc->delayed_status) {
                        WARN_ON_ONCE(event->endpoint_number != 1);
-                       dev_vdbg(dwc->dev, "Delayed Status\n");
+                       dwc3_trace(trace_dwc3_ep0, "Delayed Status");
                        return;
                }
 
@@ -1090,10 +1069,10 @@ void dwc3_ep0_interrupt(struct dwc3 *dwc,
 {
        u8                      epnum = event->endpoint_number;
 
-       dev_dbg(dwc->dev, "%s while ep%d%s in state '%s'\n",
-               dwc3_ep_event_string(event->endpoint_event),
-               epnum >> 1, (epnum & 1) ? "in" : "out",
-               dwc3_ep0_state_string(dwc->ep0state));
+       dwc3_trace(trace_dwc3_ep0, "%s while ep%d%s in state '%s'",
+                       dwc3_ep_event_string(event->endpoint_event),
+                       epnum >> 1, (epnum & 1) ? "in" : "out",
+                       dwc3_ep0_state_string(dwc->ep0state));
 
        switch (event->endpoint_event) {
        case DWC3_DEPEVT_XFERCOMPLETE:
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 2b01113d54cd..f03b136ecfce 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1,39 +1,40 @@
-// SPDX-License-Identifier: GPL-2.0
 /**
  * gadget.c - DesignWare USB3 DRD Controller Gadget Framework Link
  *
- * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com
+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
  *
  * Authors: Felipe Balbi <[email protected]>,
  *         Sebastian Andrzej Siewior <[email protected]>
  *
- * Taken from Linux Kernel v3.19-rc1 (drivers/usb/dwc3/gadget.c) and ported
- * to uboot.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2  of
+ * the License as published by the Free Software Foundation.
  *
- * commit 8e74475b0e : usb: dwc3: gadget: use udc-core's reset notifier
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
-#include <cpu_func.h>
-#include <log.h>
-#include <malloc.h>
-#include <dm.h>
-#include <dm/device_compat.h>
-#include <dm/devres.h>
-#include <linux/bug.h>
+#include <linux/kernel.h>
 #include <linux/delay.h>
-#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/list.h>
-#include <linux/printk.h>
+#include <linux/dma-mapping.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 
+#include "debug.h"
 #include "core.h"
 #include "gadget.h"
 #include "io.h"
 
-#include "linux-compat.h"
-
 /**
  * dwc3_gadget_set_test_mode - Enables USB2 Test Modes
  * @dwc: pointer to our context structure
@@ -167,6 +168,7 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum 
dwc3_link_state state)
 int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc)
 {
        int             last_fifo_depth = 0;
+       int             ram1_depth;
        int             fifo_size;
        int             mdwidth;
        int             num;
@@ -174,6 +176,7 @@ int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc)
        if (!dwc->needs_fifo_resize)
                return 0;
 
+       ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7);
        mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
 
        /* MDWIDTH is represented in bits, we need it in bytes */
@@ -231,38 +234,40 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct 
dwc3_request *req,
                int status)
 {
        struct dwc3                     *dwc = dep->dwc;
+       int                             i;
 
        if (req->queued) {
-               dep->busy_slot++;
-               /*
-                * Skip LINK TRB. We can't use req->trb and check for
-                * DWC3_TRBCTL_LINK_TRB because it points the TRB we
-                * just completed (not the LINK TRB).
-                */
-               if (((dep->busy_slot & DWC3_TRB_MASK) ==
-                       DWC3_TRB_NUM- 1) &&
-                       usb_endpoint_xfer_isoc(dep->endpoint.desc))
+               i = 0;
+               do {
                        dep->busy_slot++;
+                       /*
+                        * Skip LINK TRB. We can't use req->trb and check for
+                        * DWC3_TRBCTL_LINK_TRB because it points the TRB we
+                        * just completed (not the LINK TRB).
+                        */
+                       if (((dep->busy_slot & DWC3_TRB_MASK) ==
+                               DWC3_TRB_NUM- 1) &&
+                               usb_endpoint_xfer_isoc(dep->endpoint.desc))
+                               dep->busy_slot++;
+               } while(++i < req->request.num_mapped_sgs);
                req->queued = false;
        }
-
        list_del(&req->list);
        req->trb = NULL;
-       if (req->request.dma && req->request.length)
-               dwc3_flush_cache((uintptr_t)req->request.dma, 
req->request.length);
 
        if (req->request.status == -EINPROGRESS)
                req->request.status = status;
 
        if (dwc->ep0_bounced && dep->number == 0)
                dwc->ep0_bounced = false;
-       else if (req->request.dma)
+       else
                usb_gadget_unmap_request(&dwc->gadget, &req->request,
                                req->direction);
 
        dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n",
                        req, dep->name, req->request.actual,
                        req->request.length, status);
+       trace_dwc3_gadget_giveback(req);
 
        spin_unlock(&dwc->lock);
        usb_gadget_giveback_request(&dep->endpoint, &req->request);
@@ -274,6 +279,8 @@ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, 
unsigned cmd, u32 param)
        u32             timeout = 500;
        u32             reg;
 
+       trace_dwc3_gadget_generic_cmd(cmd, param);
+
        dwc3_writel(dwc->regs, DWC3_DGCMDPAR, param);
        dwc3_writel(dwc->regs, DWC3_DGCMD, cmd | DWC3_DGCMD_CMDACT);
 
@@ -299,38 +306,11 @@ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, 
unsigned cmd, u32 param)
 int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
                unsigned cmd, struct dwc3_gadget_ep_cmd_params *params)
 {
+       struct dwc3_ep          *dep = dwc->eps[ep];
        u32                     timeout = 500;
-       u32                     saved_config = 0;
        u32                     reg;
 
-       int                     ret = -EINVAL;
-
-       /*
-        * When operating in USB 2.0 speeds (HS/FS), if GUSB2PHYCFG.ENBLSLPM or
-        * GUSB2PHYCFG.SUSPHY is set, it must be cleared before issuing an
-        * endpoint command.
-        *
-        * Save and clear both GUSB2PHYCFG.ENBLSLPM and GUSB2PHYCFG.SUSPHY
-        * settings. Restore them after the command is completed.
-        *
-        * DWC_usb3 3.30a and DWC_usb31 1.90a programming guide section 3.2.2
-        */
-       if (dwc->gadget.speed <= USB_SPEED_HIGH ||
-           DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_ENDTRANSFER) {
-               reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
-               if (unlikely(reg & DWC3_GUSB2PHYCFG_SUSPHY)) {
-                       saved_config |= DWC3_GUSB2PHYCFG_SUSPHY;
-                       reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
-               }
-
-               if (reg & DWC3_GUSB2PHYCFG_ENBLSLPM) {
-                       saved_config |= DWC3_GUSB2PHYCFG_ENBLSLPM;
-                       reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
-               }
-
-               if (saved_config)
-                       dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
-       }
+       trace_dwc3_gadget_ep_cmd(dep, cmd, params);
 
        dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0);
        dwc3_writel(dwc->regs, DWC3_DEPCMDPAR1(ep), params->param1);
@@ -342,8 +322,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
                if (!(reg & DWC3_DEPCMD_CMDACT)) {
                        dev_vdbg(dwc->dev, "Command Complete --> %d\n",
                                        DWC3_DEPCMD_STATUS(reg));
-                       ret = 0;
-                       break;
+                       return 0;
                }
 
                /*
@@ -351,21 +330,11 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
                 * interrupt context.
                 */
                timeout--;
-               if (!timeout) {
-                       ret = -ETIMEDOUT;
-                       break;
-               }
+               if (!timeout)
+                       return -ETIMEDOUT;
 
                udelay(1);
        } while (1);
-
-       if (saved_config) {
-               reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
-               reg |= saved_config;
-               dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
-       }
-
-       return ret;
 }
 
 static dma_addr_t dwc3_trb_dma_offset(struct dwc3_ep *dep,
@@ -378,15 +347,17 @@ static dma_addr_t dwc3_trb_dma_offset(struct dwc3_ep *dep,
 
 static int dwc3_alloc_trb_pool(struct dwc3_ep *dep)
 {
+       struct dwc3             *dwc = dep->dwc;
+
        if (dep->trb_pool)
                return 0;
 
        if (dep->number == 0 || dep->number == 1)
                return 0;
 
-       dep->trb_pool = dma_alloc_coherent(sizeof(struct dwc3_trb) *
-                                          DWC3_TRB_NUM,
-                                          (unsigned long *)&dep->trb_pool_dma);
+       dep->trb_pool = dma_alloc_coherent(dwc->dev,
+                       sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
+                       &dep->trb_pool_dma, GFP_KERNEL);
        if (!dep->trb_pool) {
                dev_err(dep->dwc->dev, "failed to allocate trb pool for %s\n",
                                dep->name);
@@ -398,7 +369,10 @@ static int dwc3_alloc_trb_pool(struct dwc3_ep *dep)
 
 static void dwc3_free_trb_pool(struct dwc3_ep *dep)
 {
-       dma_free_coherent(dep->trb_pool);
+       struct dwc3             *dwc = dep->dwc;
+
+       dma_free_coherent(dwc->dev, sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
+                       dep->trb_pool, dep->trb_pool_dma);
 
        dep->trb_pool = NULL;
        dep->trb_pool_dma = 0;
@@ -640,6 +614,7 @@ static int dwc3_gadget_ep_enable(struct usb_ep *ep,
                const struct usb_endpoint_descriptor *desc)
 {
        struct dwc3_ep                  *dep;
+       struct dwc3                     *dwc;
        unsigned long                   flags;
        int                             ret;
 
@@ -654,9 +629,10 @@ static int dwc3_gadget_ep_enable(struct usb_ep *ep,
        }
 
        dep = to_dwc3_ep(ep);
+       dwc = dep->dwc;
 
        if (dep->flags & DWC3_EP_ENABLED) {
-               WARN(true, "%s is already enabled\n",
+               dev_WARN_ONCE(dwc->dev, true, "%s is already enabled\n",
                                dep->name);
                return 0;
        }
@@ -675,7 +651,7 @@ static int dwc3_gadget_ep_enable(struct usb_ep *ep,
                strlcat(dep->name, "-int", sizeof(dep->name));
                break;
        default:
-               dev_err(dep->dwc->dev, "invalid endpoint transfer type\n");
+               dev_err(dwc->dev, "invalid endpoint transfer type\n");
        }
 
        spin_lock_irqsave(&dwc->lock, flags);
@@ -688,6 +664,7 @@ static int dwc3_gadget_ep_enable(struct usb_ep *ep,
 static int dwc3_gadget_ep_disable(struct usb_ep *ep)
 {
        struct dwc3_ep                  *dep;
+       struct dwc3                     *dwc;
        unsigned long                   flags;
        int                             ret;
 
@@ -697,9 +674,10 @@ static int dwc3_gadget_ep_disable(struct usb_ep *ep)
        }
 
        dep = to_dwc3_ep(ep);
+       dwc = dep->dwc;
 
        if (!(dep->flags & DWC3_EP_ENABLED)) {
-               WARN(true, "%s is already disabled\n",
+               dev_WARN_ONCE(dwc->dev, true, "%s is already disabled\n",
                                dep->name);
                return 0;
        }
@@ -728,6 +706,8 @@ static struct usb_request 
*dwc3_gadget_ep_alloc_request(struct usb_ep *ep,
        req->epnum      = dep->number;
        req->dep        = dep;
 
+       trace_dwc3_alloc_request(req);
+
        return &req->request;
 }
 
@@ -736,6 +716,7 @@ static void dwc3_gadget_ep_free_request(struct usb_ep *ep,
 {
        struct dwc3_request             *req = to_dwc3_request(request);
 
+       trace_dwc3_free_request(req);
        kfree(req);
 }
 
@@ -748,11 +729,14 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
                struct dwc3_request *req, dma_addr_t dma,
                unsigned length, unsigned last, unsigned chain, unsigned node)
 {
+       struct dwc3             *dwc = dep->dwc;
        struct dwc3_trb         *trb;
 
-       dev_vdbg(dep->dwc->dev, "%s: req %p dma %08llx length %d%s%s\n",
-                dep->name, req, (unsigned long long)dma,
-                length, last ? " last" : "", chain ? " chain" : "");
+       dev_vdbg(dwc->dev, "%s: req %p dma %08llx length %d%s%s\n",
+                       dep->name, req, (unsigned long long) dma,
+                       length, last ? " last" : "",
+                       chain ? " chain" : "");
+
 
        trb = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];
 
@@ -815,8 +799,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
 
        trb->ctrl |= DWC3_TRB_CTRL_HWO;
 
-       dwc3_flush_cache((uintptr_t)dma, length);
-       dwc3_flush_cache((uintptr_t)trb, sizeof(*trb));
+       trace_dwc3_prepare_trb(dep, trb);
 }
 
 /*
@@ -833,6 +816,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool 
starting)
        struct dwc3_request     *req, *n;
        u32                     trbs_left;
        u32                     max;
+       unsigned int            last_one = 0;
 
        BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM);
 
@@ -882,14 +866,59 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool 
starting)
        list_for_each_entry_safe(req, n, &dep->request_list, list) {
                unsigned        length;
                dma_addr_t      dma;
+               last_one = false;
 
-               dma = req->request.dma;
-               length = req->request.length;
+               if (req->request.num_mapped_sgs > 0) {
+                       struct usb_request *request = &req->request;
+                       struct scatterlist *sg = request->sg;
+                       struct scatterlist *s;
+                       int             i;
 
-               dwc3_prepare_one_trb(dep, req, dma, length,
-                                    true, false, 0);
+                       for_each_sg(sg, s, request->num_mapped_sgs, i) {
+                               unsigned chain = true;
 
-               break;
+                               length = sg_dma_len(s);
+                               dma = sg_dma_address(s);
+
+                               if (i == (request->num_mapped_sgs - 1) ||
+                                               sg_is_last(s)) {
+                                       if (list_is_last(&req->list,
+                                                       &dep->request_list))
+                                               last_one = true;
+                                       chain = false;
+                               }
+
+                               trbs_left--;
+                               if (!trbs_left)
+                                       last_one = true;
+
+                               if (last_one)
+                                       chain = false;
+
+                               dwc3_prepare_one_trb(dep, req, dma, length,
+                                               last_one, chain, i);
+
+                               if (last_one)
+                                       break;
+                       }
+               } else {
+                       dma = req->request.dma;
+                       length = req->request.length;
+                       trbs_left--;
+
+                       if (!trbs_left)
+                               last_one = 1;
+
+                       /* Is this the last request? */
+                       if (list_is_last(&req->list, &dep->request_list))
+                               last_one = 1;
+
+                       dwc3_prepare_one_trb(dep, req, dma, length,
+                                       last_one, false, 0);
+
+                       if (last_one)
+                               break;
+               }
        }
 }
 
@@ -1007,14 +1036,6 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, 
struct dwc3_request *req)
        req->direction          = dep->direction;
        req->epnum              = dep->number;
 
-       /*
-        * DWC3 hangs on OUT requests smaller than maxpacket size,
-        * so HACK the request length
-        */
-       if (dep->direction == 0 &&
-           req->request.length < dep->endpoint.maxpacket)
-               req->request.length = dep->endpoint.maxpacket;
-
        /*
         * We only add to our list of requests now and
         * start consuming the list once we get XferNotReady
@@ -1094,6 +1115,8 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, 
struct dwc3_request *req)
 
                ret = __dwc3_gadget_kick_transfer(dep, 0, true);
                if (ret && ret != -EBUSY) {
+                       struct dwc3     *dwc = dep->dwc;
+
                        dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
                                        dep->name);
                }
@@ -1107,6 +1130,7 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct 
usb_request *request,
 {
        struct dwc3_request             *req = to_dwc3_request(request);
        struct dwc3_ep                  *dep = to_dwc3_ep(ep);
+       struct dwc3                     *dwc = dep->dwc;
 
        unsigned long                   flags;
 
@@ -1114,22 +1138,21 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, 
struct usb_request *request,
 
        spin_lock_irqsave(&dwc->lock, flags);
        if (!dep->endpoint.desc) {
-               dev_dbg(dep->dwc->dev,
-                       "trying to queue request %p to disabled %s\n", request,
-                       ep->name);
+               dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n",
+                               request, ep->name);
                ret = -ESHUTDOWN;
                goto out;
        }
 
-       if (req->dep != dep) {
-               WARN(true, "request %p belongs to '%s'\n", request,
-                    req->dep->name);
+       if (WARN(req->dep != dep, "request %p belongs to '%s'\n",
+                               request, req->dep->name)) {
                ret = -EINVAL;
                goto out;
        }
 
-       dev_vdbg(dep->dwc->dev, "queing request %p to %s length %d\n",
-                request, ep->name, request->length);
+       dev_vdbg(dwc->dev, "queing request %p to %s length %d\n",
+                       request, ep->name, request->length);
+       trace_dwc3_ep_queue(req);
 
        ret = __dwc3_gadget_ep_queue(dep, req);
 
@@ -1151,6 +1174,8 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
        unsigned long                   flags;
        int                             ret = 0;
 
+       trace_dwc3_ep_dequeue(req);
+
        spin_lock_irqsave(&dwc->lock, flags);
 
        list_for_each_entry(r, &dep->request_list, list) {
@@ -1229,6 +1254,7 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int 
value, int protocol)
 static int dwc3_gadget_ep_set_halt(struct usb_ep *ep, int value)
 {
        struct dwc3_ep                  *dep = to_dwc3_ep(ep);
+       struct dwc3                     *dwc = dep->dwc;
 
        unsigned long                   flags;
 
@@ -1244,6 +1270,7 @@ static int dwc3_gadget_ep_set_halt(struct usb_ep *ep, int 
value)
 static int dwc3_gadget_ep_set_wedge(struct usb_ep *ep)
 {
        struct dwc3_ep                  *dep = to_dwc3_ep(ep);
+       struct dwc3                     *dwc = dep->dwc;
        unsigned long                   flags;
        int                             ret;
 
@@ -1359,9 +1386,9 @@ static int dwc3_gadget_wakeup(struct usb_gadget *g)
        }
 
        /* poll until Link State changes to ON */
-       timeout = 1000;
+       timeout = jiffies + msecs_to_jiffies(100);
 
-       while (timeout--) {
+       while (!time_after(jiffies, timeout)) {
                reg = dwc3_readl(dwc->regs, DWC3_DSTS);
 
                /* in HS, means ON */
@@ -1486,6 +1513,9 @@ static void dwc3_gadget_disable_irq(struct dwc3 *dwc)
        dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00);
 }
 
+static irqreturn_t dwc3_interrupt(int irq, void *_dwc);
+static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc);
+
 static int dwc3_gadget_start(struct usb_gadget *g,
                struct usb_gadget_driver *driver)
 {
@@ -1493,14 +1523,24 @@ static int dwc3_gadget_start(struct usb_gadget *g,
        struct dwc3_ep          *dep;
        unsigned long           flags;
        int                     ret = 0;
+       int                     irq;
        u32                     reg;
 
+       irq = platform_get_irq(to_platform_device(dwc->dev), 0);
+       ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt,
+                       IRQF_SHARED, "dwc3", dwc);
+       if (ret) {
+               dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
+                               irq, ret);
+               goto err0;
+       }
+
        spin_lock_irqsave(&dwc->lock, flags);
 
        if (dwc->gadget_driver) {
                dev_err(dwc->dev, "%s is already bound to %s\n",
                                dwc->gadget.name,
-                               dwc->gadget_driver->function);
+                               dwc->gadget_driver->driver.name);
                ret = -EBUSY;
                goto err1;
        }
@@ -1584,6 +1624,9 @@ err2:
 err1:
        spin_unlock_irqrestore(&dwc->lock, flags);
 
+       free_irq(irq, dwc);
+
+err0:
        return ret;
 }
 
@@ -1591,6 +1634,7 @@ static int dwc3_gadget_stop(struct usb_gadget *g)
 {
        struct dwc3             *dwc = gadget_to_dwc(g);
        unsigned long           flags;
+       int                     irq;
 
        spin_lock_irqsave(&dwc->lock, flags);
 
@@ -1602,56 +1646,10 @@ static int dwc3_gadget_stop(struct usb_gadget *g)
 
        spin_unlock_irqrestore(&dwc->lock, flags);
 
-       return 0;
-}
-
-static struct usb_ep *dwc3_find_ep(struct usb_gadget *gadget, const char *name)
-{
-       struct usb_ep *ep;
-
-       list_for_each_entry(ep, &gadget->ep_list, ep_list)
-               if (!strcmp(ep->name, name))
-                       return ep;
+       irq = platform_get_irq(to_platform_device(dwc->dev), 0);
+       free_irq(irq, dwc);
 
-       return NULL;
-}
-
-static struct
-usb_ep *dwc3_gadget_match_ep(struct usb_gadget *gadget,
-                            struct usb_endpoint_descriptor *desc,
-                            struct usb_ss_ep_comp_descriptor *comp_desc)
-{
-       /*
-        * First try standard, common configuration: ep1in-bulk,
-        * ep2out-bulk, ep3in-int to match other udc drivers to avoid
-        * confusion in already deployed software (endpoint numbers
-        * hardcoded in userspace software/drivers)
-        */
-       if (usb_endpoint_is_bulk_in(desc))
-               return dwc3_find_ep(gadget, "ep1in");
-       if (usb_endpoint_is_bulk_out(desc))
-               return dwc3_find_ep(gadget, "ep2out");
-       if (usb_endpoint_is_int_in(desc)) {
-               /*
-                * Special workaround for NXP UUU tool in SPL.
-                *
-                * The tool expects the interrupt-in endpoint to be ep1in,
-                * otherwise it crashes. This is a result of the previous
-                * hard-coded EP setup in drivers/usb/gadget/epautoconf.c
-                * which did special-case EP allocation for SPL builds,
-                * and which was since converted to this callback, but
-                * without the special-case EP allocation in SPL part.
-                *
-                * This reinstates the SPL part in an isolated manner,
-                * only for NXP iMX SoCs, only for SPL builds, and only
-                * for the ep1in interrupt-in endpoint.
-                */
-               if (IS_ENABLED(CONFIG_MACH_IMX) && IS_ENABLED(CONFIG_XPL_BUILD))
-                       return dwc3_find_ep(gadget, "ep1in");
-               return dwc3_find_ep(gadget, "ep3in");
-       }
-
-       return NULL;
+       return 0;
 }
 
 static const struct usb_gadget_ops dwc3_gadget_ops = {
@@ -1661,7 +1659,6 @@ static const struct usb_gadget_ops dwc3_gadget_ops = {
        .pullup                 = dwc3_gadget_pullup,
        .udc_start              = dwc3_gadget_start,
        .udc_stop               = dwc3_gadget_stop,
-       .match_ep               = dwc3_gadget_match_ep,
 };
 
 /* -------------------------------------------------------------------------- 
*/
@@ -1700,7 +1697,7 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc,
                } else {
                        int             ret;
 
-                       usb_ep_set_maxpacket_limit(&dep->endpoint, 512);
+                       usb_ep_set_maxpacket_limit(&dep->endpoint, 1024);
                        dep->endpoint.max_streams = 15;
                        dep->endpoint.ops = &dwc3_gadget_ep_ops;
                        list_add_tail(&dep->endpoint.ep_list,
@@ -1776,6 +1773,8 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, 
struct dwc3_ep *dep,
        unsigned int            s_pkt = 0;
        unsigned int            trb_status;
 
+       trace_dwc3_complete_trb(dep, trb);
+
        if ((trb->ctrl & DWC3_TRB_CTRL_HWO) && status != -ESHUTDOWN)
                /*
                 * We continue despite the error. There is not much we
@@ -1850,23 +1849,35 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, 
struct dwc3_ep *dep,
        struct dwc3_request     *req;
        struct dwc3_trb         *trb;
        unsigned int            slot;
+       unsigned int            i;
+       int                     ret;
 
-       req = next_request(&dep->req_queued);
-       if (!req) {
-               WARN_ON_ONCE(1);
-               return 1;
-       }
+       do {
+               req = next_request(&dep->req_queued);
+               if (!req) {
+                       WARN_ON_ONCE(1);
+                       return 1;
+               }
+               i = 0;
+               do {
+                       slot = req->start_slot + i;
+                       if ((slot == DWC3_TRB_NUM - 1) &&
+                               usb_endpoint_xfer_isoc(dep->endpoint.desc))
+                               slot++;
+                       slot %= DWC3_TRB_NUM;
+                       trb = &dep->trb_pool[slot];
+
+                       ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb,
+                                       event, status);
+                       if (ret)
+                               break;
+               }while (++i < req->request.num_mapped_sgs);
 
-       slot = req->start_slot;
-       if ((slot == DWC3_TRB_NUM - 1) &&
-           usb_endpoint_xfer_isoc(dep->endpoint.desc))
-               slot++;
-       slot %= DWC3_TRB_NUM;
-       trb = &dep->trb_pool[slot];
+               dwc3_gadget_giveback(dep, req, status);
 
-       dwc3_flush_cache((uintptr_t)trb, sizeof(*trb));
-       __dwc3_cleanup_done_trbs(dwc, dep, req, trb, event, status);
-       dwc3_gadget_giveback(dep, req, status);
+               if (ret)
+                       break;
+       } while (1);
 
        if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
                        list_empty(&dep->req_queued)) {
@@ -2299,8 +2310,9 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 
*dwc)
                 * BESL value in the LPM token is less than or equal to LPM
                 * NYET threshold.
                 */
-               if (dwc->revision < DWC3_REVISION_240A  && dwc->has_lpm_erratum)
-                       WARN(true, "LPM Erratum not available on dwc3 
revisisions < 2.40a\n");
+               WARN_ONCE(dwc->revision < DWC3_REVISION_240A
+                               && dwc->has_lpm_erratum,
+                               "LPM Erratum not available on dwc3 revisisions 
< 2.40a\n");
 
                if (dwc->has_lpm_erratum && dwc->revision >= DWC3_REVISION_240A)
                        reg |= DWC3_DCTL_LPM_ERRATA(dwc->lpm_nyet_threshold);
@@ -2449,7 +2461,7 @@ static void dwc3_gadget_linksts_change_interrupt(struct 
dwc3 *dwc,
 static void dwc3_gadget_hibernation_interrupt(struct dwc3 *dwc,
                unsigned int evtinfo)
 {
-       unsigned int is_ss = evtinfo & (1UL << 4);
+       unsigned int is_ss = evtinfo & BIT(4);
 
        /**
         * WORKAROUND: DWC3 revison 2.20a with hibernation support
@@ -2487,10 +2499,10 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc,
                dwc3_gadget_wakeup_interrupt(dwc);
                break;
        case DWC3_DEVICE_EVENT_HIBER_REQ:
-               if (!dwc->has_hibernation) {
-                       WARN(1 ,"unexpected hibernation event\n");
+               if (dev_WARN_ONCE(dwc->dev, !dwc->has_hibernation,
+                                       "unexpected hibernation event\n"))
                        break;
-               }
+
                dwc3_gadget_hibernation_interrupt(dwc, event->event_info);
                break;
        case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:
@@ -2519,6 +2531,8 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc,
 static void dwc3_process_event_entry(struct dwc3 *dwc,
                const union dwc3_event *event)
 {
+       trace_dwc3_event(event->raw);
+
        /* Endpoint IRQ, handle it and return early */
        if (event->type.is_devspec == 0) {
                /* depevt */
@@ -2551,8 +2565,6 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 
*dwc, u32 buf)
        while (left > 0) {
                union dwc3_event event;
 
-               dwc3_invalidate_cache((uintptr_t)evt->buf, evt->length);
-
                event.raw = *(u32 *) (evt->buf + evt->lpos);
 
                dwc3_process_event_entry(dwc, &event);
@@ -2656,31 +2668,31 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 {
        int                                     ret;
 
-       dwc->ctrl_req = dma_alloc_coherent(sizeof(*dwc->ctrl_req),
-                                       (unsigned long *)&dwc->ctrl_req_addr);
+       dwc->ctrl_req = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
+                       &dwc->ctrl_req_addr, GFP_KERNEL);
        if (!dwc->ctrl_req) {
                dev_err(dwc->dev, "failed to allocate ctrl request\n");
                ret = -ENOMEM;
                goto err0;
        }
 
-       dwc->ep0_trb = dma_alloc_coherent(sizeof(*dwc->ep0_trb) * 2,
-                                         (unsigned long *)&dwc->ep0_trb_addr);
+       dwc->ep0_trb = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
+                       &dwc->ep0_trb_addr, GFP_KERNEL);
        if (!dwc->ep0_trb) {
                dev_err(dwc->dev, "failed to allocate ep0 trb\n");
                ret = -ENOMEM;
                goto err1;
        }
 
-       dwc->setup_buf = dma_alloc_coherent(DWC3_EP0_BOUNCE_SIZE,
-                                       (unsigned long *)&dwc->setup_buf_addr);
+       dwc->setup_buf = kzalloc(DWC3_EP0_BOUNCE_SIZE, GFP_KERNEL);
        if (!dwc->setup_buf) {
                ret = -ENOMEM;
                goto err2;
        }
 
-       dwc->ep0_bounce = dma_alloc_coherent(DWC3_EP0_BOUNCE_SIZE,
-                                       (unsigned long *)&dwc->ep0_bounce_addr);
+       dwc->ep0_bounce = dma_alloc_coherent(dwc->dev,
+                       DWC3_EP0_BOUNCE_SIZE, &dwc->ep0_bounce_addr,
+                       GFP_KERNEL);
        if (!dwc->ep0_bounce) {
                dev_err(dwc->dev, "failed to allocate ep0 bounce buffer\n");
                ret = -ENOMEM;
@@ -2690,6 +2702,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
        dwc->gadget.ops                 = &dwc3_gadget_ops;
        dwc->gadget.max_speed           = USB_SPEED_SUPER;
        dwc->gadget.speed               = USB_SPEED_UNKNOWN;
+       dwc->gadget.sg_supported        = true;
        dwc->gadget.name                = "dwc3-gadget";
 
        /*
@@ -2707,7 +2720,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
        if (ret)
                goto err4;
 
-       ret = usb_add_gadget_udc((struct device *)dwc->dev, &dwc->gadget);
+       ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget);
        if (ret) {
                dev_err(dwc->dev, "failed to register udc\n");
                goto err4;
@@ -2717,16 +2730,19 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 
 err4:
        dwc3_gadget_free_endpoints(dwc);
-       dma_free_coherent(dwc->ep0_bounce);
+       dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
+                       dwc->ep0_bounce, dwc->ep0_bounce_addr);
 
 err3:
-       dma_free_coherent(dwc->setup_buf);
+       kfree(dwc->setup_buf);
 
 err2:
-       dma_free_coherent(dwc->ep0_trb);
+       dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
+                       dwc->ep0_trb, dwc->ep0_trb_addr);
 
 err1:
-       dma_free_coherent(dwc->ctrl_req);
+       dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
+                       dwc->ctrl_req, dwc->ctrl_req_addr);
 
 err0:
        return ret;
@@ -2740,37 +2756,69 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
 
        dwc3_gadget_free_endpoints(dwc);
 
-       dma_free_coherent(dwc->ep0_bounce);
+       dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
+                       dwc->ep0_bounce, dwc->ep0_bounce_addr);
 
-       dma_free_coherent(dwc->setup_buf);
+       kfree(dwc->setup_buf);
 
-       dma_free_coherent(dwc->ep0_trb);
+       dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
+                       dwc->ep0_trb, dwc->ep0_trb_addr);
 
-       dma_free_coherent(dwc->ctrl_req);
+       dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
+                       dwc->ctrl_req, dwc->ctrl_req_addr);
 }
 
-/**
- * dwc3_gadget_uboot_handle_interrupt - handle dwc3 gadget interrupt
- * @dwc: struct dwce *
- *
- * Handles ep0 and gadget interrupt
- *
- * Should be called from dwc3 core.
- */
-void dwc3_gadget_uboot_handle_interrupt(struct dwc3 *dwc)
+int dwc3_gadget_suspend(struct dwc3 *dwc)
 {
-       int ret = dwc3_interrupt(0, dwc);
+       if (dwc->pullups_connected) {
+               dwc3_gadget_disable_irq(dwc);
+               dwc3_gadget_run_stop(dwc, true, true);
+       }
 
-       if (ret == IRQ_WAKE_THREAD) {
-               int i;
-               struct dwc3_event_buffer *evt;
+       __dwc3_gadget_ep_disable(dwc->eps[0]);
+       __dwc3_gadget_ep_disable(dwc->eps[1]);
 
-               dwc3_thread_interrupt(0, dwc);
+       dwc->dcfg = dwc3_readl(dwc->regs, DWC3_DCFG);
 
-               /* Clean + Invalidate the buffers after touching them */
-               for (i = 0; i < dwc->num_event_buffers; i++) {
-                       evt = dwc->ev_buffs[i];
-                       dwc3_flush_cache((uintptr_t)evt->buf, evt->length);
-               }
+       return 0;
+}
+
+int dwc3_gadget_resume(struct dwc3 *dwc)
+{
+       struct dwc3_ep          *dep;
+       int                     ret;
+
+       /* Start with SuperSpeed Default */
+       dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
+
+       dep = dwc->eps[0];
+       ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false,
+                       false);
+       if (ret)
+               goto err0;
+
+       dep = dwc->eps[1];
+       ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false,
+                       false);
+       if (ret)
+               goto err1;
+
+       /* begin to receive SETUP packets */
+       dwc->ep0state = EP0_SETUP_PHASE;
+       dwc3_ep0_out_start(dwc);
+
+       dwc3_writel(dwc->regs, DWC3_DCFG, dwc->dcfg);
+
+       if (dwc->pullups_connected) {
+               dwc3_gadget_enable_irq(dwc);
+               dwc3_gadget_run_stop(dwc, true, false);
        }
+
+       return 0;
+
+err1:
+       __dwc3_gadget_ep_disable(dwc->eps[0]);
+
+err0:
+       return ret;
 }
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
index f28a9755dcb3..18ae3eaa8b6f 100644
--- a/drivers/usb/dwc3/gadget.h
+++ b/drivers/usb/dwc3/gadget.h
@@ -1,18 +1,19 @@
-/* SPDX-License-Identifier: GPL-2.0 */
 /**
  * gadget.h - DesignWare USB3 DRD Gadget Header
  *
- * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com
+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
  *
  * Authors: Felipe Balbi <[email protected]>,
  *         Sebastian Andrzej Siewior <[email protected]>
  *
- * Taken from Linux Kernel v3.19-rc1 (drivers/usb/dwc3/gadget.h) and ported
- * to uboot.
- *
- * commit 7a60855972 : usb: dwc3: gadget: fix set_halt() bug with pending
-                      transfers
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2  of
+ * the License as published by the Free Software Foundation.
  *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 #ifndef __DRIVERS_USB_DWC3_GADGET_H
@@ -86,7 +87,6 @@ int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value);
 int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
                gfp_t gfp_flags);
 int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol);
-void dwc3_gadget_uboot_handle_interrupt(struct dwc3 *dwc);
 
 /**
  * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW
diff --git a/drivers/usb/dwc3/io.h b/drivers/usb/dwc3/io.h
index c1ab02881424..6a79c8e66bbc 100644
--- a/drivers/usb/dwc3/io.h
+++ b/drivers/usb/dwc3/io.h
@@ -1,29 +1,32 @@
-/* SPDX-License-Identifier: GPL-2.0 */
 /**
  * io.h - DesignWare USB3 DRD IO Header
  *
- * Copyright (C) 2014 Texas Instruments Incorporated - https://www.ti.com
+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
  *
  * Authors: Felipe Balbi <[email protected]>,
  *         Sebastian Andrzej Siewior <[email protected]>
  *
- * Taken from Linux Kernel v3.19-rc1 (drivers/usb/dwc3/io.h) and ported
- * to uboot.
- *
- * commit 2c4cbe6e5a : usb: dwc3: add tracepoints to aid debugging
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2  of
+ * the License as published by the Free Software Foundation.
  *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 #ifndef __DRIVERS_USB_DWC3_IO_H
 #define __DRIVERS_USB_DWC3_IO_H
 
-#include <cpu_func.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include "trace.h"
+#include "debug.h"
+#include "core.h"
 
-#define        CACHELINE_SIZE          CONFIG_SYS_CACHELINE_SIZE
 static inline u32 dwc3_readl(void __iomem *base, u32 offset)
 {
-       unsigned long offs = offset - DWC3_GLOBALS_REGS_START;
+       u32 offs = offset - DWC3_GLOBALS_REGS_START;
        u32 value;
 
        /*
@@ -33,12 +36,20 @@ static inline u32 dwc3_readl(void __iomem *base, u32 offset)
         */
        value = readl(base + offs);
 
+       /*
+        * When tracing we want to make it easy to find the correct address on
+        * documentation, so we revert it back to the proper addresses, the
+        * same way they are described on SNPS documentation
+        */
+       dwc3_trace(trace_dwc3_readl, "addr %p value %08x",
+                       base - DWC3_GLOBALS_REGS_START + offset, value);
+
        return value;
 }
 
 static inline void dwc3_writel(void __iomem *base, u32 offset, u32 value)
 {
-       unsigned long offs = offset - DWC3_GLOBALS_REGS_START;
+       u32 offs = offset - DWC3_GLOBALS_REGS_START;
 
        /*
         * We requested the mem region starting from the Globals address
@@ -46,21 +57,14 @@ static inline void dwc3_writel(void __iomem *base, u32 
offset, u32 value)
         * However, the offsets are given starting from xHCI address space.
         */
        writel(value, base + offs);
-}
-
-static inline void dwc3_flush_cache(uintptr_t addr, int length)
-{
-       uintptr_t start_addr = (uintptr_t)addr & ~(CACHELINE_SIZE - 1);
-       uintptr_t end_addr = ALIGN((uintptr_t)addr + length, CACHELINE_SIZE);
 
-       flush_dcache_range((unsigned long)start_addr, (unsigned long)end_addr);
+       /*
+        * When tracing we want to make it easy to find the correct address on
+        * documentation, so we revert it back to the proper addresses, the
+        * same way they are described on SNPS documentation
+        */
+       dwc3_trace(trace_dwc3_writel, "addr %p value %08x",
+                       base - DWC3_GLOBALS_REGS_START + offset, value);
 }
 
-static inline void dwc3_invalidate_cache(uintptr_t addr, int length)
-{
-       uintptr_t start_addr = (uintptr_t)addr & ~(CACHELINE_SIZE - 1);
-       uintptr_t end_addr = ALIGN((uintptr_t)addr + length, CACHELINE_SIZE);
-
-       invalidate_dcache_range((unsigned long)start_addr, (unsigned 
long)end_addr);
-}
 #endif /* __DRIVERS_USB_DWC3_IO_H */
diff --git a/drivers/usb/dwc3/linux-compat.h b/drivers/usb/dwc3/linux-compat.h
deleted file mode 100644
index 563f8727cdde..000000000000
--- a/drivers/usb/dwc3/linux-compat.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/**
- * linux-compat.h - DesignWare USB3 Linux Compatibiltiy Adapter  Header
- *
- * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com
- *
- * Authors: Kishon Vijay Abraham I <[email protected]>
- *
- */
-
-#ifndef __DWC3_LINUX_COMPAT__
-#define __DWC3_LINUX_COMPAT__
-
-#define dev_WARN(dev, format, arg...)  debug(format, ##arg)
-
-#endif
diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h
new file mode 100644
index 000000000000..a3a3b6d5668c
--- /dev/null
+++ b/drivers/usb/dwc3/platform_data.h
@@ -0,0 +1,47 @@
+/**
+ * platform_data.h - USB DWC3 Platform Data Support
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ * Author: Felipe Balbi <[email protected]>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2  of
+ * the License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/usb/ch9.h>
+#include <linux/usb/otg.h>
+
+struct dwc3_platform_data {
+       enum usb_device_speed maximum_speed;
+       enum usb_dr_mode dr_mode;
+       bool tx_fifo_resize;
+
+       unsigned is_utmi_l1_suspend:1;
+       u8 hird_threshold;
+
+       u8 lpm_nyet_threshold;
+
+       unsigned disable_scramble_quirk:1;
+       unsigned has_lpm_erratum:1;
+       unsigned u2exit_lfps_quirk:1;
+       unsigned u2ss_inp3_quirk:1;
+       unsigned req_p1p2p3_quirk:1;
+       unsigned del_p1p2p3_quirk:1;
+       unsigned del_phy_power_chg_quirk:1;
+       unsigned lfps_filter_quirk:1;
+       unsigned rx_detect_poll_quirk:1;
+       unsigned dis_u3_susphy_quirk:1;
+       unsigned dis_u2_susphy_quirk:1;
+
+       unsigned tx_de_emphasis_quirk:1;
+       unsigned tx_de_emphasis:2;
+};
diff --git a/drivers/usb/dwc3/samsung_usb_phy.c 
b/drivers/usb/dwc3/samsung_usb_phy.c
deleted file mode 100644
index 3563070cb85d..000000000000
--- a/drivers/usb/dwc3/samsung_usb_phy.c
+++ /dev/null
@@ -1,77 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/**
- * samsung_usb_phy.c - DesignWare USB3 (DWC3) PHY handling file
- *
- * Copyright (C) 2015 Samsung Electronics
- *
- * Author: Joonyoung Shim <[email protected]>
- */
-
-#include <asm/io.h>
-#include <asm/arch/power.h>
-#include <asm/arch/xhci-exynos.h>
-#include <linux/delay.h>
-
-void exynos5_usb3_phy_init(struct exynos_usb3_phy *phy)
-{
-       u32 reg;
-
-       /* Reset USB 3.0 PHY */
-       writel(0x0, &phy->phy_reg0);
-
-       clrbits_le32(&phy->phy_param0,
-                       /* Select PHY CLK source */
-                       PHYPARAM0_REF_USE_PAD |
-                       /* Set Loss-of-Signal Detector sensitivity */
-                       PHYPARAM0_REF_LOSLEVEL_MASK);
-       setbits_le32(&phy->phy_param0, PHYPARAM0_REF_LOSLEVEL);
-
-       writel(0x0, &phy->phy_resume);
-
-       /*
-        * Setting the Frame length Adj value[6:1] to default 0x20
-        * See xHCI 1.0 spec, 5.2.4
-        */
-       setbits_le32(&phy->link_system,
-                       LINKSYSTEM_XHCI_VERSION_CONTROL |
-                       LINKSYSTEM_FLADJ(0x20));
-
-       /* Set Tx De-Emphasis level */
-       clrbits_le32(&phy->phy_param1, PHYPARAM1_PCS_TXDEEMPH_MASK);
-       setbits_le32(&phy->phy_param1, PHYPARAM1_PCS_TXDEEMPH);
-
-       setbits_le32(&phy->phy_batchg, PHYBATCHG_UTMI_CLKSEL);
-
-       /* PHYTEST POWERDOWN Control */
-       clrbits_le32(&phy->phy_test,
-                       PHYTEST_POWERDOWN_SSP |
-                       PHYTEST_POWERDOWN_HSP);
-
-       /* UTMI Power Control */
-       writel(PHYUTMI_OTGDISABLE, &phy->phy_utmi);
-
-               /* Use core clock from main PLL */
-       reg = PHYCLKRST_REFCLKSEL_EXT_REFCLK |
-               /* Default 24Mhz crystal clock */
-               PHYCLKRST_FSEL(FSEL_CLKSEL_24M) |
-               PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF |
-               PHYCLKRST_SSC_REFCLKSEL(0) |
-               /* Force PortReset of PHY */
-               PHYCLKRST_PORTRESET |
-               /* Digital power supply in normal operating mode */
-               PHYCLKRST_RETENABLEN |
-               /* Enable ref clock for SS function */
-               PHYCLKRST_REF_SSP_EN |
-               /* Enable spread spectrum */
-               PHYCLKRST_SSC_EN |
-               /* Power down HS Bias and PLL blocks in suspend mode */
-               PHYCLKRST_COMMONONN;
-
-       writel(reg, &phy->phy_clk_rst);
-
-       /* giving time to Phy clock to settle before resetting */
-       udelay(10);
-
-       reg &= ~PHYCLKRST_PORTRESET;
-       writel(reg, &phy->phy_clk_rst);
-}
-- 
2.43.0

Reply via email to