Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9bbf449b authored by Pratham Pratap's avatar Pratham Pratap
Browse files

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: default avatarPratham Pratap <prathampratap@codeaurora.org>
parent 9ddceddf
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
// 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 <linux/module.h>
@@ -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);
+2 −1
Original line number Diff line number Diff line
@@ -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.