diff mbox

[U-Boot,u-boot,15/40] usb: dwc3: gadget: make dwc3 gadget build in uboot

Message ID 1423212497-11970-16-git-send-email-kishon@ti.com
State Accepted
Delegated to: Łukasz Majewski
Headers show

Commit Message

Kishon Vijay Abraham I Feb. 6, 2015, 8:47 a.m. UTC
Did a bunch of things to get dwc3/gadget.c compile in u-boot without
build errors and warnings
*) Changed the included header files to that used in u-boot.
*) Used dma_alloc_coherent and dma_free_coherent APIs of u-boot
*) removed sg support
*) remove jiffies and used a simple while loop
*) removed irq support and added a function to call these interrupt handler.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/usb/dwc3/gadget.c       |  244 ++++++++++++++-------------------------
 drivers/usb/dwc3/gadget.h       |    1 +
 drivers/usb/dwc3/linux-compat.h |    3 -
 include/linux/compat.h          |    1 +
 include/linux/usb/gadget.h      |   39 +++++++
 5 files changed, 125 insertions(+), 163 deletions(-)

Comments

Łukasz Majewski Feb. 16, 2015, 10:52 a.m. UTC | #1
Hi Kishon,

> Did a bunch of things to get dwc3/gadget.c compile in u-boot without
> build errors and warnings
> *) Changed the included header files to that used in u-boot.
> *) Used dma_alloc_coherent and dma_free_coherent APIs of u-boot
> *) removed sg support
> *) remove jiffies and used a simple while loop
> *) removed irq support and added a function to call these interrupt
> handler.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
>  drivers/usb/dwc3/gadget.c       |  244
> ++++++++++++++-------------------------
> drivers/usb/dwc3/gadget.h       |    1 +
> drivers/usb/dwc3/linux-compat.h |    3 -
> include/linux/compat.h          |    1 +
> include/linux/usb/gadget.h      |   39 +++++++ 5 files changed, 125
> insertions(+), 163 deletions(-)
> 
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index 7c932c6..1f97729 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -14,25 +14,22 @@
>   * 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/list.h>
> -#include <linux/dma-mapping.h>
>  
>  #include <linux/usb/ch9.h>
>  #include <linux/usb/gadget.h>
> +#include <asm/arch/sys_proto.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 +163,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 +170,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,24 +227,21 @@ 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;
>  
> @@ -301,7 +293,6 @@ 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;
>  
> @@ -340,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);
> @@ -362,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;
> @@ -607,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;
>  
> @@ -622,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;
>  	}
> @@ -657,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;
>  
> @@ -667,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;
>  	}
> @@ -719,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",
> @@ -856,57 +837,22 @@ static void dwc3_prepare_trbs(struct dwc3_ep
> *dep, bool starting) 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;
> +		dma = req->request.dma;
> +		length = req->request.length;
> +		trbs_left--;
>  
> -				length = sg_dma_len(s);
> -				dma = sg_dma_address(s);
> +		if (!trbs_left)
> +			last_one = 1;
>  
> -				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;
> -				}
> +		/* Is this the last request? */
> +		if (list_is_last(&req->list, &dep->request_list))
> +			last_one = 1;
>  
> -				trbs_left--;
> -				if (!trbs_left)
> -					last_one = true;
> +		dwc3_prepare_one_trb(dep, req, dma, length,
> +				last_one, false, 0);
>  
> -				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;
> -		}
> +		if (last_one)
> +			break;
>  	}
>  }
>  
> @@ -1103,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);
>  		}
> @@ -1118,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;
>  
> @@ -1132,8 +1075,9 @@ 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;
>  	}
> @@ -1239,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;
>  
> @@ -1255,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;
>  
> @@ -1371,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 */
> @@ -1498,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)
>  {
> @@ -1508,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;
>  	}
> @@ -1609,9 +1538,6 @@ err2:
>  err1:
>  	spin_unlock_irqrestore(&dwc->lock, flags);
>  
> -	free_irq(irq, dwc);
> -
> -err0:
>  	return ret;
>  }
>  
> @@ -1619,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);
>  
> @@ -1631,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;
>  }
>  
> @@ -1832,7 +1754,6 @@ 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 {
> @@ -1841,20 +1762,18 @@ static int dwc3_cleanup_done_reqs(struct dwc3
> *dwc, struct dwc3_ep *dep, 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];
> +
> +		ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb,
> +				event, status);
> +		if (ret)
> +			break;
>  
>  		dwc3_gadget_giveback(dep, req, status);
>  
> @@ -2293,9 +2212,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); @@ -2482,10 +2400,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:
> @@ -2649,16 +2567,16 @@ 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),
> +					  (unsigned long
> *)&dwc->ep0_trb_addr); if (!dwc->ep0_trb) {
>  		dev_err(dwc->dev, "failed to allocate ep0 trb\n");
>  		ret = -ENOMEM;
> @@ -2671,9 +2589,8 @@ int dwc3_gadget_init(struct dwc3 *dwc)
>  		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;
> @@ -2683,7 +2600,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";
>  
>  	/*
> @@ -2711,19 +2627,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;
> @@ -2737,14 +2650,25 @@ 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);
> +}
> +
> +/**
> + * 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)
> +{
> +	dwc3_interrupt(0, dwc);
> +	dwc3_thread_interrupt(0, dwc);
>  }
> diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
> index 042e247..c7db219 100644
> --- a/drivers/usb/dwc3/gadget.h
> +++ b/drivers/usb/dwc3/gadget.h
> @@ -87,6 +87,7 @@ 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/linux-compat.h
> b/drivers/usb/dwc3/linux-compat.h index 58c4716..719e82e 100644
> --- a/drivers/usb/dwc3/linux-compat.h
> +++ b/drivers/usb/dwc3/linux-compat.h
> @@ -5,9 +5,6 @@
>   *
>   * Authors: Kishon Vijay Abraham I <kishon@ti.com>
>   *
> - * Taken from Linux Kernel v3.16 (drivers/usb/dwc3/core.c) and ported
> - * to uboot.
> - *
>   * SPDX-License-Identifier:	GPL-2.0
>   *
>   */
> diff --git a/include/linux/compat.h b/include/linux/compat.h
> index b40133c..904425a 100644
> --- a/include/linux/compat.h
> +++ b/include/linux/compat.h
> @@ -327,6 +327,7 @@ typedef unsigned long dmaaddr_t;
>  
>  #define IRQ_NONE 0
>  #define IRQ_HANDLED 1
> +#define IRQ_WAKE_THREAD 2
>  
>  #define dev_set_drvdata(dev, data) do {} while (0)
>  
> diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
> index 1960958..93a5ffc 100644
> --- a/include/linux/usb/gadget.h
> +++ b/include/linux/usb/gadget.h
> @@ -31,6 +31,7 @@ struct usb_ep;
>   * @dma: DMA address corresponding to 'buf'.  If you don't set this
>   *	field, and the usb controller needs one, it is responsible
>   *	for mapping and unmapping the buffer.
> + * @stream_id: The stream id, when USB3.0 bulk streams are being used
>   * @length: Length of that data
>   * @no_interrupt: If true, hints that no completion irq is needed.
>   *	Helpful sometimes with deep request queues that are handled
> @@ -85,6 +86,7 @@ struct usb_request {
>  	unsigned		length;
>  	dma_addr_t		dma;
>  
> +	unsigned		stream_id:16;
>  	unsigned		no_interrupt:1;
>  	unsigned		zero:1;
>  	unsigned		short_not_ok:1;
> @@ -121,6 +123,7 @@ struct usb_ep_ops {
>  	int (*dequeue) (struct usb_ep *ep, struct usb_request *req);
>  
>  	int (*set_halt) (struct usb_ep *ep, int value);
> +	int (*set_wedge)(struct usb_ep *ep);
>  	int (*fifo_status) (struct usb_ep *ep);
>  	void (*fifo_flush) (struct usb_ep *ep);
>  };
> @@ -133,8 +136,18 @@ struct usb_ep_ops {
>   * @maxpacket:The maximum packet size used on this endpoint.  The
> initial
>   *	value can sometimes be reduced (hardware allowing),
> according to
>   *      the endpoint descriptor used to configure the endpoint.
> + * @maxpacket_limit:The maximum packet size value which can be
> handled by this
> + *	endpoint. It's set once by UDC driver when endpoint is
> initialized, and
> + *	should not be changed. Should not be confused with
> maxpacket.
> + * @max_streams: The maximum number of streams supported
> + * 	by this EP (0 - 16, actual number is 2^n)
> + * @maxburst: the maximum number of bursts supported by this EP (for
> usb3)
>   * @driver_data:for use by the gadget driver.  all other fields are
>   *	read-only to gadget drivers.
> + * @desc: endpoint descriptor.  This pointer is set before the
> endpoint is
> + * 	enabled and remains valid until the endpoint is disabled.
> + * @comp_desc: In case of SuperSpeed support, this is the endpoint
> companion
> + * 	descriptor that is used to configure the endpoint
>   *
>   * the bus controller driver lists all the general purpose endpoints
> in
>   * gadget->ep_list.  the control endpoint (gadget->ep0) is not in
> that list, @@ -146,11 +159,31 @@ struct usb_ep {
>  	const struct usb_ep_ops	*ops;
>  	struct list_head	ep_list;
>  	unsigned		maxpacket:16;
> +	unsigned		maxpacket_limit:16;
> +	unsigned		max_streams:16;
> +	unsigned		maxburst:5;
> +	const struct usb_endpoint_descriptor	*desc;
> +	const struct usb_ss_ep_comp_descriptor	*comp_desc;
>  };
>  
>  /*-------------------------------------------------------------------------*/
>  
>  /**
> + * usb_ep_set_maxpacket_limit - set maximum packet size limit for
> endpoint
> + * @ep:the endpoint being configured
> + * @maxpacket_limit:value of maximum packet size limit
> + *
> + * This function shoud be used only in UDC drivers to initialize
> endpoint
> + * (usually in probe function).
> + */
> +static inline void usb_ep_set_maxpacket_limit(struct usb_ep *ep,
> +					      unsigned
> maxpacket_limit) +{
> +	ep->maxpacket_limit = maxpacket_limit;
> +	ep->maxpacket = maxpacket_limit;
> +}
> +
> +/**
>   * usb_ep_enable - configure endpoint, making it usable
>   * @ep:the endpoint being configured.  may not be the endpoint named
> "ep0".
>   *	drivers discover endpoints through the ep_list of a
> usb_gadget. @@ -422,6 +455,8 @@ struct usb_gadget_ops {
>   *	driver setup() requests
>   * @ep_list: List of other endpoints supported by the device.
>   * @speed: Speed of current connection to USB host.
> + * @max_speed: Maximal speed the UDC can handle.  UDC must support
> this
> + *      and all slower speeds.
>   * @is_dualspeed: true if the controller supports both high and full
> speed
>   *	operation.  If it does, the gadget driver must also
> support both.
>   * @is_otg: true if the USB device port uses a Mini-AB jack, so that
> the @@ -438,6 +473,8 @@ struct usb_gadget_ops {
>   * @name: Identifies the controller hardware type.  Used in
> diagnostics
>   *	and sometimes configuration.
>   * @dev: Driver model state for this abstract device.
> + * @quirk_ep_out_aligned_size: epout requires buffer size to be
> aligned to
> + *	MaxPacketSize.
>   *
>   * Gadgets have a mostly-portable "gadget driver" implementing device
>   * functions, handling all usb configurations and interfaces.  Gadget
> @@ -463,6 +500,7 @@ struct usb_gadget {
>  	struct usb_ep			*ep0;
>  	struct list_head		ep_list;	/* of usb_ep
> */ enum usb_device_speed		speed;
> +	enum usb_device_speed		max_speed;
>  	enum usb_device_state		state;
>  	unsigned			is_dualspeed:1;
>  	unsigned			is_otg:1;
> @@ -472,6 +510,7 @@ struct usb_gadget {
>  	unsigned			a_alt_hnp_support:1;
>  	const char			*name;
>  	struct device			dev;
> +	unsigned			quirk_ep_out_aligned_size:1;
>  };
>  
>  static inline void set_gadget_data(struct usb_gadget *gadget, void
> *data)

Reviewed-by: Lukasz Majewski <l.majewski@samsung.com>
diff mbox

Patch

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 7c932c6..1f97729 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -14,25 +14,22 @@ 
  * 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/list.h>
-#include <linux/dma-mapping.h>
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
+#include <asm/arch/sys_proto.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 +163,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 +170,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,24 +227,21 @@  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;
 
@@ -301,7 +293,6 @@  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;
 
@@ -340,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);
@@ -362,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;
@@ -607,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;
 
@@ -622,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;
 	}
@@ -657,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;
 
@@ -667,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;
 	}
@@ -719,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",
@@ -856,57 +837,22 @@  static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)
 		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;
+		dma = req->request.dma;
+		length = req->request.length;
+		trbs_left--;
 
-				length = sg_dma_len(s);
-				dma = sg_dma_address(s);
+		if (!trbs_left)
+			last_one = 1;
 
-				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;
-				}
+		/* Is this the last request? */
+		if (list_is_last(&req->list, &dep->request_list))
+			last_one = 1;
 
-				trbs_left--;
-				if (!trbs_left)
-					last_one = true;
+		dwc3_prepare_one_trb(dep, req, dma, length,
+				last_one, false, 0);
 
-				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;
-		}
+		if (last_one)
+			break;
 	}
 }
 
@@ -1103,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);
 		}
@@ -1118,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;
 
@@ -1132,8 +1075,9 @@  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;
 	}
@@ -1239,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;
 
@@ -1255,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;
 
@@ -1371,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 */
@@ -1498,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)
 {
@@ -1508,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;
 	}
@@ -1609,9 +1538,6 @@  err2:
 err1:
 	spin_unlock_irqrestore(&dwc->lock, flags);
 
-	free_irq(irq, dwc);
-
-err0:
 	return ret;
 }
 
@@ -1619,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);
 
@@ -1631,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;
 }
 
@@ -1832,7 +1754,6 @@  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 {
@@ -1841,20 +1762,18 @@  static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
 			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];
+
+		ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb,
+				event, status);
+		if (ret)
+			break;
 
 		dwc3_gadget_giveback(dep, req, status);
 
@@ -2293,9 +2212,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);
@@ -2482,10 +2400,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:
@@ -2649,16 +2567,16 @@  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),
+					  (unsigned long *)&dwc->ep0_trb_addr);
 	if (!dwc->ep0_trb) {
 		dev_err(dwc->dev, "failed to allocate ep0 trb\n");
 		ret = -ENOMEM;
@@ -2671,9 +2589,8 @@  int dwc3_gadget_init(struct dwc3 *dwc)
 		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;
@@ -2683,7 +2600,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";
 
 	/*
@@ -2711,19 +2627,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;
@@ -2737,14 +2650,25 @@  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);
+}
+
+/**
+ * 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)
+{
+	dwc3_interrupt(0, dwc);
+	dwc3_thread_interrupt(0, dwc);
 }
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
index 042e247..c7db219 100644
--- a/drivers/usb/dwc3/gadget.h
+++ b/drivers/usb/dwc3/gadget.h
@@ -87,6 +87,7 @@  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/linux-compat.h b/drivers/usb/dwc3/linux-compat.h
index 58c4716..719e82e 100644
--- a/drivers/usb/dwc3/linux-compat.h
+++ b/drivers/usb/dwc3/linux-compat.h
@@ -5,9 +5,6 @@ 
  *
  * Authors: Kishon Vijay Abraham I <kishon@ti.com>
  *
- * Taken from Linux Kernel v3.16 (drivers/usb/dwc3/core.c) and ported
- * to uboot.
- *
  * SPDX-License-Identifier:	GPL-2.0
  *
  */
diff --git a/include/linux/compat.h b/include/linux/compat.h
index b40133c..904425a 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -327,6 +327,7 @@  typedef unsigned long dmaaddr_t;
 
 #define IRQ_NONE 0
 #define IRQ_HANDLED 1
+#define IRQ_WAKE_THREAD 2
 
 #define dev_set_drvdata(dev, data) do {} while (0)
 
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 1960958..93a5ffc 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -31,6 +31,7 @@  struct usb_ep;
  * @dma: DMA address corresponding to 'buf'.  If you don't set this
  *	field, and the usb controller needs one, it is responsible
  *	for mapping and unmapping the buffer.
+ * @stream_id: The stream id, when USB3.0 bulk streams are being used
  * @length: Length of that data
  * @no_interrupt: If true, hints that no completion irq is needed.
  *	Helpful sometimes with deep request queues that are handled
@@ -85,6 +86,7 @@  struct usb_request {
 	unsigned		length;
 	dma_addr_t		dma;
 
+	unsigned		stream_id:16;
 	unsigned		no_interrupt:1;
 	unsigned		zero:1;
 	unsigned		short_not_ok:1;
@@ -121,6 +123,7 @@  struct usb_ep_ops {
 	int (*dequeue) (struct usb_ep *ep, struct usb_request *req);
 
 	int (*set_halt) (struct usb_ep *ep, int value);
+	int (*set_wedge)(struct usb_ep *ep);
 	int (*fifo_status) (struct usb_ep *ep);
 	void (*fifo_flush) (struct usb_ep *ep);
 };
@@ -133,8 +136,18 @@  struct usb_ep_ops {
  * @maxpacket:The maximum packet size used on this endpoint.  The initial
  *	value can sometimes be reduced (hardware allowing), according to
  *      the endpoint descriptor used to configure the endpoint.
+ * @maxpacket_limit:The maximum packet size value which can be handled by this
+ *	endpoint. It's set once by UDC driver when endpoint is initialized, and
+ *	should not be changed. Should not be confused with maxpacket.
+ * @max_streams: The maximum number of streams supported
+ * 	by this EP (0 - 16, actual number is 2^n)
+ * @maxburst: the maximum number of bursts supported by this EP (for usb3)
  * @driver_data:for use by the gadget driver.  all other fields are
  *	read-only to gadget drivers.
+ * @desc: endpoint descriptor.  This pointer is set before the endpoint is
+ * 	enabled and remains valid until the endpoint is disabled.
+ * @comp_desc: In case of SuperSpeed support, this is the endpoint companion
+ * 	descriptor that is used to configure the endpoint
  *
  * the bus controller driver lists all the general purpose endpoints in
  * gadget->ep_list.  the control endpoint (gadget->ep0) is not in that list,
@@ -146,11 +159,31 @@  struct usb_ep {
 	const struct usb_ep_ops	*ops;
 	struct list_head	ep_list;
 	unsigned		maxpacket:16;
+	unsigned		maxpacket_limit:16;
+	unsigned		max_streams:16;
+	unsigned		maxburst:5;
+	const struct usb_endpoint_descriptor	*desc;
+	const struct usb_ss_ep_comp_descriptor	*comp_desc;
 };
 
 /*-------------------------------------------------------------------------*/
 
 /**
+ * usb_ep_set_maxpacket_limit - set maximum packet size limit for endpoint
+ * @ep:the endpoint being configured
+ * @maxpacket_limit:value of maximum packet size limit
+ *
+ * This function shoud be used only in UDC drivers to initialize endpoint
+ * (usually in probe function).
+ */
+static inline void usb_ep_set_maxpacket_limit(struct usb_ep *ep,
+					      unsigned maxpacket_limit)
+{
+	ep->maxpacket_limit = maxpacket_limit;
+	ep->maxpacket = maxpacket_limit;
+}
+
+/**
  * usb_ep_enable - configure endpoint, making it usable
  * @ep:the endpoint being configured.  may not be the endpoint named "ep0".
  *	drivers discover endpoints through the ep_list of a usb_gadget.
@@ -422,6 +455,8 @@  struct usb_gadget_ops {
  *	driver setup() requests
  * @ep_list: List of other endpoints supported by the device.
  * @speed: Speed of current connection to USB host.
+ * @max_speed: Maximal speed the UDC can handle.  UDC must support this
+ *      and all slower speeds.
  * @is_dualspeed: true if the controller supports both high and full speed
  *	operation.  If it does, the gadget driver must also support both.
  * @is_otg: true if the USB device port uses a Mini-AB jack, so that the
@@ -438,6 +473,8 @@  struct usb_gadget_ops {
  * @name: Identifies the controller hardware type.  Used in diagnostics
  *	and sometimes configuration.
  * @dev: Driver model state for this abstract device.
+ * @quirk_ep_out_aligned_size: epout requires buffer size to be aligned to
+ *	MaxPacketSize.
  *
  * Gadgets have a mostly-portable "gadget driver" implementing device
  * functions, handling all usb configurations and interfaces.  Gadget
@@ -463,6 +500,7 @@  struct usb_gadget {
 	struct usb_ep			*ep0;
 	struct list_head		ep_list;	/* of usb_ep */
 	enum usb_device_speed		speed;
+	enum usb_device_speed		max_speed;
 	enum usb_device_state		state;
 	unsigned			is_dualspeed:1;
 	unsigned			is_otg:1;
@@ -472,6 +510,7 @@  struct usb_gadget {
 	unsigned			a_alt_hnp_support:1;
 	const char			*name;
 	struct device			dev;
+	unsigned			quirk_ep_out_aligned_size:1;
 };
 
 static inline void set_gadget_data(struct usb_gadget *gadget, void *data)