Commit 3b207a45 authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Simon Horman

ARM: shmobile: sh73a0: do not overwrite all div4 clock operations

An earlier commit "ARM: shmobile: sh73a0: add support for adjusting CPU
frequency" intended to replace some clock operations only for the Z-clock,
instead it replaced them for all div4 clocks, since all div4 clocks share
the same copy of clock operations. Fix this by using a separate clock
operations structure for Z-clock.
Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski+renesas@gmail.com>
Signed-off-by: default avatarSimon Horman <horms+renesas@verge.net.au>
parent 43cb8cb7
...@@ -257,9 +257,8 @@ static struct clk twd_clk = { ...@@ -257,9 +257,8 @@ static struct clk twd_clk = {
.ops = &twd_clk_ops, .ops = &twd_clk_ops,
}; };
static int (*div4_set_rate)(struct clk *clk, unsigned long rate); static struct sh_clk_ops zclk_ops;
static unsigned long (*div4_recalc)(struct clk *clk); static const struct sh_clk_ops *div4_clk_ops;
static long (*div4_round_rate)(struct clk *clk, unsigned long rate);
static int zclk_set_rate(struct clk *clk, unsigned long rate) static int zclk_set_rate(struct clk *clk, unsigned long rate)
{ {
...@@ -275,7 +274,7 @@ static int zclk_set_rate(struct clk *clk, unsigned long rate) ...@@ -275,7 +274,7 @@ static int zclk_set_rate(struct clk *clk, unsigned long rate)
/* 1:1 - switch off divider */ /* 1:1 - switch off divider */
__raw_writel(__raw_readl(FRQCRB) & ~(1 << 28), FRQCRB); __raw_writel(__raw_readl(FRQCRB) & ~(1 << 28), FRQCRB);
/* nullify the divider to prepare for the next time */ /* nullify the divider to prepare for the next time */
ret = div4_set_rate(clk, rate / 2); ret = div4_clk_ops->set_rate(clk, rate / 2);
if (!ret) if (!ret)
ret = frqcr_kick(); ret = frqcr_kick();
if (ret > 0) if (ret > 0)
...@@ -290,7 +289,7 @@ static int zclk_set_rate(struct clk *clk, unsigned long rate) ...@@ -290,7 +289,7 @@ static int zclk_set_rate(struct clk *clk, unsigned long rate)
* set the divider - call the DIV4 method, it will kick * set the divider - call the DIV4 method, it will kick
* FRQCRB too * FRQCRB too
*/ */
ret = div4_set_rate(clk, rate); ret = div4_clk_ops->set_rate(clk, rate);
if (ret < 0) if (ret < 0)
goto esetrate; goto esetrate;
} }
...@@ -302,7 +301,7 @@ static int zclk_set_rate(struct clk *clk, unsigned long rate) ...@@ -302,7 +301,7 @@ static int zclk_set_rate(struct clk *clk, unsigned long rate)
static long zclk_round_rate(struct clk *clk, unsigned long rate) static long zclk_round_rate(struct clk *clk, unsigned long rate)
{ {
unsigned long div_freq = div4_round_rate(clk, rate), unsigned long div_freq = div4_clk_ops->round_rate(clk, rate),
parent_freq = clk_get_rate(clk->parent); parent_freq = clk_get_rate(clk->parent);
if (rate > div_freq && abs(parent_freq - rate) < rate - div_freq) if (rate > div_freq && abs(parent_freq - rate) < rate - div_freq)
...@@ -317,7 +316,7 @@ static unsigned long zclk_recalc(struct clk *clk) ...@@ -317,7 +316,7 @@ static unsigned long zclk_recalc(struct clk *clk)
* Must recalculate frequencies in case PLL0 has been changed, even if * Must recalculate frequencies in case PLL0 has been changed, even if
* the divisor is unused ATM! * the divisor is unused ATM!
*/ */
unsigned long div_freq = div4_recalc(clk); unsigned long div_freq = div4_clk_ops->recalc(clk);
if (__raw_readl(FRQCRB) & (1 << 28)) if (__raw_readl(FRQCRB) & (1 << 28))
return div_freq; return div_freq;
...@@ -327,13 +326,16 @@ static unsigned long zclk_recalc(struct clk *clk) ...@@ -327,13 +326,16 @@ static unsigned long zclk_recalc(struct clk *clk)
static void zclk_extend(void) static void zclk_extend(void)
{ {
div4_clk_ops = div4_clks[DIV4_Z].ops;
/* We extend the DIV4 clock with a 1:1 pass-through case */ /* We extend the DIV4 clock with a 1:1 pass-through case */
div4_set_rate = div4_clks[DIV4_Z].ops->set_rate; zclk_ops = *div4_clk_ops;
div4_round_rate = div4_clks[DIV4_Z].ops->round_rate;
div4_recalc = div4_clks[DIV4_Z].ops->recalc; zclk_ops.set_rate = zclk_set_rate;
div4_clks[DIV4_Z].ops->set_rate = zclk_set_rate; zclk_ops.round_rate = zclk_round_rate;
div4_clks[DIV4_Z].ops->round_rate = zclk_round_rate; zclk_ops.recalc = zclk_recalc;
div4_clks[DIV4_Z].ops->recalc = zclk_recalc;
div4_clks[DIV4_Z].ops = &zclk_ops;
} }
enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1, enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment