diff options
Diffstat (limited to 'drivers/clk/st/clkgen-fsyn.c')
| -rw-r--r-- | drivers/clk/st/clkgen-fsyn.c | 54 |
1 files changed, 34 insertions, 20 deletions
diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c index 164285d6be97..e06e7e5cc1a5 100644 --- a/drivers/clk/st/clkgen-fsyn.c +++ b/drivers/clk/st/clkgen-fsyn.c @@ -375,22 +375,21 @@ static int clk_fs660c32_vco_get_params(unsigned long input, return 0; } -static long quadfs_pll_fs660c32_round_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long *prate) +static int quadfs_pll_fs660c32_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct stm_fs params; - if (clk_fs660c32_vco_get_params(*prate, rate, ¶ms)) - return rate; + if (clk_fs660c32_vco_get_params(req->best_parent_rate, req->rate, ¶ms)) + return 0; - clk_fs660c32_vco_get_rate(*prate, ¶ms, &rate); + clk_fs660c32_vco_get_rate(req->best_parent_rate, ¶ms, &req->rate); pr_debug("%s: %s new rate %ld [ndiv=%u]\n", __func__, clk_hw_get_name(hw), - rate, (unsigned int)params.ndiv); + req->rate, (unsigned int)params.ndiv); - return rate; + return 0; } static int quadfs_pll_fs660c32_set_rate(struct clk_hw *hw, unsigned long rate, @@ -436,7 +435,7 @@ static const struct clk_ops st_quadfs_pll_c32_ops = { .disable = quadfs_pll_disable, .is_enabled = quadfs_pll_is_enabled, .recalc_rate = quadfs_pll_fs660c32_recalc_rate, - .round_rate = quadfs_pll_fs660c32_round_rate, + .determine_rate = quadfs_pll_fs660c32_determine_rate, .set_rate = quadfs_pll_fs660c32_set_rate, }; @@ -814,19 +813,21 @@ static unsigned long quadfs_recalc_rate(struct clk_hw *hw, return rate; } -static long quadfs_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int quadfs_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct stm_fs params; - rate = quadfs_find_best_rate(hw, rate, *prate, ¶ms); + req->rate = quadfs_find_best_rate(hw, req->rate, + req->best_parent_rate, ¶ms); pr_debug("%s: %s new rate %ld [sdiv=0x%x,md=0x%x,pe=0x%x,nsdiv3=%u]\n", __func__, clk_hw_get_name(hw), - rate, (unsigned int)params.sdiv, (unsigned int)params.mdiv, - (unsigned int)params.pe, (unsigned int)params.nsdiv); + req->rate, (unsigned int)params.sdiv, + (unsigned int)params.mdiv, + (unsigned int)params.pe, (unsigned int)params.nsdiv); - return rate; + return 0; } @@ -873,7 +874,7 @@ static const struct clk_ops st_quadfs_ops = { .enable = quadfs_fsynth_enable, .disable = quadfs_fsynth_disable, .is_enabled = quadfs_fsynth_is_enabled, - .round_rate = quadfs_round_rate, + .determine_rate = quadfs_determine_rate, .set_rate = quadfs_set_rate, .recalc_rate = quadfs_recalc_rate, }; @@ -987,10 +988,22 @@ static void __init st_of_quadfs_setup(struct device_node *np, const char *pll_name, *clk_parent_name; void __iomem *reg; spinlock_t *lock; + struct device_node *parent_np; + /* + * First check for reg property within the node to keep backward + * compatibility, then if reg doesn't exist look at the parent node + */ reg = of_iomap(np, 0); - if (!reg) - return; + if (!reg) { + parent_np = of_get_parent(np); + reg = of_iomap(parent_np, 0); + of_node_put(parent_np); + if (!reg) { + pr_err("%s: Failed to get base address\n", __func__); + return; + } + } clk_parent_name = of_clk_get_parent_name(np, 0); if (!clk_parent_name) @@ -1008,9 +1021,10 @@ static void __init st_of_quadfs_setup(struct device_node *np, clk = st_clk_register_quadfs_pll(pll_name, clk_parent_name, datac->data, reg, lock); - if (IS_ERR(clk)) + if (IS_ERR(clk)) { + kfree(lock); goto err_exit; - else + } else pr_debug("%s: parent %s rate %u\n", __clk_get_name(clk), __clk_get_name(clk_get_parent(clk)), |
