summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/gic.c
diff options
context:
space:
mode:
authorScott Williams <scwilliams@nvidia.com>2012-02-01 17:06:50 -0800
committerVarun Wadekar <vwadekar@nvidia.com>2012-06-22 18:29:54 +0530
commit7a2e5ae3e6c26ca91281787913fa1c547285cceb (patch)
treee02415b59db194e2b2052bf57b8da7ecedb3f4ac /arch/arm/mach-tegra/gic.c
parent513162b825d2034cbfcd6623ce9537caf69d270c (diff)
ARM: tegra: Reprogram GIC CPU interface on CPU PM entry
To prevent race conditions and ensure proper interrupt routing on Cortex-A15 CPUs when they are power-gated, add a CPU PM notifier call-back to reprogram the GIC CPU interface on PM entry. The GIC CPU interface will be reset back to its normal state by the common GIC CPU PM exit callback when the CPU wakes up. BUG 929216 Change-Id: I2280468a001b41ca2a9db8edfcd7bd65f82b1fcd Signed-off-by: Scott Williams <scwilliams@nvidia.com> Reviewed-on: http://git-master/r/79091 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Aleksandr Frid <afrid@nvidia.com> Reviewed-by: Varun Wadekar <vwadekar@nvidia.com> Reviewed-by: Jin Qian <jqian@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/gic.c')
-rw-r--r--arch/arm/mach-tegra/gic.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/gic.c b/arch/arm/mach-tegra/gic.c
index 5162c6331598..2b21effe7977 100644
--- a/arch/arm/mach-tegra/gic.c
+++ b/arch/arm/mach-tegra/gic.c
@@ -18,6 +18,7 @@
#include <linux/irqnr.h>
#include <asm/hardware/gic.h>
+#include <asm/cpu_pm.h>
#include <mach/iomap.h>
#include <mach/irqs.h>
@@ -128,6 +129,27 @@ void tegra_gic_affinity_to_cpu0(void)
wmb();
}
#endif
+
+static int tegra_gic_notifier(struct notifier_block *self, unsigned long cmd, void *v)
+{
+ u32 gic_cpu_ctrl;
+
+ switch (cmd) {
+ case CPU_PM_ENTER:
+ gic_cpu_ctrl = readl(tegra_gic_cpu_base + GIC_CPU_CTRL);
+ if (gic_cpu_ctrl & 1) {
+ gic_cpu_ctrl |= 0x1E0;
+ writel(gic_cpu_ctrl, tegra_gic_cpu_base + GIC_CPU_CTRL);
+ }
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block tegra_gic_notifier_block = {
+ .notifier_call = tegra_gic_notifier,
+};
#endif
void __init tegra_gic_init(void)
@@ -146,4 +168,9 @@ void __init tegra_gic_init(void)
gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE),
tegra_gic_cpu_base);
+
+#ifdef CONFIG_PM_SLEEP
+ if (is_vgic)
+ cpu_pm_register_notifier(&tegra_gic_notifier_block);
+#endif
}