diff options
| -rw-r--r-- | drivers/usb/dwc3/core.c | 48 | 
1 files changed, 18 insertions, 30 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 17fd81447c9f..fa20f5a99d12 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -67,23 +67,9 @@ void dwc3_set_mode(struct dwc3 *dwc, u32 mode)  static int dwc3_core_soft_reset(struct dwc3 *dwc)  {  	u32		reg; +	int		retries = 1000;  	int		ret; -	/* Before Resetting PHY, put Core in Reset */ -	reg = dwc3_readl(dwc->regs, DWC3_GCTL); -	reg |= DWC3_GCTL_CORESOFTRESET; -	dwc3_writel(dwc->regs, DWC3_GCTL, reg); - -	/* Assert USB3 PHY reset */ -	reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); -	reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST; -	dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); - -	/* Assert USB2 PHY reset */ -	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); -	reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST; -	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); -  	usb_phy_init(dwc->usb2_phy);  	usb_phy_init(dwc->usb3_phy);  	ret = phy_init(dwc->usb2_generic_phy); @@ -95,26 +81,28 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)  		phy_exit(dwc->usb2_generic_phy);  		return ret;  	} -	mdelay(100); -	/* Clear USB3 PHY reset */ -	reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); -	reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST; -	dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); +	/* +	 * We're resetting only the device side because, if we're in host mode, +	 * XHCI driver will reset the host block. If dwc3 was configured for +	 * host-only mode, then we can return early. +	 */ +	if (dwc->dr_mode == USB_DR_MODE_HOST) +		return 0; -	/* Clear USB2 PHY reset */ -	reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); -	reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST; -	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); +	reg = dwc3_readl(dwc->regs, DWC3_DCTL); +	reg |= DWC3_DCTL_CSFTRST; +	dwc3_writel(dwc->regs, DWC3_DCTL, reg); -	mdelay(100); +	do { +		reg = dwc3_readl(dwc->regs, DWC3_DCTL); +		if (!(reg & DWC3_DCTL_CSFTRST)) +			return 0; -	/* After PHYs are stable we can take Core out of reset state */ -	reg = dwc3_readl(dwc->regs, DWC3_GCTL); -	reg &= ~DWC3_GCTL_CORESOFTRESET; -	dwc3_writel(dwc->regs, DWC3_GCTL, reg); +		udelay(1); +	} while (--retries); -	return 0; +	return -ETIMEDOUT;  }  /**  | 
