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

Commit 90f11cc3 authored by Mayank Rana's avatar Mayank Rana Committed by Matt Wagantall
Browse files

dwc3: gadget: Resume usb if in_lpm before setting RUN STOP



This change aborts pending suspend and if it is already suspended,
it resumes USB controller and wait for it before setting Run/Stop
bit. This change fixes device crash seen due to unclock accessed
while enabling Pullup.

CRs-Fixed: 718233
Change-Id: Ib014f49bb9dfc2baf966a68e90fc2a86db63c80e
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent 4bc36e72
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -1852,11 +1852,16 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
	struct dwc3		*dwc = gadget_to_dwc(g);
	unsigned long		flags;
	int			ret;
	unsigned long		timeout;

	is_on = !!is_on;

	spin_lock_irqsave(&dwc->lock, flags);

	/* If pending suspend, abort this suspend. */
	if (dwc->enable_bus_suspend)
		usb_phy_set_suspend(dwc->dotg->otg.phy, 0);

	dwc->softconnect = is_on;

	if ((dwc->dotg && !dwc->vbus_active) ||
@@ -1880,13 +1885,32 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
		dbg_event(0xFF, "Gdgpull gsyn", 0);
		pm_runtime_get_sync(dwc->dev);
		dwc->disable_during_lpm = true;
		goto set_run_stop;
	}

	if (is_on && dwc->disable_during_lpm) {
		dbg_event(0xFF, "Gdgpull psyn", 0);
		pm_runtime_put_sync(dwc->dev);
		dwc->disable_during_lpm = false;
		goto set_run_stop;
	}

	if (atomic_read(&dwc->in_lpm)) {
		pm_runtime_resume(dwc->dev);
		timeout = jiffies + msecs_to_jiffies(20);
		do {
			if (!atomic_read(&dwc->in_lpm))
				break;

			if (time_after(jiffies, timeout)) {
				pr_err("%s(): Err getting pullup\n", __func__);
				return -ETIMEDOUT;
			}
			usleep_range(2, 5);
		} while (true);
	}

set_run_stop:
	spin_lock_irqsave(&dwc->lock, flags);

	ret = dwc3_gadget_run_stop(dwc, is_on, false);