From 9bbf449b9608fce3bb437a6f168080565a940d68 Mon Sep 17 00:00:00 2001 From: Pratham Pratap Date: Thu, 21 Jan 2021 23:05:58 +0530 Subject: [PATCH] usb: dwc3: Clear err_evt_seen flag on disconnect Currently err_evt_seen flag is cleared only while clearing run/stop. Consider a case where err_evt_seen flag is set and controller is swtiching from peripheral mode to host mode. Now, from dwc3_gadget_pullup driver will bail out since the flag is set. Also since softconnect flag is not set run_stop will not get cleared from vbus_session(0), leaving the err evt_seen flag set. If any interrupt is generated then driver will bail out from interrupt handler without processing the interrupt, which can lead to irq storm. Fix this by clearing the err_evt_seen flag in disconnect and also add a judgement in pullup so that driver can proceed with clearing run/stop if softconnect is cleared, even with the err_evt_seen flag is set. Change-Id: Ib7026dca8b4e76e943832419b19cef180ca96171 Signed-off-by: Pratham Pratap --- drivers/usb/dwc3/dwc3-msm.c | 7 ++++++- drivers/usb/dwc3/gadget.c | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 538d5821537e..e3a5cd171efb 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ #include @@ -4992,6 +4992,11 @@ static int dwc3_otg_start_peripheral(struct dwc3_msm *mdwc, int on) mdwc->in_device_mode = false; usb_gadget_vbus_disconnect(&dwc->gadget); + /* + * Clearing err_evt_seen after disconnect ensures that interrupts + * are ignored if err_evt_seen is set + */ + dwc->err_evt_seen = false; usb_phy_notify_disconnect(mdwc->hs_phy, USB_SPEED_HIGH); usb_phy_notify_disconnect(mdwc->ss_phy, USB_SPEED_SUPER); redriver_notify_disconnect(mdwc->ss_redriver_node); diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index dc2b4cdd588a..34a1bf36ed85 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2330,7 +2330,8 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) dwc->softconnect = is_on; if (((dwc->dr_mode > USB_DR_MODE_HOST) && !dwc->vbus_active) - || !dwc->gadget_driver || dwc->err_evt_seen) { + || !dwc->gadget_driver || (dwc->err_evt_seen && + dwc->softconnect)) { /* * Need to wait for vbus_session(on) from otg driver or to * the udc_start.