diff options
Diffstat (limited to 'drivers/usb/dwc2/platform.c')
-rw-r--r-- | drivers/usb/dwc2/platform.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index d1589ba7d322..5aee284018c0 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -101,10 +101,16 @@ static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg) if (ret) return ret; + if (hsotg->utmi_clk) { + ret = clk_prepare_enable(hsotg->utmi_clk); + if (ret) + goto err_dis_reg; + } + if (hsotg->clk) { ret = clk_prepare_enable(hsotg->clk); if (ret) - return ret; + goto err_dis_utmi_clk; } if (hsotg->uphy) { @@ -113,10 +119,29 @@ static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg) ret = hsotg->plat->phy_init(pdev, hsotg->plat->phy_type); } else { ret = phy_init(hsotg->phy); - if (ret == 0) + if (ret == 0) { ret = phy_power_on(hsotg->phy); + if (ret) + phy_exit(hsotg->phy); + } } + if (ret) + goto err_dis_clk; + + return 0; + +err_dis_clk: + if (hsotg->clk) + clk_disable_unprepare(hsotg->clk); + +err_dis_utmi_clk: + if (hsotg->utmi_clk) + clk_disable_unprepare(hsotg->utmi_clk); + +err_dis_reg: + regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); + return ret; } @@ -156,6 +181,9 @@ static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg) if (hsotg->clk) clk_disable_unprepare(hsotg->clk); + if (hsotg->utmi_clk) + clk_disable_unprepare(hsotg->utmi_clk); + return regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); } @@ -232,6 +260,11 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) if (IS_ERR(hsotg->clk)) return dev_err_probe(hsotg->dev, PTR_ERR(hsotg->clk), "cannot get otg clock\n"); + hsotg->utmi_clk = devm_clk_get_optional(hsotg->dev, "utmi"); + if (IS_ERR(hsotg->utmi_clk)) + return dev_err_probe(hsotg->dev, PTR_ERR(hsotg->utmi_clk), + "cannot get utmi clock\n"); + /* Regulators */ for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++) hsotg->supplies[i].supply = dwc2_hsotg_supply_names[i]; |