]> git.sur5r.net Git - u-boot/blobdiff - drivers/usb/dwc3/gadget.c
SPDX: Convert all of our single license tags to Linux Kernel style
[u-boot] / drivers / usb / dwc3 / gadget.c
index 0aefc5c7e2d514d42a8f945191ca5f3653a2adad..d45fae044c4a0c04cc34236aec11ca4c6327bb98 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /**
  * gadget.c - DesignWare USB3 DRD Controller Gadget Framework Link
  *
  * to uboot.
  *
  * commit 8e74475b0e : usb: dwc3: gadget: use udc-core's reset notifier
- *
- * SPDX-License-Identifier:     GPL-2.0
  */
 
-#include <linux/kernel.h>
-#include <linux/delay.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 <common.h>
+#include <malloc.h>
+#include <asm/dma-mapping.h>
+#include <usb/lin_gadget_compat.h>
+#include <linux/bug.h>
 #include <linux/list.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
@@ -166,7 +162,6 @@ 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,7 +169,6 @@ 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 */
@@ -232,26 +226,24 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
                int status)
 {
        struct dwc3                     *dwc = dep->dwc;
-       int                             i;
 
        if (req->queued) {
-               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++;
-                       /*
-                        * 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;
+       dwc3_flush_cache((uintptr_t)req->request.dma, req->request.length);
 
        if (req->request.status == -EINPROGRESS)
                req->request.status = status;
@@ -265,7 +257,6 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
        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);
@@ -277,8 +268,6 @@ 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);
 
@@ -304,12 +293,9 @@ 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                     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);
        dwc3_writel(dwc->regs, DWC3_DEPCMDPAR2(ep), params->param2);
@@ -345,17 +331,15 @@ 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(dwc->dev,
-                       sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
-                       &dep->trb_pool_dma, GFP_KERNEL);
+       dep->trb_pool = dma_alloc_coherent(sizeof(struct dwc3_trb) *
+                                          DWC3_TRB_NUM,
+                                          (unsigned long *)&dep->trb_pool_dma);
        if (!dep->trb_pool) {
                dev_err(dep->dwc->dev, "failed to allocate trb pool for %s\n",
                                dep->name);
@@ -367,10 +351,7 @@ static int dwc3_alloc_trb_pool(struct dwc3_ep *dep)
 
 static void dwc3_free_trb_pool(struct dwc3_ep *dep)
 {
-       struct dwc3             *dwc = dep->dwc;
-
-       dma_free_coherent(dwc->dev, sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
-                       dep->trb_pool, dep->trb_pool_dma);
+       dma_free_coherent(dep->trb_pool);
 
        dep->trb_pool = NULL;
        dep->trb_pool_dma = 0;
@@ -612,7 +593,6 @@ 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;
 
@@ -627,10 +607,9 @@ static int dwc3_gadget_ep_enable(struct usb_ep *ep,
        }
 
        dep = to_dwc3_ep(ep);
-       dwc = dep->dwc;
 
        if (dep->flags & DWC3_EP_ENABLED) {
-               dev_WARN_ONCE(dwc->dev, true, "%s is already enabled\n",
+               WARN(true, "%s is already enabled\n",
                                dep->name);
                return 0;
        }
@@ -662,7 +641,6 @@ 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;
 
@@ -672,10 +650,9 @@ static int dwc3_gadget_ep_disable(struct usb_ep *ep)
        }
 
        dep = to_dwc3_ep(ep);
-       dwc = dep->dwc;
 
        if (!(dep->flags & DWC3_EP_ENABLED)) {
-               dev_WARN_ONCE(dwc->dev, true, "%s is already disabled\n",
+               WARN(true, "%s is already disabled\n",
                                dep->name);
                return 0;
        }
@@ -704,8 +681,6 @@ 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;
 }
 
@@ -714,7 +689,6 @@ 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);
 }
 
@@ -727,7 +701,6 @@ 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(dwc->dev, "%s: req %p dma %08llx length %d%s%s\n",
@@ -797,7 +770,8 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
 
        trb->ctrl |= DWC3_TRB_CTRL_HWO;
 
-       trace_dwc3_prepare_trb(dep, trb);
+       dwc3_flush_cache((uintptr_t)dma, length);
+       dwc3_flush_cache((uintptr_t)trb, sizeof(*trb));
 }
 
 /*
@@ -814,7 +788,6 @@ 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);
 
@@ -864,59 +837,14 @@ 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;
-
-               if (req->request.num_mapped_sgs > 0) {
-                       struct usb_request *request = &req->request;
-                       struct scatterlist *sg = request->sg;
-                       struct scatterlist *s;
-                       int             i;
-
-                       for_each_sg(sg, s, request->num_mapped_sgs, i) {
-                               unsigned chain = true;
-
-                               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;
+               dma = req->request.dma;
+               length = req->request.length;
 
-                       /* 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,
+                                    true, false, 0);
 
-                       dwc3_prepare_one_trb(dep, req, dma, length,
-                                       last_one, false, 0);
-
-                       if (last_one)
-                               break;
-               }
+               break;
        }
 }
 
@@ -1034,6 +962,14 @@ 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
@@ -1113,8 +1049,6 @@ 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);
                }
@@ -1128,7 +1062,6 @@ 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;
 
@@ -1142,15 +1075,15 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request,
                goto out;
        }
 
-       if (WARN(req->dep != dep, "request %p belongs to '%s'\n",
-                               request, req->dep->name)) {
+       if (req->dep != dep) {
+               WARN(true, "request %p belongs to '%s'\n",
+                               request, req->dep->name);
                ret = -EINVAL;
                goto out;
        }
 
        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);
 
@@ -1172,8 +1105,6 @@ 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) {
@@ -1252,7 +1183,6 @@ 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;
 
@@ -1268,7 +1198,6 @@ 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;
 
@@ -1384,9 +1313,9 @@ static int dwc3_gadget_wakeup(struct usb_gadget *g)
        }
 
        /* poll until Link State changes to ON */
-       timeout = jiffies + msecs_to_jiffies(100);
+       timeout = 1000;
 
-       while (!time_after(jiffies, timeout)) {
+       while (timeout--) {
                reg = dwc3_readl(dwc->regs, DWC3_DSTS);
 
                /* in HS, means ON */
@@ -1511,9 +1440,6 @@ 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)
 {
@@ -1521,24 +1447,14 @@ 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->driver.name);
+                               dwc->gadget_driver->function);
                ret = -EBUSY;
                goto err1;
        }
@@ -1622,9 +1538,6 @@ err2:
 err1:
        spin_unlock_irqrestore(&dwc->lock, flags);
 
-       free_irq(irq, dwc);
-
-err0:
        return ret;
 }
 
@@ -1632,7 +1545,6 @@ 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);
 
@@ -1644,9 +1556,6 @@ static int dwc3_gadget_stop(struct usb_gadget *g)
 
        spin_unlock_irqrestore(&dwc->lock, flags);
 
-       irq = platform_get_irq(to_platform_device(dwc->dev), 0);
-       free_irq(irq, dwc);
-
        return 0;
 }
 
@@ -1695,7 +1604,7 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc,
                } else {
                        int             ret;
 
-                       usb_ep_set_maxpacket_limit(&dep->endpoint, 1024);
+                       usb_ep_set_maxpacket_limit(&dep->endpoint, 512);
                        dep->endpoint.max_streams = 15;
                        dep->endpoint.ops = &dwc3_gadget_ep_ops;
                        list_add_tail(&dep->endpoint.ep_list,
@@ -1771,8 +1680,6 @@ 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
@@ -1847,35 +1754,23 @@ 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;
 
-       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);
+       req = next_request(&dep->req_queued);
+       if (!req) {
+               WARN_ON_ONCE(1);
+               return 1;
+       }
 
-               dwc3_gadget_giveback(dep, req, status);
+       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];
 
-               if (ret)
-                       break;
-       } while (1);
+       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 (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
                        list_empty(&dep->req_queued)) {
@@ -2308,9 +2203,8 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
                 * BESL value in the LPM token is less than or equal to LPM
                 * NYET threshold.
                 */
-               WARN_ONCE(dwc->revision < DWC3_REVISION_240A
-                               && dwc->has_lpm_erratum,
-                               "LPM Erratum not available on dwc3 revisisions < 2.40a\n");
+               if (dwc->revision < DWC3_REVISION_240A  && dwc->has_lpm_erratum)
+                       WARN(true, "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);
@@ -2459,7 +2353,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 & BIT(4);
+       unsigned int is_ss = evtinfo & (1UL << 4);
 
        /**
         * WORKAROUND: DWC3 revison 2.20a with hibernation support
@@ -2497,10 +2391,10 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc,
                dwc3_gadget_wakeup_interrupt(dwc);
                break;
        case DWC3_DEVICE_EVENT_HIBER_REQ:
-               if (dev_WARN_ONCE(dwc->dev, !dwc->has_hibernation,
-                                       "unexpected hibernation event\n"))
+               if (!dwc->has_hibernation) {
+                       WARN(1 ,"unexpected hibernation event\n");
                        break;
-
+               }
                dwc3_gadget_hibernation_interrupt(dwc, event->event_info);
                break;
        case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:
@@ -2529,8 +2423,6 @@ 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 */
@@ -2666,31 +2558,31 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 {
        int                                     ret;
 
-       dwc->ctrl_req = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
-                       &dwc->ctrl_req_addr, GFP_KERNEL);
+       dwc->ctrl_req = dma_alloc_coherent(sizeof(*dwc->ctrl_req),
+                                       (unsigned long *)&dwc->ctrl_req_addr);
        if (!dwc->ctrl_req) {
                dev_err(dwc->dev, "failed to allocate ctrl request\n");
                ret = -ENOMEM;
                goto err0;
        }
 
-       dwc->ep0_trb = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
-                       &dwc->ep0_trb_addr, GFP_KERNEL);
+       dwc->ep0_trb = dma_alloc_coherent(sizeof(*dwc->ep0_trb) * 2,
+                                         (unsigned long *)&dwc->ep0_trb_addr);
        if (!dwc->ep0_trb) {
                dev_err(dwc->dev, "failed to allocate ep0 trb\n");
                ret = -ENOMEM;
                goto err1;
        }
 
-       dwc->setup_buf = kzalloc(DWC3_EP0_BOUNCE_SIZE, GFP_KERNEL);
+       dwc->setup_buf = memalign(CONFIG_SYS_CACHELINE_SIZE,
+                                 DWC3_EP0_BOUNCE_SIZE);
        if (!dwc->setup_buf) {
                ret = -ENOMEM;
                goto err2;
        }
 
-       dwc->ep0_bounce = dma_alloc_coherent(dwc->dev,
-                       DWC3_EP0_BOUNCE_SIZE, &dwc->ep0_bounce_addr,
-                       GFP_KERNEL);
+       dwc->ep0_bounce = dma_alloc_coherent(DWC3_EP0_BOUNCE_SIZE,
+                                       (unsigned long *)&dwc->ep0_bounce_addr);
        if (!dwc->ep0_bounce) {
                dev_err(dwc->dev, "failed to allocate ep0 bounce buffer\n");
                ret = -ENOMEM;
@@ -2700,7 +2592,6 @@ 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";
 
        /*
@@ -2728,19 +2619,16 @@ int dwc3_gadget_init(struct dwc3 *dwc)
 
 err4:
        dwc3_gadget_free_endpoints(dwc);
-       dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
-                       dwc->ep0_bounce, dwc->ep0_bounce_addr);
+       dma_free_coherent(dwc->ep0_bounce);
 
 err3:
        kfree(dwc->setup_buf);
 
 err2:
-       dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
-                       dwc->ep0_trb, dwc->ep0_trb_addr);
+       dma_free_coherent(dwc->ep0_trb);
 
 err1:
-       dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
-                       dwc->ctrl_req, dwc->ctrl_req_addr);
+       dma_free_coherent(dwc->ctrl_req);
 
 err0:
        return ret;
@@ -2754,69 +2642,37 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
 
        dwc3_gadget_free_endpoints(dwc);
 
-       dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
-                       dwc->ep0_bounce, dwc->ep0_bounce_addr);
+       dma_free_coherent(dwc->ep0_bounce);
 
        kfree(dwc->setup_buf);
 
-       dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
-                       dwc->ep0_trb, dwc->ep0_trb_addr);
+       dma_free_coherent(dwc->ep0_trb);
 
-       dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
-                       dwc->ctrl_req, dwc->ctrl_req_addr);
+       dma_free_coherent(dwc->ctrl_req);
 }
 
-int dwc3_gadget_suspend(struct dwc3 *dwc)
+/**
+ * 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)
 {
-       if (dwc->pullups_connected) {
-               dwc3_gadget_disable_irq(dwc);
-               dwc3_gadget_run_stop(dwc, true, true);
-       }
-
-       __dwc3_gadget_ep_disable(dwc->eps[0]);
-       __dwc3_gadget_ep_disable(dwc->eps[1]);
+       int ret = dwc3_interrupt(0, dwc);
 
-       dwc->dcfg = dwc3_readl(dwc->regs, DWC3_DCFG);
-
-       return 0;
-}
+       if (ret == IRQ_WAKE_THREAD) {
+               int i;
+               struct dwc3_event_buffer *evt;
 
-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);
+               dwc3_thread_interrupt(0, dwc);
 
-       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);
+               /* 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;
-
-err1:
-       __dwc3_gadget_ep_disable(dwc->eps[0]);
-
-err0:
-       return ret;
 }