summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRabin Vincent <rabin.vincent@stericsson.com>2011-03-17 11:11:57 +0530
committerUlf Hansson <ulf.hansson@stericsson.com>2011-09-19 15:14:59 +0200
commit0a2ff4f76523ac1b6559bd92f5d568abbbcf0184 (patch)
tree26588f91ee22f80206a87b8ffc1fe20ca97a8ffe
parentbc794a2f9721a54beda922f8fe7ff146750a64e1 (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.c21
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()) {