ARM: shmobile: sh73a0: wait for completion when kicking the clock
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Thu, 28 Feb 2013 12:21:58 +0000 (13:21 +0100)
committerSimon Horman <horms+renesas@verge.net.au>
Tue, 2 Apr 2013 01:58:23 +0000 (10:58 +0900)
To reconfigure clocks, controlled by FRQCRA and FRQCRB, a kick bit has to
be set and to make sure the setting has taken effect, it has to be read
back repeatedly until it is cleared by the hardware. This patch adds the
waiting part, that was missing until now.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Acked-by: Magnus Damm <damm@opensource.se
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
arch/arm/mach-shmobile/clock-sh73a0.c

index 71843dd39e16adb0593dd5f377a6baefb857116b..34b5c5ae4cbdba937bbb42fa4ad1c1af4b8c959c 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/io.h>
 #include <linux/sh_clk.h>
 #include <linux/clkdev.h>
+#include <asm/processor.h>
 #include <mach/common.h>
 
 #define FRQCRA         IOMEM(0xe6150000)
@@ -234,14 +235,24 @@ static struct clk *main_clks[] = {
        &sh73a0_extalr_clk,
 };
 
-static void div4_kick(struct clk *clk)
+static int frqcr_kick(void)
 {
-       unsigned long value;
+       int i;
+
+       /* set KICK bit in FRQCRB to update hardware setting, check success */
+       __raw_writel(__raw_readl(FRQCRB) | (1 << 31), FRQCRB);
+       for (i = 1000; i; i--)
+               if (__raw_readl(FRQCRB) & (1 << 31))
+                       cpu_relax();
+               else
+                       return i;
+
+       return -ETIMEDOUT;
+}
 
-       /* set KICK bit in FRQCRB to update hardware setting */
-       value = __raw_readl(FRQCRB);
-       value |= (1 << 31);
-       __raw_writel(value, FRQCRB);
+static void div4_kick(struct clk *clk)
+{
+       frqcr_kick();
 }
 
 static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,