diff options
Diffstat (limited to 'drivers/usb/cdns3')
| -rw-r--r-- | drivers/usb/cdns3/cdns3-gadget.c | 12 | 
1 files changed, 12 insertions, 0 deletions
| diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c index 5adcb349718c..ccfaebca6faa 100644 --- a/drivers/usb/cdns3/cdns3-gadget.c +++ b/drivers/usb/cdns3/cdns3-gadget.c @@ -2614,6 +2614,7 @@ int cdns3_gadget_ep_dequeue(struct usb_ep *ep,  	u8 req_on_hw_ring = 0;  	unsigned long flags;  	int ret = 0; +	int val;  	if (!ep || !request || !ep->desc)  		return -EINVAL; @@ -2649,6 +2650,13 @@ found:  	/* Update ring only if removed request is on pending_req_list list */  	if (req_on_hw_ring && link_trb) { +		/* Stop DMA */ +		writel(EP_CMD_DFLUSH, &priv_dev->regs->ep_cmd); + +		/* wait for DFLUSH cleared */ +		readl_poll_timeout_atomic(&priv_dev->regs->ep_cmd, val, +					  !(val & EP_CMD_DFLUSH), 1, 1000); +  		link_trb->buffer = cpu_to_le32(TRB_BUFFER(priv_ep->trb_pool_dma +  			((priv_req->end_trb + 1) * TRB_SIZE)));  		link_trb->control = cpu_to_le32((le32_to_cpu(link_trb->control) & TRB_CYCLE) | @@ -2660,6 +2668,10 @@ found:  	cdns3_gadget_giveback(priv_ep, priv_req, -ECONNRESET); +	req = cdns3_next_request(&priv_ep->pending_req_list); +	if (req) +		cdns3_rearm_transfer(priv_ep, 1); +  not_found:  	spin_unlock_irqrestore(&priv_dev->lock, flags);  	return ret; | 
