diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2013-05-22 18:09:36 -0400 |
---|---|---|
committer | Simon Horman <horms+renesas@verge.net.au> | 2013-06-07 01:24:52 -0400 |
commit | 3b207a45f909a73b6d7fbdcef49e9287ad7385af (patch) | |
tree | 582ff798621197faadb4a2f77af8b58cd4d0a75d /arch | |
parent | 43cb8cb739b9d5f9f723b1953c58b95d3102d821 (diff) |
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: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-shmobile/clock-sh73a0.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c index acb9e0970739..d05cf9039788 100644 --- a/arch/arm/mach-shmobile/clock-sh73a0.c +++ b/arch/arm/mach-shmobile/clock-sh73a0.c | |||
@@ -257,9 +257,8 @@ static struct clk twd_clk = { | |||
257 | .ops = &twd_clk_ops, | 257 | .ops = &twd_clk_ops, |
258 | }; | 258 | }; |
259 | 259 | ||
260 | static int (*div4_set_rate)(struct clk *clk, unsigned long rate); | 260 | static struct sh_clk_ops zclk_ops; |
261 | static unsigned long (*div4_recalc)(struct clk *clk); | 261 | static const struct sh_clk_ops *div4_clk_ops; |
262 | static long (*div4_round_rate)(struct clk *clk, unsigned long rate); | ||
263 | 262 | ||
264 | static int zclk_set_rate(struct clk *clk, unsigned long rate) | 263 | static int zclk_set_rate(struct clk *clk, unsigned long rate) |
265 | { | 264 | { |
@@ -275,7 +274,7 @@ static int zclk_set_rate(struct clk *clk, unsigned long rate) | |||
275 | /* 1:1 - switch off divider */ | 274 | /* 1:1 - switch off divider */ |
276 | __raw_writel(__raw_readl(FRQCRB) & ~(1 << 28), FRQCRB); | 275 | __raw_writel(__raw_readl(FRQCRB) & ~(1 << 28), FRQCRB); |
277 | /* nullify the divider to prepare for the next time */ | 276 | /* nullify the divider to prepare for the next time */ |
278 | ret = div4_set_rate(clk, rate / 2); | 277 | ret = div4_clk_ops->set_rate(clk, rate / 2); |
279 | if (!ret) | 278 | if (!ret) |
280 | ret = frqcr_kick(); | 279 | ret = frqcr_kick(); |
281 | if (ret > 0) | 280 | if (ret > 0) |
@@ -290,7 +289,7 @@ static int zclk_set_rate(struct clk *clk, unsigned long rate) | |||
290 | * set the divider - call the DIV4 method, it will kick | 289 | * set the divider - call the DIV4 method, it will kick |
291 | * FRQCRB too | 290 | * FRQCRB too |
292 | */ | 291 | */ |
293 | ret = div4_set_rate(clk, rate); | 292 | ret = div4_clk_ops->set_rate(clk, rate); |
294 | if (ret < 0) | 293 | if (ret < 0) |
295 | goto esetrate; | 294 | goto esetrate; |
296 | } | 295 | } |
@@ -302,7 +301,7 @@ esetrate: | |||
302 | 301 | ||
303 | static long zclk_round_rate(struct clk *clk, unsigned long rate) | 302 | static long zclk_round_rate(struct clk *clk, unsigned long rate) |
304 | { | 303 | { |
305 | unsigned long div_freq = div4_round_rate(clk, rate), | 304 | unsigned long div_freq = div4_clk_ops->round_rate(clk, rate), |
306 | parent_freq = clk_get_rate(clk->parent); | 305 | parent_freq = clk_get_rate(clk->parent); |
307 | 306 | ||
308 | if (rate > div_freq && abs(parent_freq - rate) < rate - div_freq) | 307 | if (rate > div_freq && abs(parent_freq - rate) < rate - div_freq) |
@@ -317,7 +316,7 @@ static unsigned long zclk_recalc(struct clk *clk) | |||
317 | * Must recalculate frequencies in case PLL0 has been changed, even if | 316 | * Must recalculate frequencies in case PLL0 has been changed, even if |
318 | * the divisor is unused ATM! | 317 | * the divisor is unused ATM! |
319 | */ | 318 | */ |
320 | unsigned long div_freq = div4_recalc(clk); | 319 | unsigned long div_freq = div4_clk_ops->recalc(clk); |
321 | 320 | ||
322 | if (__raw_readl(FRQCRB) & (1 << 28)) | 321 | if (__raw_readl(FRQCRB) & (1 << 28)) |
323 | return div_freq; | 322 | return div_freq; |
@@ -327,13 +326,16 @@ static unsigned long zclk_recalc(struct clk *clk) | |||
327 | 326 | ||
328 | static void zclk_extend(void) | 327 | static void zclk_extend(void) |
329 | { | 328 | { |
329 | div4_clk_ops = div4_clks[DIV4_Z].ops; | ||
330 | |||
330 | /* We extend the DIV4 clock with a 1:1 pass-through case */ | 331 | /* We extend the DIV4 clock with a 1:1 pass-through case */ |
331 | div4_set_rate = div4_clks[DIV4_Z].ops->set_rate; | 332 | zclk_ops = *div4_clk_ops; |
332 | div4_round_rate = div4_clks[DIV4_Z].ops->round_rate; | 333 | |
333 | div4_recalc = div4_clks[DIV4_Z].ops->recalc; | 334 | zclk_ops.set_rate = zclk_set_rate; |
334 | div4_clks[DIV4_Z].ops->set_rate = zclk_set_rate; | 335 | zclk_ops.round_rate = zclk_round_rate; |
335 | div4_clks[DIV4_Z].ops->round_rate = zclk_round_rate; | 336 | zclk_ops.recalc = zclk_recalc; |
336 | div4_clks[DIV4_Z].ops->recalc = zclk_recalc; | 337 | |
338 | div4_clks[DIV4_Z].ops = &zclk_ops; | ||
337 | } | 339 | } |
338 | 340 | ||
339 | enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1, | 341 | enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1, |