Currently, the fifo gets re-init, with a running DMA, e.g. when using_desc_dma(): - dwc2_hsotg_init_fifo -> Flushes the FIFO, DMA may run in parallel - DCFG_DESCDMA_EN gets cleared (e.g. disables dma desc) - then DCFG_DESCDMA_EN gets set back again. So move the dwc2_hsotg_init_fifo() call after DCFG_DESCDMA_EN gets cleared e.g. DCFG write. Then the FIFO can be flushed safely, before DCFG_DESCDMA_EN is set back on. A BNA interrupt may happen on EP0, before this change. When it happens we can't recover to a working device. Fixes: a5c18f113150 ("usb: dwc2: gadget: Enable descriptor DMA mode") Cc: stable@vger.kernel.org Acked-by: Thinh Nguyen Signed-off-by: Fabrice Gasnier --- Changes in v2: - Update Fixes tag and collect Thinh's Acked-by tag. --- drivers/usb/dwc2/gadget.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 6c8a9f05fff0..bdabf3c39da1 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3486,8 +3486,6 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, dwc2_phy_init(hsotg, true); - dwc2_hsotg_init_fifo(hsotg); - if (!is_usb_reset) { dwc2_set_bit(hsotg, DCTL, DCTL_SFTDISCON); if (hsotg->params.eusb2_disc) @@ -3515,6 +3513,8 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, dwc2_writel(hsotg, dcfg, DCFG); + dwc2_hsotg_init_fifo(hsotg); + /* Clear any pending OTG interrupts */ dwc2_writel(hsotg, 0xffffffff, GOTGINT); -- 2.43.0