From 203a3ea2cdf3d17c7f670fa09fcef1612fe6e841 Mon Sep 17 00:00:00 2001 From: Amit Nischal Date: Wed, 14 Jun 2017 10:45:46 +0530 Subject: [PATCH 1/2] clk: qcom: Check for errors during RCG read There could be instances where the RCG configuration update or readback could fail. Notify the caller of the failure. Add support to change scope of mux_div_get_src_div() in order to use it globally. Change-Id: Ica07c28cede695785db81697effcb40ab6b717d4 Signed-off-by: Amit Nischal Signed-off-by: Taniya Das Signed-off-by: Naveen Yadav --- drivers/clk/qcom/clk-regmap-mux-div.c | 18 +++++++++++++----- drivers/clk/qcom/clk-regmap-mux-div.h | 1 + 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/clk/qcom/clk-regmap-mux-div.c b/drivers/clk/qcom/clk-regmap-mux-div.c index 6044839da85a..4ec0a09ffc66 100644 --- a/drivers/clk/qcom/clk-regmap-mux-div.c +++ b/drivers/clk/qcom/clk-regmap-mux-div.c @@ -56,20 +56,26 @@ int mux_div_set_src_div(struct clk_regmap_mux_div *md, u32 src, u32 div) } EXPORT_SYMBOL_GPL(mux_div_set_src_div); -static void mux_div_get_src_div(struct clk_regmap_mux_div *md, u32 *src, - u32 *div) +int mux_div_get_src_div(struct clk_regmap_mux_div *md, u32 *src, + u32 *div) { + int ret = 0; u32 val, d, s; const char *name = clk_hw_get_name(&md->clkr.hw); - regmap_read(md->clkr.regmap, CMD_RCGR + md->reg_offset, &val); + ret = regmap_read(md->clkr.regmap, CMD_RCGR + md->reg_offset, &val); + if (ret) + return ret; if (val & CMD_RCGR_DIRTY_CFG) { pr_err("%s: RCG configuration is pending\n", name); - return; + return -EBUSY; } - regmap_read(md->clkr.regmap, CFG_RCGR + md->reg_offset, &val); + ret = regmap_read(md->clkr.regmap, CFG_RCGR + md->reg_offset, &val); + if (ret) + return ret; + s = (val >> md->src_shift); s &= BIT(md->src_width) - 1; *src = s; @@ -77,6 +83,8 @@ static void mux_div_get_src_div(struct clk_regmap_mux_div *md, u32 *src, d = (val >> md->hid_shift); d &= BIT(md->hid_width) - 1; *div = d; + + return ret; } static inline bool is_better_rate(unsigned long req, unsigned long best, diff --git a/drivers/clk/qcom/clk-regmap-mux-div.h b/drivers/clk/qcom/clk-regmap-mux-div.h index 4df6c8d24c24..70215e8ff63f 100644 --- a/drivers/clk/qcom/clk-regmap-mux-div.h +++ b/drivers/clk/qcom/clk-regmap-mux-div.h @@ -40,5 +40,6 @@ struct clk_regmap_mux_div { extern const struct clk_ops clk_regmap_mux_div_ops; extern int mux_div_set_src_div(struct clk_regmap_mux_div *md, u32 src, u32 div); +int mux_div_get_src_div(struct clk_regmap_mux_div *md, u32 *src, u32 *div); #endif From 68840cf2533e768586ef7a46087bcabfc4f05d60 Mon Sep 17 00:00:00 2001 From: Naveen Yadav Date: Fri, 18 Sep 2020 20:09:58 +0530 Subject: [PATCH 2/2] clk: qcom: Update parent map to use parent_map struct Add support to use parent_map structure for mux clk parent. Change-Id: I3f3655387bd8a7a3046a801ece921576d4e69e4b Signed-off-by: Naveen Yadav --- drivers/clk/qcom/clk-regmap-mux-div.c | 10 +++++----- drivers/clk/qcom/clk-regmap-mux-div.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/clk/qcom/clk-regmap-mux-div.c b/drivers/clk/qcom/clk-regmap-mux-div.c index 4ec0a09ffc66..26d48a65bd37 100644 --- a/drivers/clk/qcom/clk-regmap-mux-div.c +++ b/drivers/clk/qcom/clk-regmap-mux-div.c @@ -150,7 +150,7 @@ static int __mux_div_set_rate_and_parent(struct clk_hw *hw, unsigned long rate, if (is_better_rate(rate, best_rate, actual_rate)) { best_rate = actual_rate; - best_src = md->parent_map[i]; + best_src = md->parent_map[i].cfg; best_div = div - 1; } @@ -177,7 +177,7 @@ static u8 mux_div_get_parent(struct clk_hw *hw) mux_div_get_src_div(md, &src, &div); for (i = 0; i < clk_hw_get_num_parents(hw); i++) - if (src == md->parent_map[i]) + if (src == md->parent_map[i].cfg) return i; pr_err("%s: Can't find parent with src %d\n", name, src); @@ -188,7 +188,7 @@ static int mux_div_set_parent(struct clk_hw *hw, u8 index) { struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw); - return mux_div_set_src_div(md, md->parent_map[index], md->div); + return mux_div_set_src_div(md, md->parent_map[index].cfg, md->div); } static int mux_div_set_rate(struct clk_hw *hw, @@ -205,7 +205,7 @@ static int mux_div_set_rate_and_parent(struct clk_hw *hw, unsigned long rate, struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw); return __mux_div_set_rate_and_parent(hw, rate, prate, - md->parent_map[index]); + md->parent_map[index].cfg); } static unsigned long mux_div_recalc_rate(struct clk_hw *hw, unsigned long prate) @@ -217,7 +217,7 @@ static unsigned long mux_div_recalc_rate(struct clk_hw *hw, unsigned long prate) mux_div_get_src_div(md, &src, &div); for (i = 0; i < num_parents; i++) - if (src == md->parent_map[i]) { + if (src == md->parent_map[i].cfg) { struct clk_hw *p = clk_hw_get_parent_by_index(hw, i); unsigned long parent_rate = clk_hw_get_rate(p); diff --git a/drivers/clk/qcom/clk-regmap-mux-div.h b/drivers/clk/qcom/clk-regmap-mux-div.h index 70215e8ff63f..08acb529f36f 100644 --- a/drivers/clk/qcom/clk-regmap-mux-div.h +++ b/drivers/clk/qcom/clk-regmap-mux-div.h @@ -19,7 +19,7 @@ * @src_shift: lowest bit of source select field * @div: the divider raw configuration value * @src: the mux index which will be used if the clock is enabled - * @parent_map: map from parent_names index to src_sel field + * @parent_map: pointer to parent_map struct * @clkr: handle between common and hardware-specific interfaces * @pclk: the input PLL clock * @clk_nb: clock notifier for rate changes of the input PLL @@ -32,7 +32,7 @@ struct clk_regmap_mux_div { u32 src_shift; u32 div; u32 src; - const u32 *parent_map; + const struct parent_map *parent_map; struct clk_regmap clkr; struct clk *pclk; struct notifier_block clk_nb;