summaryrefslogtreecommitdiffstats
path: root/drivers/clk/ti
diff options
context:
space:
mode:
authorTero Kristo <t-kristo@ti.com>2016-02-20 06:24:26 -0500
committerStephen Boyd <sboyd@codeaurora.org>2016-02-22 17:16:49 -0500
commitb6f5128459a40410f9afefddc0ad688ea5b22c28 (patch)
treedfd2a78beabd091b5c49d8aa045497061c1d1855 /drivers/clk/ti
parent1e59403990acfb67d0e9ddf57fe6acc1c2aff4dc (diff)
clk: ti: dpll: convert DPLL support code to use clk_hw instead of clk ptrs
Convert DPLL support code to use clk_hw pointers for reference and bypass clocks. This allows us to use clk_hw_* APIs for accessing any required parameters for these clocks, avoiding some locking problems at least with DPLL enable code; this used clk_get_rate which uses mutex but isn't good under clk_enable / clk_disable. Signed-off-by: Tero Kristo <t-kristo@ti.com> Acked-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Diffstat (limited to 'drivers/clk/ti')
-rw-r--r--drivers/clk/ti/apll.c20
-rw-r--r--drivers/clk/ti/clkt_dpll.c6
-rw-r--r--drivers/clk/ti/dpll.c25
-rw-r--r--drivers/clk/ti/dpll3xxx.c17
-rw-r--r--drivers/clk/ti/dpll44xx.c8
5 files changed, 50 insertions, 26 deletions
diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c
index b336a8c11e2a..6411e132faa2 100644
--- a/drivers/clk/ti/apll.c
+++ b/drivers/clk/ti/apll.c
@@ -140,11 +140,21 @@ static void __init omap_clk_register_apll(struct clk_hw *hw,
140 struct dpll_data *ad = clk_hw->dpll_data; 140 struct dpll_data *ad = clk_hw->dpll_data;
141 struct clk *clk; 141 struct clk *clk;
142 142
143 ad->clk_ref = of_clk_get(node, 0); 143 clk = of_clk_get(node, 0);
144 ad->clk_bypass = of_clk_get(node, 1); 144 if (IS_ERR(clk)) {
145 pr_debug("clk-ref for %s not ready, retry\n",
146 node->name);
147 if (!ti_clk_retry_init(node, hw, omap_clk_register_apll))
148 return;
149
150 goto cleanup;
151 }
145 152
146 if (IS_ERR(ad->clk_ref) || IS_ERR(ad->clk_bypass)) { 153 ad->clk_ref = __clk_get_hw(clk);
147 pr_debug("clk-ref or clk-bypass for %s not ready, retry\n", 154
155 clk = of_clk_get(node, 1);
156 if (IS_ERR(clk)) {
157 pr_debug("clk-bypass for %s not ready, retry\n",
148 node->name); 158 node->name);
149 if (!ti_clk_retry_init(node, hw, omap_clk_register_apll)) 159 if (!ti_clk_retry_init(node, hw, omap_clk_register_apll))
150 return; 160 return;
@@ -152,6 +162,8 @@ static void __init omap_clk_register_apll(struct clk_hw *hw,
152 goto cleanup; 162 goto cleanup;
153 } 163 }
154 164
165 ad->clk_bypass = __clk_get_hw(clk);
166
155 clk = clk_register(NULL, &clk_hw->hw); 167 clk = clk_register(NULL, &clk_hw->hw);
156 if (!IS_ERR(clk)) { 168 if (!IS_ERR(clk)) {
157 of_clk_add_provider(node, of_clk_src_simple_get, clk); 169 of_clk_add_provider(node, of_clk_src_simple_get, clk);
diff --git a/drivers/clk/ti/clkt_dpll.c b/drivers/clk/ti/clkt_dpll.c
index b5cc6f66ae5d..032c658a5f5e 100644
--- a/drivers/clk/ti/clkt_dpll.c
+++ b/drivers/clk/ti/clkt_dpll.c
@@ -254,7 +254,7 @@ unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk)
254 v >>= __ffs(dd->enable_mask); 254 v >>= __ffs(dd->enable_mask);
255 255
256 if (_omap2_dpll_is_in_bypass(v)) 256 if (_omap2_dpll_is_in_bypass(v))
257 return clk_get_rate(dd->clk_bypass); 257 return clk_hw_get_rate(dd->clk_bypass);
258 258
259 v = ti_clk_ll_ops->clk_readl(dd->mult_div1_reg); 259 v = ti_clk_ll_ops->clk_readl(dd->mult_div1_reg);
260 dpll_mult = v & dd->mult_mask; 260 dpll_mult = v & dd->mult_mask;
@@ -262,7 +262,7 @@ unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk)
262 dpll_div = v & dd->div1_mask; 262 dpll_div = v & dd->div1_mask;
263 dpll_div >>= __ffs(dd->div1_mask); 263 dpll_div >>= __ffs(dd->div1_mask);
264 264
265 dpll_clk = (u64)clk_get_rate(dd->clk_ref) * dpll_mult; 265 dpll_clk = (u64)clk_hw_get_rate(dd->clk_ref) * dpll_mult;
266 do_div(dpll_clk, dpll_div + 1); 266 do_div(dpll_clk, dpll_div + 1);
267 267
268 return dpll_clk; 268 return dpll_clk;
@@ -301,7 +301,7 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
301 301
302 dd = clk->dpll_data; 302 dd = clk->dpll_data;
303 303
304 ref_rate = clk_get_rate(dd->clk_ref); 304 ref_rate = clk_hw_get_rate(dd->clk_ref);
305 clk_name = clk_hw_get_name(hw); 305 clk_name = clk_hw_get_name(hw);
306 pr_debug("clock: %s: starting DPLL round_rate, target rate %lu\n", 306 pr_debug("clock: %s: starting DPLL round_rate, target rate %lu\n",
307 clk_name, target_rate); 307 clk_name, target_rate);
diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
index 5519b386edc0..f8306f1c30f1 100644
--- a/drivers/clk/ti/dpll.c
+++ b/drivers/clk/ti/dpll.c
@@ -147,11 +147,22 @@ static void __init _register_dpll(struct clk_hw *hw,
147 struct dpll_data *dd = clk_hw->dpll_data; 147 struct dpll_data *dd = clk_hw->dpll_data;
148 struct clk *clk; 148 struct clk *clk;
149 149
150 dd->clk_ref = of_clk_get(node, 0); 150 clk = of_clk_get(node, 0);
151 dd->clk_bypass = of_clk_get(node, 1); 151 if (IS_ERR(clk)) {
152 pr_debug("clk-ref missing for %s, retry later\n",
153 node->name);
154 if (!ti_clk_retry_init(node, hw, _register_dpll))
155 return;
152 156
153 if (IS_ERR(dd->clk_ref) || IS_ERR(dd->clk_bypass)) { 157 goto cleanup;
154 pr_debug("clk-ref or clk-bypass missing for %s, retry later\n", 158 }
159
160 dd->clk_ref = __clk_get_hw(clk);
161
162 clk = of_clk_get(node, 1);
163
164 if (IS_ERR(clk)) {
165 pr_debug("clk-bypass missing for %s, retry later\n",
155 node->name); 166 node->name);
156 if (!ti_clk_retry_init(node, hw, _register_dpll)) 167 if (!ti_clk_retry_init(node, hw, _register_dpll))
157 return; 168 return;
@@ -159,6 +170,8 @@ static void __init _register_dpll(struct clk_hw *hw,
159 goto cleanup; 170 goto cleanup;
160 } 171 }
161 172
173 dd->clk_bypass = __clk_get_hw(clk);
174
162 /* register the clock */ 175 /* register the clock */
163 clk = clk_register(NULL, &clk_hw->hw); 176 clk = clk_register(NULL, &clk_hw->hw);
164 177
@@ -251,8 +264,8 @@ struct clk *ti_clk_register_dpll(struct ti_clk *setup)
251 dd->recal_en_bit = dpll->recal_en_bit; 264 dd->recal_en_bit = dpll->recal_en_bit;
252 dd->recal_st_bit = dpll->recal_st_bit; 265 dd->recal_st_bit = dpll->recal_st_bit;
253 266
254 dd->clk_ref = clk_ref; 267 dd->clk_ref = __clk_get_hw(clk_ref);
255 dd->clk_bypass = clk_bypass; 268 dd->clk_bypass = __clk_get_hw(clk_bypass);
256 269
257 if (dpll->flags & CLKF_CORE) 270 if (dpll->flags & CLKF_CORE)
258 ops = &omap3_dpll_core_ck_ops; 271 ops = &omap3_dpll_core_ck_ops;
diff --git a/drivers/clk/ti/dpll3xxx.c b/drivers/clk/ti/dpll3xxx.c
index cc739291a3ce..88f2ce81ba55 100644
--- a/drivers/clk/ti/dpll3xxx.c
+++ b/drivers/clk/ti/dpll3xxx.c
@@ -98,7 +98,7 @@ static u16 _omap3_dpll_compute_freqsel(struct clk_hw_omap *clk, u8 n)
98 unsigned long fint; 98 unsigned long fint;
99 u16 f = 0; 99 u16 f = 0;
100 100
101 fint = clk_get_rate(clk->dpll_data->clk_ref) / n; 101 fint = clk_hw_get_rate(clk->dpll_data->clk_ref) / n;
102 102
103 pr_debug("clock: fint is %lu\n", fint); 103 pr_debug("clock: fint is %lu\n", fint);
104 104
@@ -460,12 +460,11 @@ int omap3_noncore_dpll_enable(struct clk_hw *hw)
460 460
461 parent = clk_hw_get_parent(hw); 461 parent = clk_hw_get_parent(hw);
462 462
463 if (clk_hw_get_rate(hw) == 463 if (clk_hw_get_rate(hw) == clk_hw_get_rate(dd->clk_bypass)) {
464 clk_hw_get_rate(__clk_get_hw(dd->clk_bypass))) { 464 WARN_ON(parent != dd->clk_bypass);
465 WARN_ON(parent != __clk_get_hw(dd->clk_bypass));
466 r = _omap3_noncore_dpll_bypass(clk); 465 r = _omap3_noncore_dpll_bypass(clk);
467 } else { 466 } else {
468 WARN_ON(parent != __clk_get_hw(dd->clk_ref)); 467 WARN_ON(parent != dd->clk_ref);
469 r = _omap3_noncore_dpll_lock(clk); 468 r = _omap3_noncore_dpll_lock(clk);
470 } 469 }
471 470
@@ -513,13 +512,13 @@ int omap3_noncore_dpll_determine_rate(struct clk_hw *hw,
513 if (!dd) 512 if (!dd)
514 return -EINVAL; 513 return -EINVAL;
515 514
516 if (clk_get_rate(dd->clk_bypass) == req->rate && 515 if (clk_hw_get_rate(dd->clk_bypass) == req->rate &&
517 (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { 516 (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
518 req->best_parent_hw = __clk_get_hw(dd->clk_bypass); 517 req->best_parent_hw = dd->clk_bypass;
519 } else { 518 } else {
520 req->rate = omap2_dpll_round_rate(hw, req->rate, 519 req->rate = omap2_dpll_round_rate(hw, req->rate,
521 &req->best_parent_rate); 520 &req->best_parent_rate);
522 req->best_parent_hw = __clk_get_hw(dd->clk_ref); 521 req->best_parent_hw = dd->clk_ref;
523 } 522 }
524 523
525 req->best_parent_rate = req->rate; 524 req->best_parent_rate = req->rate;
@@ -577,7 +576,7 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
577 if (!dd) 576 if (!dd)
578 return -EINVAL; 577 return -EINVAL;
579 578
580 if (clk_hw_get_parent(hw) != __clk_get_hw(dd->clk_ref)) 579 if (clk_hw_get_parent(hw) != dd->clk_ref)
581 return -EINVAL; 580 return -EINVAL;
582 581
583 if (dd->last_rounded_rate == 0) 582 if (dd->last_rounded_rate == 0)
diff --git a/drivers/clk/ti/dpll44xx.c b/drivers/clk/ti/dpll44xx.c
index 660d7436ac24..82c05b55a7be 100644
--- a/drivers/clk/ti/dpll44xx.c
+++ b/drivers/clk/ti/dpll44xx.c
@@ -94,7 +94,7 @@ static void omap4_dpll_lpmode_recalc(struct dpll_data *dd)
94{ 94{
95 long fint, fout; 95 long fint, fout;
96 96
97 fint = clk_get_rate(dd->clk_ref) / (dd->last_rounded_n + 1); 97 fint = clk_hw_get_rate(dd->clk_ref) / (dd->last_rounded_n + 1);
98 fout = fint * dd->last_rounded_m; 98 fout = fint * dd->last_rounded_m;
99 99
100 if ((fint < OMAP4_DPLL_LP_FINT_MAX) && (fout < OMAP4_DPLL_LP_FOUT_MAX)) 100 if ((fint < OMAP4_DPLL_LP_FINT_MAX) && (fout < OMAP4_DPLL_LP_FOUT_MAX))
@@ -212,13 +212,13 @@ int omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw,
212 if (!dd) 212 if (!dd)
213 return -EINVAL; 213 return -EINVAL;
214 214
215 if (clk_get_rate(dd->clk_bypass) == req->rate && 215 if (clk_hw_get_rate(dd->clk_bypass) == req->rate &&
216 (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { 216 (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
217 req->best_parent_hw = __clk_get_hw(dd->clk_bypass); 217 req->best_parent_hw = dd->clk_bypass;
218 } else { 218 } else {
219 req->rate = omap4_dpll_regm4xen_round_rate(hw, req->rate, 219 req->rate = omap4_dpll_regm4xen_round_rate(hw, req->rate,
220 &req->best_parent_rate); 220 &req->best_parent_rate);
221 req->best_parent_hw = __clk_get_hw(dd->clk_ref); 221 req->best_parent_hw = dd->clk_ref;
222 } 222 }
223 223
224 req->best_parent_rate = req->rate; 224 req->best_parent_rate = req->rate;