aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-shmobile/clock-sh73a0.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index d05cf9039788..d9fd0336b910 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -257,7 +257,7 @@ static struct clk twd_clk = {
257 .ops = &twd_clk_ops, 257 .ops = &twd_clk_ops,
258}; 258};
259 259
260static struct sh_clk_ops zclk_ops; 260static struct sh_clk_ops zclk_ops, kicker_ops;
261static const struct sh_clk_ops *div4_clk_ops; 261static const struct sh_clk_ops *div4_clk_ops;
262 262
263static int zclk_set_rate(struct clk *clk, unsigned long rate) 263static int zclk_set_rate(struct clk *clk, unsigned long rate)
@@ -324,18 +324,32 @@ static unsigned long zclk_recalc(struct clk *clk)
324 return clk_get_rate(clk->parent); 324 return clk_get_rate(clk->parent);
325} 325}
326 326
327static void zclk_extend(void) 327static int kicker_set_rate(struct clk *clk, unsigned long rate)
328{ 328{
329 div4_clk_ops = div4_clks[DIV4_Z].ops; 329 if (__raw_readl(FRQCRB) & (1 << 31))
330 return -EBUSY;
331
332 return div4_clk_ops->set_rate(clk, rate);
333}
334
335static void div4_clk_extend(void)
336{
337 int i;
338
339 div4_clk_ops = div4_clks[0].ops;
330 340
341 /* Add a kicker-busy check before changing the rate */
342 kicker_ops = *div4_clk_ops;
331 /* We extend the DIV4 clock with a 1:1 pass-through case */ 343 /* We extend the DIV4 clock with a 1:1 pass-through case */
332 zclk_ops = *div4_clk_ops; 344 zclk_ops = *div4_clk_ops;
333 345
346 kicker_ops.set_rate = kicker_set_rate;
334 zclk_ops.set_rate = zclk_set_rate; 347 zclk_ops.set_rate = zclk_set_rate;
335 zclk_ops.round_rate = zclk_round_rate; 348 zclk_ops.round_rate = zclk_round_rate;
336 zclk_ops.recalc = zclk_recalc; 349 zclk_ops.recalc = zclk_recalc;
337 350
338 div4_clks[DIV4_Z].ops = &zclk_ops; 351 for (i = 0; i < DIV4_NR; i++)
352 div4_clks[i].ops = i == DIV4_Z ? &zclk_ops : &kicker_ops;
339} 353}
340 354
341enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1, 355enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
@@ -697,7 +711,7 @@ void __init sh73a0_clock_init(void)
697 if (!ret) { 711 if (!ret) {
698 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); 712 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
699 if (!ret) 713 if (!ret)
700 zclk_extend(); 714 div4_clk_extend();
701 } 715 }
702 716
703 if (!ret) 717 if (!ret)