diff options
author | Paul Walmsley <paul@pwsan.com> | 2012-09-23 19:27:43 -0400 |
---|---|---|
committer | Paul Walmsley <paul@pwsan.com> | 2012-09-23 19:27:43 -0400 |
commit | 4fb85d35bcec842e0f20437aea277157973aa45f (patch) | |
tree | d3b865af2f4066f68828806b231e4bb5b4de9ec8 /arch/arm/mach-omap2/clkt_clksel.c | |
parent | 1e2ee2a60df5c3ab74dd1c9155fb01b5bc6f807d (diff) | |
parent | a86c0b9867940bd0ba78f109686079b4051a463d (diff) |
Merge branch 'clock_devel_3.7' into hwmod_prcm_clock_a_3.7
Conflicts:
arch/arm/mach-omap2/clkt34xx_dpll3m2.c
arch/arm/mach-omap2/clkt_clksel.c
arch/arm/mach-omap2/clock.c
Diffstat (limited to 'arch/arm/mach-omap2/clkt_clksel.c')
-rw-r--r-- | arch/arm/mach-omap2/clkt_clksel.c | 86 |
1 files changed, 55 insertions, 31 deletions
diff --git a/arch/arm/mach-omap2/clkt_clksel.c b/arch/arm/mach-omap2/clkt_clksel.c index 19a980956d44..eaed3900a83c 100644 --- a/arch/arm/mach-omap2/clkt_clksel.c +++ b/arch/arm/mach-omap2/clkt_clksel.c | |||
@@ -72,7 +72,7 @@ static const struct clksel *_get_clksel_by_parent(struct clk *clk, | |||
72 | if (!clks->parent) { | 72 | if (!clks->parent) { |
73 | /* This indicates a data problem */ | 73 | /* This indicates a data problem */ |
74 | WARN(1, "clock: %s: could not find parent clock %s in clksel array\n", | 74 | WARN(1, "clock: %s: could not find parent clock %s in clksel array\n", |
75 | clk->name, src_clk->name); | 75 | __clk_get_name(clk), __clk_get_name(src_clk)); |
76 | return NULL; | 76 | return NULL; |
77 | } | 77 | } |
78 | 78 | ||
@@ -127,7 +127,8 @@ static u8 _get_div_and_fieldval(struct clk *src_clk, struct clk *clk, | |||
127 | if (max_div == 0) { | 127 | if (max_div == 0) { |
128 | /* This indicates an error in the clksel data */ | 128 | /* This indicates an error in the clksel data */ |
129 | WARN(1, "clock: %s: could not find divisor for parent %s\n", | 129 | WARN(1, "clock: %s: could not find divisor for parent %s\n", |
130 | clk->name, src_clk->parent->name); | 130 | __clk_get_name(clk), |
131 | __clk_get_name(__clk_get_parent(src_clk))); | ||
131 | return 0; | 132 | return 0; |
132 | } | 133 | } |
133 | 134 | ||
@@ -176,8 +177,10 @@ static u32 _clksel_to_divisor(struct clk *clk, u32 field_val) | |||
176 | { | 177 | { |
177 | const struct clksel *clks; | 178 | const struct clksel *clks; |
178 | const struct clksel_rate *clkr; | 179 | const struct clksel_rate *clkr; |
180 | struct clk *parent; | ||
179 | 181 | ||
180 | clks = _get_clksel_by_parent(clk, clk->parent); | 182 | parent = __clk_get_parent(clk); |
183 | clks = _get_clksel_by_parent(clk, parent); | ||
181 | if (!clks) | 184 | if (!clks) |
182 | return 0; | 185 | return 0; |
183 | 186 | ||
@@ -191,8 +194,8 @@ static u32 _clksel_to_divisor(struct clk *clk, u32 field_val) | |||
191 | 194 | ||
192 | if (!clkr->div) { | 195 | if (!clkr->div) { |
193 | /* This indicates a data error */ | 196 | /* This indicates a data error */ |
194 | WARN(1, "clock: %s: could not find fieldval %d parent %s\n", | 197 | WARN(1, "clock: %s: could not find fieldval %d for parent %s\n", |
195 | clk->name, field_val, clk->parent->name); | 198 | __clk_get_name(clk), field_val, __clk_get_name(parent)); |
196 | return 0; | 199 | return 0; |
197 | } | 200 | } |
198 | 201 | ||
@@ -213,11 +216,13 @@ static u32 _divisor_to_clksel(struct clk *clk, u32 div) | |||
213 | { | 216 | { |
214 | const struct clksel *clks; | 217 | const struct clksel *clks; |
215 | const struct clksel_rate *clkr; | 218 | const struct clksel_rate *clkr; |
219 | struct clk *parent; | ||
216 | 220 | ||
217 | /* should never happen */ | 221 | /* should never happen */ |
218 | WARN_ON(div == 0); | 222 | WARN_ON(div == 0); |
219 | 223 | ||
220 | clks = _get_clksel_by_parent(clk, clk->parent); | 224 | parent = __clk_get_parent(clk); |
225 | clks = _get_clksel_by_parent(clk, parent); | ||
221 | if (!clks) | 226 | if (!clks) |
222 | return ~0; | 227 | return ~0; |
223 | 228 | ||
@@ -230,8 +235,8 @@ static u32 _divisor_to_clksel(struct clk *clk, u32 div) | |||
230 | } | 235 | } |
231 | 236 | ||
232 | if (!clkr->div) { | 237 | if (!clkr->div) { |
233 | pr_err("clock: %s: could not find divisor %d parent %s\n", | 238 | pr_err("clock: %s: could not find divisor %d for parent %s\n", |
234 | clk->name, div, clk->parent->name); | 239 | __clk_get_name(clk), div, __clk_get_name(parent)); |
235 | return ~0; | 240 | return ~0; |
236 | } | 241 | } |
237 | 242 | ||
@@ -281,16 +286,23 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate, | |||
281 | const struct clksel *clks; | 286 | const struct clksel *clks; |
282 | const struct clksel_rate *clkr; | 287 | const struct clksel_rate *clkr; |
283 | u32 last_div = 0; | 288 | u32 last_div = 0; |
289 | struct clk *parent; | ||
290 | unsigned long parent_rate; | ||
291 | const char *clk_name; | ||
292 | |||
293 | parent = __clk_get_parent(clk); | ||
294 | parent_rate = __clk_get_rate(parent); | ||
295 | clk_name = __clk_get_name(clk); | ||
284 | 296 | ||
285 | if (!clk->clksel || !clk->clksel_mask) | 297 | if (!clk->clksel || !clk->clksel_mask) |
286 | return ~0; | 298 | return ~0; |
287 | 299 | ||
288 | pr_debug("clock: clksel_round_rate_div: %s target_rate %ld\n", | 300 | pr_debug("clock: clksel_round_rate_div: %s target_rate %ld\n", |
289 | clk->name, target_rate); | 301 | clk_name, target_rate); |
290 | 302 | ||
291 | *new_div = 1; | 303 | *new_div = 1; |
292 | 304 | ||
293 | clks = _get_clksel_by_parent(clk, clk->parent); | 305 | clks = _get_clksel_by_parent(clk, parent); |
294 | if (!clks) | 306 | if (!clks) |
295 | return ~0; | 307 | return ~0; |
296 | 308 | ||
@@ -300,29 +312,29 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate, | |||
300 | 312 | ||
301 | /* Sanity check */ | 313 | /* Sanity check */ |
302 | if (clkr->div <= last_div) | 314 | if (clkr->div <= last_div) |
303 | pr_err("clock: %s: clksel_rate table not sorted", | 315 | pr_err("clock: %s: clksel_rate table not sorted\n", |
304 | clk->name); | 316 | clk_name); |
305 | 317 | ||
306 | last_div = clkr->div; | 318 | last_div = clkr->div; |
307 | 319 | ||
308 | test_rate = clk->parent->rate / clkr->div; | 320 | test_rate = parent_rate / clkr->div; |
309 | 321 | ||
310 | if (test_rate <= target_rate) | 322 | if (test_rate <= target_rate) |
311 | break; /* found it */ | 323 | break; /* found it */ |
312 | } | 324 | } |
313 | 325 | ||
314 | if (!clkr->div) { | 326 | if (!clkr->div) { |
315 | pr_err("clock: %s: could not find divisor for target rate %ld parent %s\n", | 327 | pr_err("clock: %s: could not find divisor for target rate %ld for parent %s\n", |
316 | clk->name, target_rate, clk->parent->name); | 328 | clk_name, target_rate, __clk_get_name(parent)); |
317 | return ~0; | 329 | return ~0; |
318 | } | 330 | } |
319 | 331 | ||
320 | *new_div = clkr->div; | 332 | *new_div = clkr->div; |
321 | 333 | ||
322 | pr_debug("clock: new_div = %d, new_rate = %ld\n", *new_div, | 334 | pr_debug("clock: new_div = %d, new_rate = %ld\n", *new_div, |
323 | (clk->parent->rate / clkr->div)); | 335 | (parent_rate / clkr->div)); |
324 | 336 | ||
325 | return clk->parent->rate / clkr->div; | 337 | return parent_rate / clkr->div; |
326 | } | 338 | } |
327 | 339 | ||
328 | /* | 340 | /* |
@@ -344,10 +356,15 @@ void omap2_init_clksel_parent(struct clk *clk) | |||
344 | const struct clksel *clks; | 356 | const struct clksel *clks; |
345 | const struct clksel_rate *clkr; | 357 | const struct clksel_rate *clkr; |
346 | u32 r, found = 0; | 358 | u32 r, found = 0; |
359 | struct clk *parent; | ||
360 | const char *clk_name; | ||
347 | 361 | ||
348 | if (!clk->clksel || !clk->clksel_mask) | 362 | if (!clk->clksel || !clk->clksel_mask) |
349 | return; | 363 | return; |
350 | 364 | ||
365 | parent = __clk_get_parent(clk); | ||
366 | clk_name = __clk_get_name(clk); | ||
367 | |||
351 | r = __raw_readl(clk->clksel_reg) & clk->clksel_mask; | 368 | r = __raw_readl(clk->clksel_reg) & clk->clksel_mask; |
352 | r >>= __ffs(clk->clksel_mask); | 369 | r >>= __ffs(clk->clksel_mask); |
353 | 370 | ||
@@ -357,11 +374,13 @@ void omap2_init_clksel_parent(struct clk *clk) | |||
357 | continue; | 374 | continue; |
358 | 375 | ||
359 | if (clkr->val == r) { | 376 | if (clkr->val == r) { |
360 | if (clk->parent != clks->parent) { | 377 | if (parent != clks->parent) { |
361 | pr_debug("clock: %s: inited parent to %s (was %s)\n", | 378 | pr_debug("clock: %s: inited parent to %s (was %s)\n", |
362 | clk->name, clks->parent->name, | 379 | clk_name, |
363 | ((clk->parent) ? | 380 | __clk_get_name(clks->parent), |
364 | clk->parent->name : "NULL")); | 381 | ((parent) ? |
382 | __clk_get_name(parent) : | ||
383 | "NULL")); | ||
365 | clk_reparent(clk, clks->parent); | 384 | clk_reparent(clk, clks->parent); |
366 | }; | 385 | }; |
367 | found = 1; | 386 | found = 1; |
@@ -371,7 +390,7 @@ void omap2_init_clksel_parent(struct clk *clk) | |||
371 | 390 | ||
372 | /* This indicates a data error */ | 391 | /* This indicates a data error */ |
373 | WARN(!found, "clock: %s: init parent: could not find regval %0x\n", | 392 | WARN(!found, "clock: %s: init parent: could not find regval %0x\n", |
374 | clk->name, r); | 393 | clk_name, r); |
375 | 394 | ||
376 | return; | 395 | return; |
377 | } | 396 | } |
@@ -389,15 +408,17 @@ unsigned long omap2_clksel_recalc(struct clk *clk) | |||
389 | { | 408 | { |
390 | unsigned long rate; | 409 | unsigned long rate; |
391 | u32 div = 0; | 410 | u32 div = 0; |
411 | struct clk *parent; | ||
392 | 412 | ||
393 | div = _read_divisor(clk); | 413 | div = _read_divisor(clk); |
394 | if (div == 0) | 414 | if (div == 0) |
395 | return clk->rate; | 415 | return __clk_get_rate(clk); |
396 | 416 | ||
397 | rate = clk->parent->rate / div; | 417 | parent = __clk_get_parent(clk); |
418 | rate = __clk_get_rate(parent) / div; | ||
398 | 419 | ||
399 | pr_debug("clock: %s: recalc'd rate is %ld (div %d)\n", clk->name, | 420 | pr_debug("clock: %s: recalc'd rate is %ld (div %d)\n", |
400 | rate, div); | 421 | __clk_get_name(clk), rate, div); |
401 | 422 | ||
402 | return rate; | 423 | return rate; |
403 | } | 424 | } |
@@ -452,9 +473,10 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate) | |||
452 | 473 | ||
453 | _write_clksel_reg(clk, field_val); | 474 | _write_clksel_reg(clk, field_val); |
454 | 475 | ||
455 | clk->rate = clk->parent->rate / new_div; | 476 | clk->rate = __clk_get_rate(__clk_get_parent(clk)) / new_div; |
456 | 477 | ||
457 | pr_debug("clock: %s: set rate to %ld\n", clk->name, clk->rate); | 478 | pr_debug("clock: %s: set rate to %ld\n", __clk_get_name(clk), |
479 | __clk_get_rate(clk)); | ||
458 | 480 | ||
459 | return 0; | 481 | return 0; |
460 | } | 482 | } |
@@ -496,13 +518,15 @@ int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent) | |||
496 | clk_reparent(clk, new_parent); | 518 | clk_reparent(clk, new_parent); |
497 | 519 | ||
498 | /* CLKSEL clocks follow their parents' rates, divided by a divisor */ | 520 | /* CLKSEL clocks follow their parents' rates, divided by a divisor */ |
499 | clk->rate = new_parent->rate; | 521 | clk->rate = __clk_get_rate(new_parent); |
500 | 522 | ||
501 | if (parent_div > 0) | 523 | if (parent_div > 0) |
502 | clk->rate /= parent_div; | 524 | __clk_get_rate(clk) /= parent_div; |
503 | 525 | ||
504 | pr_debug("clock: %s: set parent to %s (new rate %ld)\n", | 526 | pr_debug("clock: %s: set parent to %s (new rate %ld)\n", |
505 | clk->name, clk->parent->name, clk->rate); | 527 | __clk_get_name(clk), |
528 | __clk_get_name(__clk_get_parent(clk)), | ||
529 | __clk_get_rate(clk)); | ||
506 | 530 | ||
507 | return 0; | 531 | return 0; |
508 | } | 532 | } |