diff options
author | Rabin Vincent <rabin.vincent@stericsson.com> | 2011-03-17 11:11:57 +0530 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@stericsson.com> | 2011-09-19 15:14:59 +0200 |
commit | 0a2ff4f76523ac1b6559bd92f5d568abbbcf0184 (patch) | |
tree | 26588f91ee22f80206a87b8ffc1fe20ca97a8ffe | |
parent | bc794a2f9721a54beda922f8fe7ff146750a64e1 (diff) |
ux500: pm: enable clocks before touching PRCC
If the peripheral cluster clock is gated, touching registers inside the cluster
will cause a hang. Enable the clocks before touching the PRCC registers in the
context code.
ST-Ericsson Linux next: -
ST-Ericsson ID: ER327234
ST-Ericsson FOSS-OUT ID: Trivial
Change-Id: I7b3c751192a81e6a812241cb0fba14ff42b1495f
Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/18541
Reviewed-by: Rickard ANDERSSON <rickard.andersson@stericsson.com>
Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com>
-rw-r--r-- | arch/arm/mach-ux500/pm/context.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/arch/arm/mach-ux500/pm/context.c b/arch/arm/mach-ux500/pm/context.c index 4763ae74e71..248fbdbd3a6 100644 --- a/arch/arm/mach-ux500/pm/context.c +++ b/arch/arm/mach-ux500/pm/context.c @@ -16,6 +16,8 @@ #include <linux/slab.h> #include <linux/device.h> #include <linux/notifier.h> +#include <linux/clk.h> +#include <linux/err.h> #include <mach/hardware.h> #include <mach/irqs.h> @@ -164,6 +166,7 @@ static struct { #define UX500_NR_PRCC_BANKS 5 static struct { void __iomem *base; + struct clk *clk; u32 bus_clk; u32 kern_clk; } context_prcc[UX500_NR_PRCC_BANKS]; @@ -242,10 +245,14 @@ static void save_prcc(void) int i; for (i = 0; i < UX500_NR_PRCC_BANKS; i++) { + clk_enable(context_prcc[i].clk); + context_prcc[i].bus_clk = readl(context_prcc[i].base + PRCC_BCK_STATUS); context_prcc[i].kern_clk = readl(context_prcc[i].base + PRCC_KCK_STATUS); + + clk_disable(context_prcc[i].clk); } } @@ -254,10 +261,14 @@ static void restore_prcc(void) int i; for (i = 0; i < UX500_NR_PRCC_BANKS; i++) { + clk_enable(context_prcc[i].clk); + writel(context_prcc[i].bus_clk, context_prcc[i].base + PRCC_BCK_EN); writel(context_prcc[i].kern_clk, context_prcc[i].base + PRCC_KCK_EN); + + clk_disable(context_prcc[i].clk); } } @@ -875,6 +886,16 @@ static int __init context_init(void) context_prcc[3].base = ioremap(U8500_CLKRST5_BASE, SZ_4K); context_prcc[4].base = ioremap(U8500_CLKRST6_BASE, SZ_4K); + for (i = 0; i < ARRAY_SIZE(context_prcc); i++) { + const int clusters[] = {1, 2, 3, 5, 6}; + char clkname[10]; + + snprintf(clkname, sizeof(clkname), "PERIPH%d", clusters[i]); + + context_prcc[i].clk = clk_get_sys(clkname, NULL); + BUG_ON(IS_ERR(context_prcc[i].clk)); + } + if (cpu_is_u8500()) { u8500_context_init(); } else if (cpu_is_u5500()) { |