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

Commit 78ba525b authored by Mayank Rana's avatar Mayank Rana
Browse files

dwc3: gadget: Handle usb2 phy autosuspend functionality with gadget event



Current code put usb2 phy into autosuspend mode and poll for IN_L2
pwr_event to be set while putting device into LPM on receiving SUSPEND
event. There is a possible race that arises when gadget events are
processed before the resume routine has disabled the USB2 PHY autosuspend.
Some of the gadget events issue endpoint commands which may time out since
the PHY is still autosuspended. Fix this issue by using available check
where it calls dwc3_gadget_usb2_phy_suspend() API to disable usb2 phy
autosuspend, and ignore hsphy_auto_suspend_disable platform specific
variable.

Also add error messages where this failure case is checked.

CRs-Fixed: 680990
Change-Id: Iebc48e10ea5bc9f90e17ad21f0fec620f5c57211
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent bb898bb5
Loading
Loading
Loading
Loading
+22 −4
Original line number Diff line number Diff line
@@ -466,6 +466,10 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
		 */
		timeout--;
		if (!timeout) {
			dev_err(dwc->dev, "%s command timeout for %s\n",
				dwc3_gadget_ep_cmd_string(cmd),
				dep->name);
			WARN_ON_ONCE(1);
			ret = -ETIMEDOUT;
			break;
		}
@@ -639,21 +643,30 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,

	if (!(dep->flags & DWC3_EP_ENABLED)) {
		ret = dwc3_gadget_start_config(dwc, dep);
		if (ret)
		if (ret) {
			dev_err(dwc->dev, "start_config() failed for %s\n",
								dep->name);
			return ret;
		}
	}

	ret = dwc3_gadget_set_ep_config(dwc, dep, desc, comp_desc, ignore);
	if (ret)
	if (ret) {
		dev_err(dwc->dev, "set_ep_config() failed for %s\n",
							dep->name);
		return ret;
	}

	if (!(dep->flags & DWC3_EP_ENABLED)) {
		struct dwc3_trb	*trb_st_hw;
		struct dwc3_trb	*trb_link;

		ret = dwc3_gadget_set_xfer_resource(dwc, dep);
		if (ret)
		if (ret) {
			dev_err(dwc->dev, "set_xfer_resource() failed for %s\n",
								dep->name);
			return ret;
		}

		dep->endpoint.desc = desc;
		dep->comp_desc = comp_desc;
@@ -2790,7 +2803,12 @@ static void dwc3_gadget_usb2_phy_suspend(struct dwc3 *dwc, int suspend)
{
	u32			reg;

	if (dwc->hsphy_auto_suspend_disable)
	/*
	 * Disable usb2 phy autosuspend functionality where it is not
	 * enabled by default. Possible case where it is enabled to put
	 * usb into LPM.
	 */
	if (dwc->hsphy_auto_suspend_disable && suspend)
		return;

	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));