diff options
Diffstat (limited to 'drivers/usb/dwc2/gadget.c')
| -rw-r--r-- | drivers/usb/dwc2/gadget.c | 26 | 
1 files changed, 16 insertions, 10 deletions
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index e4c3ce0de5de..5bcad1d869b5 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -1917,7 +1917,9 @@ static void dwc2_hsotg_program_zlp(struct dwc2_hsotg *hsotg,  		/* Not specific buffer needed for ep0 ZLP */  		dma_addr_t dma = hs_ep->desc_list_dma; -		dwc2_gadget_set_ep0_desc_chain(hsotg, hs_ep); +		if (!index) +			dwc2_gadget_set_ep0_desc_chain(hsotg, hs_ep); +  		dwc2_gadget_config_nonisoc_xfer_ddma(hs_ep, dma, 0);  	} else {  		dwc2_writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) | @@ -2974,9 +2976,13 @@ static void dwc2_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx,  	if (ints & DXEPINT_STSPHSERCVD) {  		dev_dbg(hsotg->dev, "%s: StsPhseRcvd\n", __func__); -		/* Move to STATUS IN for DDMA */ -		if (using_desc_dma(hsotg)) -			dwc2_hsotg_ep0_zlp(hsotg, true); +		/* Safety check EP0 state when STSPHSERCVD asserted */ +		if (hsotg->ep0_state == DWC2_EP0_DATA_OUT) { +			/* Move to STATUS IN for DDMA */ +			if (using_desc_dma(hsotg)) +				dwc2_hsotg_ep0_zlp(hsotg, true); +		} +  	}  	if (ints & DXEPINT_BACK2BACKSETUP) @@ -3375,12 +3381,6 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,  	dwc2_writel(dwc2_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) |  	       DXEPCTL_USBACTEP, hsotg->regs + DIEPCTL0); -	dwc2_hsotg_enqueue_setup(hsotg); - -	dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n", -		dwc2_readl(hsotg->regs + DIEPCTL0), -		dwc2_readl(hsotg->regs + DOEPCTL0)); -  	/* clear global NAKs */  	val = DCTL_CGOUTNAK | DCTL_CGNPINNAK;  	if (!is_usb_reset) @@ -3391,6 +3391,12 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,  	mdelay(3);  	hsotg->lx_state = DWC2_L0; + +	dwc2_hsotg_enqueue_setup(hsotg); + +	dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n", +		dwc2_readl(hsotg->regs + DIEPCTL0), +		dwc2_readl(hsotg->regs + DOEPCTL0));  }  static void dwc2_hsotg_core_disconnect(struct dwc2_hsotg *hsotg)  |