From: Taniya Das <tdas@xxxxxxxxxxxxxx> In the case where the PLL configuration is lost, then the pm runtime resume will reconfigure before usage. Fixes: edab812d802d ("clk: qcom: lpass: Add support for LPASS clock controller for SC7180") Signed-off-by: Taniya Das <tdas@xxxxxxxxxxxxxx> Signed-off-by: Douglas Anderson <dianders@xxxxxxxxxxxx> --- Changes in v4: - Put regmap names in "static const char *" globals. Changes in v3: - Now based on a series which disentangles the two clock devices. - Use dev_get_regmap(). - Better comment about reading PLL_L_VAL. Changes in v2: - Don't needlessly have a 2nd copy of dev_pm_ops and jam it in. - Check the return value of pm_clk_resume() - l_val should be unsigned int. drivers/clk/qcom/lpasscorecc-sc7180.c | 28 ++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/drivers/clk/qcom/lpasscorecc-sc7180.c b/drivers/clk/qcom/lpasscorecc-sc7180.c index 4ed766ca08bb..d7586858760c 100644 --- a/drivers/clk/qcom/lpasscorecc-sc7180.c +++ b/drivers/clk/qcom/lpasscorecc-sc7180.c @@ -21,6 +21,9 @@ #include "common.h" #include "gdsc.h" +static const char *lpass_audio_cc_regmap_name = "lpass_audio_cc"; +static const char *lpass_core_cc_regmap_name = "lpass_core_cc"; + enum { P_BI_TCXO, P_LPASS_LPAAUDIO_DIG_PLL_OUT_ODD, @@ -388,6 +391,25 @@ static int lpass_create_pm_clks(struct platform_device *pdev) return ret; } +static int lpass_core_cc_pm_clk_resume(struct device *dev) +{ + struct regmap *regmap = dev_get_regmap(dev, lpass_core_cc_regmap_name); + unsigned int l_val; + int ret; + + ret = pm_clk_resume(dev); + if (ret) + return ret; + + /* If PLL_L_VAL was cleared then we should re-init the whole PLL */ + regmap_read(regmap, 0x1004, &l_val); + if (!l_val) + clk_fabia_pll_configure(&lpass_lpaaudio_dig_pll, regmap, + &lpass_lpaaudio_dig_pll_config); + + return 0; +} + static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) { const struct qcom_cc_desc *desc; @@ -398,13 +420,13 @@ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) if (ret) return ret; - lpass_core_cc_sc7180_regmap_config.name = "lpass_audio_cc"; + lpass_core_cc_sc7180_regmap_config.name = lpass_audio_cc_regmap_name; desc = &lpass_audio_hm_sc7180_desc; ret = qcom_cc_probe_by_index(pdev, 1, desc); if (ret) return ret; - lpass_core_cc_sc7180_regmap_config.name = "lpass_core_cc"; + lpass_core_cc_sc7180_regmap_config.name = lpass_core_cc_regmap_name; regmap = qcom_cc_map(pdev, &lpass_core_cc_sc7180_desc); if (IS_ERR(regmap)) return PTR_ERR(regmap); @@ -457,7 +479,7 @@ static const struct of_device_id lpass_core_cc_sc7180_match_table[] = { MODULE_DEVICE_TABLE(of, lpass_core_cc_sc7180_match_table); static const struct dev_pm_ops lpass_core_cc_pm_ops = { - SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL) + SET_RUNTIME_PM_OPS(pm_clk_suspend, lpass_core_cc_pm_clk_resume, NULL) }; static struct platform_driver lpass_core_cc_sc7180_driver = { -- 2.28.0.1011.ga647a8990f-goog