aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/clkt_clksel.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/clkt_clksel.c')
-rw-r--r--arch/arm/mach-omap2/clkt_clksel.c91
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}