diff options
Diffstat (limited to 'drivers/usb/dwc3/core.c')
| -rw-r--r-- | drivers/usb/dwc3/core.c | 61 | 
1 files changed, 27 insertions, 34 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index c9bb93a2c81e..999ce5e84d3c 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -168,7 +168,6 @@ static void __dwc3_set_mode(struct work_struct *work)  				otg_set_vbus(dwc->usb2_phy->otg, true);  			phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST);  			phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_HOST); -			phy_calibrate(dwc->usb2_generic_phy);  		}  		break;  	case DWC3_GCTL_PRTCAP_DEVICE: @@ -252,12 +251,25 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)  	reg |= DWC3_DCTL_CSFTRST;  	dwc3_writel(dwc->regs, DWC3_DCTL, reg); +	/* +	 * For DWC_usb31 controller 1.90a and later, the DCTL.CSFRST bit +	 * is cleared only after all the clocks are synchronized. This can +	 * take a little more than 50ms. Set the polling rate at 20ms +	 * for 10 times instead. +	 */ +	if (dwc3_is_usb31(dwc) && dwc->revision >= DWC3_USB31_REVISION_190A) +		retries = 10; +  	do {  		reg = dwc3_readl(dwc->regs, DWC3_DCTL);  		if (!(reg & DWC3_DCTL_CSFTRST))  			goto done; -		udelay(1); +		if (dwc3_is_usb31(dwc) && +		    dwc->revision >= DWC3_USB31_REVISION_190A) +			msleep(20); +		else +			udelay(1);  	} while (--retries);  	phy_exit(dwc->usb3_generic_phy); @@ -267,11 +279,11 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)  done:  	/* -	 * For DWC_usb31 controller, once DWC3_DCTL_CSFTRST bit is cleared, -	 * we must wait at least 50ms before accessing the PHY domain -	 * (synchronization delay). DWC_usb31 programming guide section 1.3.2. +	 * For DWC_usb31 controller 1.80a and prior, once DCTL.CSFRST bit +	 * is cleared, we must wait at least 50ms before accessing the PHY +	 * domain (synchronization delay).  	 */ -	if (dwc3_is_usb31(dwc)) +	if (dwc3_is_usb31(dwc) && dwc->revision <= DWC3_USB31_REVISION_180A)  		msleep(50);  	return 0; @@ -686,8 +698,7 @@ static void dwc3_core_exit(struct dwc3 *dwc)  	usb_phy_set_suspend(dwc->usb3_phy, 1);  	phy_power_off(dwc->usb2_generic_phy);  	phy_power_off(dwc->usb3_generic_phy); -	clk_bulk_disable(dwc->num_clks, dwc->clks); -	clk_bulk_unprepare(dwc->num_clks, dwc->clks); +	clk_bulk_disable_unprepare(dwc->num_clks, dwc->clks);  	reset_control_assert(dwc->reset);  } @@ -813,8 +824,7 @@ static void dwc3_set_incr_burst_type(struct dwc3 *dwc)  	 * result = 1, means INCRx burst mode supported.  	 * result > 1, means undefined length burst mode supported.  	 */ -	ntype = device_property_read_u32_array(dev, -			"snps,incr-burst-type-adjustment", NULL, 0); +	ntype = device_property_count_u32(dev, "snps,incr-burst-type-adjustment");  	if (ntype <= 0)  		return; @@ -1166,7 +1176,6 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)  				dev_err(dev, "failed to initialize host\n");  			return ret;  		} -		phy_calibrate(dwc->usb2_generic_phy);  		break;  	case USB_DR_MODE_OTG:  		INIT_WORK(&dwc->drd_work, __dwc3_set_mode); @@ -1310,8 +1319,7 @@ static void dwc3_get_properties(struct dwc3 *dwc)  	dwc->lpm_nyet_threshold = lpm_nyet_threshold;  	dwc->tx_de_emphasis = tx_de_emphasis; -	dwc->hird_threshold = hird_threshold -		| (dwc->is_utmi_l1_suspend << 4); +	dwc->hird_threshold = hird_threshold;  	dwc->rx_thr_num_pkt_prd = rx_thr_num_pkt_prd;  	dwc->rx_max_burst_prd = rx_max_burst_prd; @@ -1436,7 +1444,7 @@ static int dwc3_probe(struct platform_device *pdev)  	if (dev->of_node) {  		dwc->num_clks = ARRAY_SIZE(dwc3_core_clks); -		ret = clk_bulk_get(dev, dwc->num_clks, dwc->clks); +		ret = devm_clk_bulk_get(dev, dwc->num_clks, dwc->clks);  		if (ret == -EPROBE_DEFER)  			return ret;  		/* @@ -1449,16 +1457,12 @@ static int dwc3_probe(struct platform_device *pdev)  	ret = reset_control_deassert(dwc->reset);  	if (ret) -		goto put_clks; +		return ret; -	ret = clk_bulk_prepare(dwc->num_clks, dwc->clks); +	ret = clk_bulk_prepare_enable(dwc->num_clks, dwc->clks);  	if (ret)  		goto assert_reset; -	ret = clk_bulk_enable(dwc->num_clks, dwc->clks); -	if (ret) -		goto unprepare_clks; -  	if (!dwc3_core_is_valid(dwc)) {  		dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n");  		ret = -ENODEV; @@ -1531,13 +1535,9 @@ err1:  	pm_runtime_disable(&pdev->dev);  disable_clks: -	clk_bulk_disable(dwc->num_clks, dwc->clks); -unprepare_clks: -	clk_bulk_unprepare(dwc->num_clks, dwc->clks); +	clk_bulk_disable_unprepare(dwc->num_clks, dwc->clks);  assert_reset:  	reset_control_assert(dwc->reset); -put_clks: -	clk_bulk_put(dwc->num_clks, dwc->clks);  	return ret;  } @@ -1560,7 +1560,6 @@ static int dwc3_remove(struct platform_device *pdev)  	dwc3_free_event_buffers(dwc);  	dwc3_free_scratch_buffers(dwc); -	clk_bulk_put(dwc->num_clks, dwc->clks);  	return 0;  } @@ -1574,14 +1573,10 @@ static int dwc3_core_init_for_resume(struct dwc3 *dwc)  	if (ret)  		return ret; -	ret = clk_bulk_prepare(dwc->num_clks, dwc->clks); +	ret = clk_bulk_prepare_enable(dwc->num_clks, dwc->clks);  	if (ret)  		goto assert_reset; -	ret = clk_bulk_enable(dwc->num_clks, dwc->clks); -	if (ret) -		goto unprepare_clks; -  	ret = dwc3_core_init(dwc);  	if (ret)  		goto disable_clks; @@ -1589,9 +1584,7 @@ static int dwc3_core_init_for_resume(struct dwc3 *dwc)  	return 0;  disable_clks: -	clk_bulk_disable(dwc->num_clks, dwc->clks); -unprepare_clks: -	clk_bulk_unprepare(dwc->num_clks, dwc->clks); +	clk_bulk_disable_unprepare(dwc->num_clks, dwc->clks);  assert_reset:  	reset_control_assert(dwc->reset);  |