diff options
Diffstat (limited to 'drivers/phy/cadence/phy-cadence-sierra.c')
-rw-r--r-- | drivers/phy/cadence/phy-cadence-sierra.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c index 039ca10db59d..5c68e31c5939 100644 --- a/drivers/phy/cadence/phy-cadence-sierra.c +++ b/drivers/phy/cadence/phy-cadence-sierra.c @@ -768,6 +768,40 @@ static int cdns_sierra_phy_get_clocks(struct cdns_sierra_phy *sp, return 0; } +static int cdns_sierra_phy_enable_clocks(struct cdns_sierra_phy *sp) +{ + int ret; + + ret = clk_prepare_enable(sp->input_clks[PHY_CLK]); + if (ret) + return ret; + + ret = clk_prepare_enable(sp->output_clks[CDNS_SIERRA_PLL_CMNLC]); + if (ret) + goto err_pll_cmnlc; + + ret = clk_prepare_enable(sp->output_clks[CDNS_SIERRA_PLL_CMNLC1]); + if (ret) + goto err_pll_cmnlc1; + + return 0; + +err_pll_cmnlc1: + clk_disable_unprepare(sp->output_clks[CDNS_SIERRA_PLL_CMNLC]); + +err_pll_cmnlc: + clk_disable_unprepare(sp->input_clks[PHY_CLK]); + + return ret; +} + +static void cdns_sierra_phy_disable_clocks(struct cdns_sierra_phy *sp) +{ + clk_disable_unprepare(sp->output_clks[CDNS_SIERRA_PLL_CMNLC1]); + clk_disable_unprepare(sp->output_clks[CDNS_SIERRA_PLL_CMNLC]); + clk_disable_unprepare(sp->input_clks[PHY_CLK]); +} + static int cdns_sierra_phy_get_resets(struct cdns_sierra_phy *sp, struct device *dev) { @@ -848,7 +882,7 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev) if (ret) goto unregister_clk; - ret = clk_prepare_enable(sp->input_clks[PHY_CLK]); + ret = cdns_sierra_phy_enable_clocks(sp); if (ret) goto unregister_clk; @@ -925,7 +959,7 @@ put_child2: reset_control_put(sp->phys[i].lnk_rst); of_node_put(child); clk_disable: - clk_disable_unprepare(sp->input_clks[PHY_CLK]); + cdns_sierra_phy_disable_clocks(sp); reset_control_assert(sp->apb_rst); unregister_clk: cdns_sierra_clk_unregister(sp); @@ -941,6 +975,7 @@ static int cdns_sierra_phy_remove(struct platform_device *pdev) reset_control_assert(phy->apb_rst); pm_runtime_disable(&pdev->dev); + cdns_sierra_phy_disable_clocks(phy); /* * The device level resets will be put automatically. * Need to put the subnode resets here though. @@ -950,7 +985,6 @@ static int cdns_sierra_phy_remove(struct platform_device *pdev) reset_control_put(phy->phys[i].lnk_rst); } - clk_disable_unprepare(phy->input_clks[PHY_CLK]); cdns_sierra_clk_unregister(phy); return 0; |