diff options
Diffstat (limited to 'arch/arm/mach-omap2/clkt_clksel.c')
-rw-r--r-- | arch/arm/mach-omap2/clkt_clksel.c | 91 |
1 files changed, 57 insertions, 34 deletions
diff --git a/arch/arm/mach-omap2/clkt_clksel.c b/arch/arm/mach-omap2/clkt_clksel.c index 04d551b1f7f7..33382fb46cc1 100644 --- a/arch/arm/mach-omap2/clkt_clksel.c +++ b/arch/arm/mach-omap2/clkt_clksel.c | |||
@@ -71,8 +71,8 @@ static const struct clksel *_get_clksel_by_parent(struct clk *clk, | |||
71 | 71 | ||
72 | if (!clks->parent) { | 72 | if (!clks->parent) { |
73 | /* This indicates a data problem */ | 73 | /* This indicates a data problem */ |
74 | WARN(1, "clock: Could not find parent clock %s in clksel array " | 74 | WARN(1, "clock: %s: could not find parent clock %s in clksel array\n", |
75 | "of clock %s\n", src_clk->name, clk->name); | 75 | __clk_get_name(clk), __clk_get_name(src_clk)); |
76 | return NULL; | 76 | return NULL; |
77 | } | 77 | } |
78 | 78 | ||
@@ -126,8 +126,9 @@ static u8 _get_div_and_fieldval(struct clk *src_clk, struct clk *clk, | |||
126 | 126 | ||
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: Could not find divisor for clock %s parent %s" | 129 | WARN(1, "clock: %s: could not find divisor for parent %s\n", |
130 | "\n", 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: Could not find fieldval %d for clock %s parent " | 197 | WARN(1, "clock: %s: could not find fieldval %d for parent %s\n", |
195 | "%s\n", field_val, clk->name, 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: Could not find divisor %d for clock %s parent " | 238 | pr_err("clock: %s: could not find divisor %d for parent %s\n", |
234 | "%s\n", div, clk->name, 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,30 +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: clksel_rate table not sorted " | 315 | pr_err("clock: %s: clksel_rate table not sorted\n", |
304 | "for clock %s", 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: Could not find divisor for target " | 327 | pr_err("clock: %s: could not find divisor for target rate %ld for parent %s\n", |
316 | "rate %ld for clock %s parent %s\n", target_rate, | 328 | clk_name, target_rate, __clk_get_name(parent)); |
317 | clk->name, clk->parent->name); | ||
318 | return ~0; | 329 | return ~0; |
319 | } | 330 | } |
320 | 331 | ||
321 | *new_div = clkr->div; | 332 | *new_div = clkr->div; |
322 | 333 | ||
323 | 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, |
324 | (clk->parent->rate / clkr->div)); | 335 | (parent_rate / clkr->div)); |
325 | 336 | ||
326 | return clk->parent->rate / clkr->div; | 337 | return parent_rate / clkr->div; |
327 | } | 338 | } |
328 | 339 | ||
329 | /* | 340 | /* |
@@ -345,10 +356,15 @@ void omap2_init_clksel_parent(struct clk *clk) | |||
345 | const struct clksel *clks; | 356 | const struct clksel *clks; |
346 | const struct clksel_rate *clkr; | 357 | const struct clksel_rate *clkr; |
347 | u32 r, found = 0; | 358 | u32 r, found = 0; |
359 | struct clk *parent; | ||
360 | const char *clk_name; | ||
348 | 361 | ||
349 | if (!clk->clksel || !clk->clksel_mask) | 362 | if (!clk->clksel || !clk->clksel_mask) |
350 | return; | 363 | return; |
351 | 364 | ||
365 | parent = __clk_get_parent(clk); | ||
366 | clk_name = __clk_get_name(clk); | ||
367 | |||
352 | r = __raw_readl(clk->clksel_reg) & clk->clksel_mask; | 368 | r = __raw_readl(clk->clksel_reg) & clk->clksel_mask; |
353 | r >>= __ffs(clk->clksel_mask); | 369 | r >>= __ffs(clk->clksel_mask); |
354 | 370 | ||
@@ -358,12 +374,14 @@ void omap2_init_clksel_parent(struct clk *clk) | |||
358 | continue; | 374 | continue; |
359 | 375 | ||
360 | if (clkr->val == r) { | 376 | if (clkr->val == r) { |
361 | if (clk->parent != clks->parent) { | 377 | if (parent != clks->parent) { |
362 | pr_debug("clock: inited %s parent " | 378 | pr_debug("clock: inited %s parent " |
363 | "to %s (was %s)\n", | 379 | "to %s (was %s)\n", |
364 | clk->name, clks->parent->name, | 380 | clk_name, |
365 | ((clk->parent) ? | 381 | __clk_get_name(clks->parent), |
366 | clk->parent->name : "NULL")); | 382 | ((parent) ? |
383 | __clk_get_name(parent) : | ||
384 | "NULL")); | ||
367 | clk_reparent(clk, clks->parent); | 385 | clk_reparent(clk, clks->parent); |
368 | }; | 386 | }; |
369 | found = 1; | 387 | found = 1; |
@@ -373,7 +391,7 @@ void omap2_init_clksel_parent(struct clk *clk) | |||
373 | 391 | ||
374 | /* This indicates a data error */ | 392 | /* This indicates a data error */ |
375 | WARN(!found, "clock: %s: init parent: could not find regval %0x\n", | 393 | WARN(!found, "clock: %s: init parent: could not find regval %0x\n", |
376 | clk->name, r); | 394 | clk_name, r); |
377 | 395 | ||
378 | return; | 396 | return; |
379 | } | 397 | } |
@@ -391,15 +409,17 @@ unsigned long omap2_clksel_recalc(struct clk *clk) | |||
391 | { | 409 | { |
392 | unsigned long rate; | 410 | unsigned long rate; |
393 | u32 div = 0; | 411 | u32 div = 0; |
412 | struct clk *parent; | ||
394 | 413 | ||
395 | div = _read_divisor(clk); | 414 | div = _read_divisor(clk); |
396 | if (div == 0) | 415 | if (div == 0) |
397 | return clk->rate; | 416 | return __clk_get_rate(clk); |
398 | 417 | ||
399 | rate = clk->parent->rate / div; | 418 | parent = __clk_get_parent(clk); |
419 | rate = __clk_get_rate(parent) / div; | ||
400 | 420 | ||
401 | pr_debug("clock: %s: recalc'd rate is %ld (div %d)\n", clk->name, | 421 | pr_debug("clock: %s: recalc'd rate is %ld (div %d)\n", |
402 | rate, div); | 422 | __clk_get_name(clk), rate, div); |
403 | 423 | ||
404 | return rate; | 424 | return rate; |
405 | } | 425 | } |
@@ -454,9 +474,10 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate) | |||
454 | 474 | ||
455 | _write_clksel_reg(clk, field_val); | 475 | _write_clksel_reg(clk, field_val); |
456 | 476 | ||
457 | clk->rate = clk->parent->rate / new_div; | 477 | clk->rate = __clk_get_rate(__clk_get_parent(clk)) / new_div; |
458 | 478 | ||
459 | pr_debug("clock: %s: set rate to %ld\n", clk->name, clk->rate); | 479 | pr_debug("clock: %s: set rate to %ld\n", __clk_get_name(clk), |
480 | __clk_get_rate(clk)); | ||
460 | 481 | ||
461 | return 0; | 482 | return 0; |
462 | } | 483 | } |
@@ -498,13 +519,15 @@ int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent) | |||
498 | clk_reparent(clk, new_parent); | 519 | clk_reparent(clk, new_parent); |
499 | 520 | ||
500 | /* CLKSEL clocks follow their parents' rates, divided by a divisor */ | 521 | /* CLKSEL clocks follow their parents' rates, divided by a divisor */ |
501 | clk->rate = new_parent->rate; | 522 | clk->rate = __clk_get_rate(new_parent); |
502 | 523 | ||
503 | if (parent_div > 0) | 524 | if (parent_div > 0) |
504 | clk->rate /= parent_div; | 525 | __clk_get_rate(clk) /= parent_div; |
505 | 526 | ||
506 | pr_debug("clock: %s: set parent to %s (new rate %ld)\n", | 527 | pr_debug("clock: %s: set parent to %s (new rate %ld)\n", |
507 | clk->name, clk->parent->name, clk->rate); | 528 | __clk_get_name(clk), |
529 | __clk_get_name(__clk_get_parent(clk)), | ||
530 | __clk_get_rate(clk)); | ||
508 | 531 | ||
509 | return 0; | 532 | return 0; |
510 | } | 533 | } |