summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2013-02-28 13:21:58 +0100
committerSimon Horman <horms+renesas@verge.net.au>2013-04-02 10:58:23 +0900
commit7653c318b73d8553d4c13bb7e371878ddc19f80d (patch)
treeec18d819e483d491e19c4f10bd4e6aa57a46de8b
parentd313d068d4b5801ea9c0c66bed66f37c64ad6807 (diff)
downloadlinux-stable-7653c318b73d8553d4c13bb7e371878ddc19f80d.tar.gz
linux-stable-7653c318b73d8553d4c13bb7e371878ddc19f80d.tar.bz2
linux-stable-7653c318b73d8553d4c13bb7e371878ddc19f80d.zip
ARM: shmobile: sh73a0: wait for completion when kicking the clock
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>
-rw-r--r--arch/arm/mach-shmobile/clock-sh73a0.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 71843dd39e16..34b5c5ae4cbd 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -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,