When device cable is disconnected core receives suspend interrupt and enters hibernation. After entering into hibernation GPWRDN_RST_DET and GPWRDN_STS_CHGINT interrupts are asserted. >From cable disconnection we need to exit from hibernation either by GPWRDN_RST_DET or GPWRDN_STS_CHGINT. If we exit from hibernation by GPWRDN_STS_CHGINT, DEVADDR will not be reset. But we need to exit gadget hibernation properly with resetting the DEVADDR as reset accrued. - Allowed exit from gadget hibernation from GPWRDN_RST_DET by checking only linestate. - Setting hsotg->lx_state = DWC2_L0 in dwc2_hsotg_irq GINTSTS_RESETDET flow without checking if lx_state == DWC2_L2 Signed-off-by: Artur Petrosyan <arturp@xxxxxxxxxxxx> --- drivers/usb/dwc2/core_intr.c | 2 +- drivers/usb/dwc2/gadget.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 40d296d9b6fb..cb827a5e1bfb 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -771,7 +771,7 @@ static void dwc2_handle_gpwrdn_intr(struct dwc2_hsotg *hsotg) if ((gpwrdn & GPWRDN_RST_DET) && (gpwrdn & GPWRDN_RST_DET_MSK)) { dev_dbg(hsotg->dev, "%s: GPWRDN_RST_DET\n", __func__); - if (!linestate && (gpwrdn & GPWRDN_BSESSVLD)) + if (!linestate) dwc2_exit_hibernation(hsotg, 0, 1, 0); } diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 8c3e1f1c1b0f..b35c966d4f63 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3637,8 +3637,8 @@ static irqreturn_t dwc2_hsotg_irq(int irq, void *pw) /* This event must be used only if controller is suspended */ if (hsotg->lx_state == DWC2_L2) { dwc2_exit_partial_power_down(hsotg, true); - hsotg->lx_state = DWC2_L0; } + hsotg->lx_state = DWC2_L0; } if (gintsts & (GINTSTS_USBRST | GINTSTS_RESETDET)) { -- 2.11.0