Message ID | 75f383c94960b2c1305304bb380e6b6504c67262.1626085155.git.Minas.Harutyunyan@synopsys.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | usb: dwc2: gadget: Fix GOUTNAK flow for Slave mode. | expand |
On Mon, Jul 12, 2021 at 02:22:09PM +0400, Minas Harutyunyan wrote: > Because of dwc2_hsotg_ep_stop_xfr() function uses poll > mode, first need to mask GINTSTS_GOUTNAKEFF interrupt. > In Slave mode GINTSTS_GOUTNAKEFF interrupt will be > aserted only after pop OUT NAK status packet from RxFIFO. > > In dwc2_hsotg_ep_sethalt() function before setting > DCTL_SGOUTNAK need to unmask GOUTNAKEFF interrupt. > > Tested by USBCV CH9 and MSC tests set in Slave, BDMA and DDMA. > All tests are passed. > > Fixes: a4f827714539a ("usb: dwc2: gadget: Disable enabled HW endpoint in > dwc2_hsotg_ep_disable") Please do not wrap this line. > Fixes: 6070636c4918c ("usb: dwc2: Fix Stalling a Non-Isochronous OUT EP") > No need for a blank line there please. thanks, gre gk-h
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 7352f2720963..77d595738bdd 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3903,9 +3903,27 @@ static void dwc2_hsotg_ep_stop_xfr(struct dwc2_hsotg *hsotg, __func__); } } else { + /* Mask GINTSTS_GOUTNAKEFF interrupt */ + dwc2_hsotg_disable_gsint(hsotg, GINTSTS_GOUTNAKEFF); + if (!(dwc2_readl(hsotg, GINTSTS) & GINTSTS_GOUTNAKEFF)) dwc2_set_bit(hsotg, DCTL, DCTL_SGOUTNAK); + if (!using_dma(hsotg)) { + /* Wait for GINTSTS_RXFLVL interrupt */ + if (dwc2_hsotg_wait_bit_set(hsotg, GINTSTS, + GINTSTS_RXFLVL, 100)) { + dev_warn(hsotg->dev, "%s: timeout GINTSTS.RXFLVL\n", + __func__); + } else { + /* + * Pop GLOBAL OUT NAK status packet from RxFIFO + * to assert GOUTNAKEFF interrupt + */ + dwc2_readl(hsotg, GRXSTSP); + } + } + /* Wait for global nak to take effect */ if (dwc2_hsotg_wait_bit_set(hsotg, GINTSTS, GINTSTS_GOUTNAKEFF, 100)) @@ -4374,6 +4392,9 @@ static int dwc2_hsotg_ep_sethalt(struct usb_ep *ep, int value, bool now) epctl = dwc2_readl(hs, epreg); if (value) { + /* Unmask GOUTNAKEFF interrupt */ + dwc2_hsotg_en_gsint(hs, GINTSTS_GOUTNAKEFF); + if (!(dwc2_readl(hs, GINTSTS) & GINTSTS_GOUTNAKEFF)) dwc2_set_bit(hs, DCTL, DCTL_SGOUTNAK); // STALL bit will be set in GOUTNAKEFF interrupt handler
Because of dwc2_hsotg_ep_stop_xfr() function uses poll mode, first need to mask GINTSTS_GOUTNAKEFF interrupt. In Slave mode GINTSTS_GOUTNAKEFF interrupt will be aserted only after pop OUT NAK status packet from RxFIFO. In dwc2_hsotg_ep_sethalt() function before setting DCTL_SGOUTNAK need to unmask GOUTNAKEFF interrupt. Tested by USBCV CH9 and MSC tests set in Slave, BDMA and DDMA. All tests are passed. Fixes: a4f827714539a ("usb: dwc2: gadget: Disable enabled HW endpoint in dwc2_hsotg_ep_disable") Fixes: 6070636c4918c ("usb: dwc2: Fix Stalling a Non-Isochronous OUT EP") Signed-off-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com> --- drivers/usb/dwc2/gadget.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) base-commit: 3143ea6b8eee08761709a6c2788216292be46a34