Commit 83dda228 authored by Sean Paul's avatar Sean Paul

drm/msm/dsi_pll_10nm: Release clk hw on destroy and failure

The 10nm pll driver didn't have any failure-path cleanup in register,
and the destroy function didn't unregister any of the hardware. This
patch adds both.

The reason things haven't been blowing up horribly is that msm_drv has a
reference count issue that keeps devices alive, so the destroy function
was never called. That will be fixed in a follow-up patch.
Reviewed-by: default avatarRob Clark <robdclark@chromium.org>
Signed-off-by: default avatarSean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20190617201301.133275-1-sean@poorly.run
parent 7896e223
...@@ -104,8 +104,13 @@ struct dsi_pll_10nm { ...@@ -104,8 +104,13 @@ struct dsi_pll_10nm {
struct dsi_pll_regs reg_setup; struct dsi_pll_regs reg_setup;
/* private clocks: */ /* private clocks: */
struct clk_hw *hws[NUM_DSI_CLOCKS_MAX]; struct clk_hw *out_div_clk_hw;
u32 num_hws; struct clk_hw *bit_clk_hw;
struct clk_hw *byte_clk_hw;
struct clk_hw *by_2_bit_clk_hw;
struct clk_hw *post_out_div_clk_hw;
struct clk_hw *pclk_mux_hw;
struct clk_hw *out_dsiclk_hw;
/* clock-provider: */ /* clock-provider: */
struct clk_hw_onecell_data *hw_data; struct clk_hw_onecell_data *hw_data;
...@@ -617,8 +622,19 @@ static int dsi_pll_10nm_get_provider(struct msm_dsi_pll *pll, ...@@ -617,8 +622,19 @@ static int dsi_pll_10nm_get_provider(struct msm_dsi_pll *pll,
static void dsi_pll_10nm_destroy(struct msm_dsi_pll *pll) static void dsi_pll_10nm_destroy(struct msm_dsi_pll *pll)
{ {
struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll);
struct device *dev = &pll_10nm->pdev->dev;
DBG("DSI PLL%d", pll_10nm->id); DBG("DSI PLL%d", pll_10nm->id);
of_clk_del_provider(dev->of_node);
clk_hw_unregister_divider(pll_10nm->out_dsiclk_hw);
clk_hw_unregister_mux(pll_10nm->pclk_mux_hw);
clk_hw_unregister_fixed_factor(pll_10nm->post_out_div_clk_hw);
clk_hw_unregister_fixed_factor(pll_10nm->by_2_bit_clk_hw);
clk_hw_unregister_fixed_factor(pll_10nm->byte_clk_hw);
clk_hw_unregister_divider(pll_10nm->bit_clk_hw);
clk_hw_unregister_divider(pll_10nm->out_div_clk_hw);
clk_hw_unregister(&pll_10nm->base.clk_hw);
} }
/* /*
...@@ -639,10 +655,8 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm) ...@@ -639,10 +655,8 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm)
.ops = &clk_ops_dsi_pll_10nm_vco, .ops = &clk_ops_dsi_pll_10nm_vco,
}; };
struct device *dev = &pll_10nm->pdev->dev; struct device *dev = &pll_10nm->pdev->dev;
struct clk_hw **hws = pll_10nm->hws;
struct clk_hw_onecell_data *hw_data; struct clk_hw_onecell_data *hw_data;
struct clk_hw *hw; struct clk_hw *hw;
int num = 0;
int ret; int ret;
DBG("DSI%d", pll_10nm->id); DBG("DSI%d", pll_10nm->id);
...@@ -660,8 +674,6 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm) ...@@ -660,8 +674,6 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm)
if (ret) if (ret)
return ret; return ret;
hws[num++] = &pll_10nm->base.clk_hw;
snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_10nm->id); snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_10nm->id);
snprintf(parent, 32, "dsi%dvco_clk", pll_10nm->id); snprintf(parent, 32, "dsi%dvco_clk", pll_10nm->id);
...@@ -670,10 +682,12 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm) ...@@ -670,10 +682,12 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm)
pll_10nm->mmio + pll_10nm->mmio +
REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE, REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE,
0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL); 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL);
if (IS_ERR(hw)) if (IS_ERR(hw)) {
return PTR_ERR(hw); ret = PTR_ERR(hw);
goto err_base_clk_hw;
}
hws[num++] = hw; pll_10nm->out_div_clk_hw = hw;
snprintf(clk_name, 32, "dsi%d_pll_bit_clk", pll_10nm->id); snprintf(clk_name, 32, "dsi%d_pll_bit_clk", pll_10nm->id);
snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_10nm->id); snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_10nm->id);
...@@ -685,10 +699,12 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm) ...@@ -685,10 +699,12 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm)
REG_DSI_10nm_PHY_CMN_CLK_CFG0, REG_DSI_10nm_PHY_CMN_CLK_CFG0,
0, 4, CLK_DIVIDER_ONE_BASED, 0, 4, CLK_DIVIDER_ONE_BASED,
&pll_10nm->postdiv_lock); &pll_10nm->postdiv_lock);
if (IS_ERR(hw)) if (IS_ERR(hw)) {
return PTR_ERR(hw); ret = PTR_ERR(hw);
goto err_out_div_clk_hw;
}
hws[num++] = hw; pll_10nm->bit_clk_hw = hw;
snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_10nm->id); snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_10nm->id);
snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->id); snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->id);
...@@ -696,10 +712,12 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm) ...@@ -696,10 +712,12 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm)
/* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */ /* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */
hw = clk_hw_register_fixed_factor(dev, clk_name, parent, hw = clk_hw_register_fixed_factor(dev, clk_name, parent,
CLK_SET_RATE_PARENT, 1, 8); CLK_SET_RATE_PARENT, 1, 8);
if (IS_ERR(hw)) if (IS_ERR(hw)) {
return PTR_ERR(hw); ret = PTR_ERR(hw);
goto err_bit_clk_hw;
}
hws[num++] = hw; pll_10nm->byte_clk_hw = hw;
hw_data->hws[DSI_BYTE_PLL_CLK] = hw; hw_data->hws[DSI_BYTE_PLL_CLK] = hw;
snprintf(clk_name, 32, "dsi%d_pll_by_2_bit_clk", pll_10nm->id); snprintf(clk_name, 32, "dsi%d_pll_by_2_bit_clk", pll_10nm->id);
...@@ -707,20 +725,24 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm) ...@@ -707,20 +725,24 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm)
hw = clk_hw_register_fixed_factor(dev, clk_name, parent, hw = clk_hw_register_fixed_factor(dev, clk_name, parent,
0, 1, 2); 0, 1, 2);
if (IS_ERR(hw)) if (IS_ERR(hw)) {
return PTR_ERR(hw); ret = PTR_ERR(hw);
goto err_byte_clk_hw;
}
hws[num++] = hw; pll_10nm->by_2_bit_clk_hw = hw;
snprintf(clk_name, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->id); snprintf(clk_name, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->id);
snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_10nm->id); snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_10nm->id);
hw = clk_hw_register_fixed_factor(dev, clk_name, parent, hw = clk_hw_register_fixed_factor(dev, clk_name, parent,
0, 1, 4); 0, 1, 4);
if (IS_ERR(hw)) if (IS_ERR(hw)) {
return PTR_ERR(hw); ret = PTR_ERR(hw);
goto err_by_2_bit_clk_hw;
}
hws[num++] = hw; pll_10nm->post_out_div_clk_hw = hw;
snprintf(clk_name, 32, "dsi%d_pclk_mux", pll_10nm->id); snprintf(clk_name, 32, "dsi%d_pclk_mux", pll_10nm->id);
snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->id); snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->id);
...@@ -734,10 +756,12 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm) ...@@ -734,10 +756,12 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm)
}, 4, 0, pll_10nm->phy_cmn_mmio + }, 4, 0, pll_10nm->phy_cmn_mmio +
REG_DSI_10nm_PHY_CMN_CLK_CFG1, REG_DSI_10nm_PHY_CMN_CLK_CFG1,
0, 2, 0, NULL); 0, 2, 0, NULL);
if (IS_ERR(hw)) if (IS_ERR(hw)) {
return PTR_ERR(hw); ret = PTR_ERR(hw);
goto err_post_out_div_clk_hw;
}
hws[num++] = hw; pll_10nm->pclk_mux_hw = hw;
snprintf(clk_name, 32, "dsi%d_phy_pll_out_dsiclk", pll_10nm->id); snprintf(clk_name, 32, "dsi%d_phy_pll_out_dsiclk", pll_10nm->id);
snprintf(parent, 32, "dsi%d_pclk_mux", pll_10nm->id); snprintf(parent, 32, "dsi%d_pclk_mux", pll_10nm->id);
...@@ -748,14 +772,14 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm) ...@@ -748,14 +772,14 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm)
REG_DSI_10nm_PHY_CMN_CLK_CFG0, REG_DSI_10nm_PHY_CMN_CLK_CFG0,
4, 4, CLK_DIVIDER_ONE_BASED, 4, 4, CLK_DIVIDER_ONE_BASED,
&pll_10nm->postdiv_lock); &pll_10nm->postdiv_lock);
if (IS_ERR(hw)) if (IS_ERR(hw)) {
return PTR_ERR(hw); ret = PTR_ERR(hw);
goto err_pclk_mux_hw;
}
hws[num++] = hw; pll_10nm->out_dsiclk_hw = hw;
hw_data->hws[DSI_PIXEL_PLL_CLK] = hw; hw_data->hws[DSI_PIXEL_PLL_CLK] = hw;
pll_10nm->num_hws = num;
hw_data->num = NUM_PROVIDED_CLKS; hw_data->num = NUM_PROVIDED_CLKS;
pll_10nm->hw_data = hw_data; pll_10nm->hw_data = hw_data;
...@@ -763,10 +787,29 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm) ...@@ -763,10 +787,29 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm)
pll_10nm->hw_data); pll_10nm->hw_data);
if (ret) { if (ret) {
DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret); DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret);
return ret; goto err_dsiclk_hw;
} }
return 0; return 0;
err_dsiclk_hw:
clk_hw_unregister_divider(pll_10nm->out_dsiclk_hw);
err_pclk_mux_hw:
clk_hw_unregister_mux(pll_10nm->pclk_mux_hw);
err_post_out_div_clk_hw:
clk_hw_unregister_fixed_factor(pll_10nm->post_out_div_clk_hw);
err_by_2_bit_clk_hw:
clk_hw_unregister_fixed_factor(pll_10nm->by_2_bit_clk_hw);
err_byte_clk_hw:
clk_hw_unregister_fixed_factor(pll_10nm->byte_clk_hw);
err_bit_clk_hw:
clk_hw_unregister_divider(pll_10nm->bit_clk_hw);
err_out_div_clk_hw:
clk_hw_unregister_divider(pll_10nm->out_div_clk_hw);
err_base_clk_hw:
clk_hw_unregister(&pll_10nm->base.clk_hw);
return ret;
} }
struct msm_dsi_pll *msm_dsi_pll_10nm_init(struct platform_device *pdev, int id) struct msm_dsi_pll *msm_dsi_pll_10nm_init(struct platform_device *pdev, int id)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment