summaryrefslogtreecommitdiff
path: root/arch/arm/plat-mxc/gic.c
diff options
context:
space:
mode:
authorShawn Guo <shawn.guo@linaro.org>2011-09-24 00:43:06 +0800
committerArnd Bergmann <arnd@arndb.de>2011-10-31 14:26:22 +0100
commit1103643c266ae45c7098e0f7f3ee0b68e3e7c7cc (patch)
treeb7fb2f16ee3f6f66bfef60c28c8adf88b54d7524 /arch/arm/plat-mxc/gic.c
parentbac89d754ba333453576fd38eb6073d7f89818fe (diff)
arm/imx: add gic_handle_irq function
This is a plain translation of assembly gic irq handler to C function for CONFIG_MULTI_IRQ_HANDLER support on imx family. Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Diffstat (limited to 'arch/arm/plat-mxc/gic.c')
-rw-r--r--arch/arm/plat-mxc/gic.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/arch/arm/plat-mxc/gic.c b/arch/arm/plat-mxc/gic.c
new file mode 100644
index 000000000000..b3b8eed263b8
--- /dev/null
+++ b/arch/arm/plat-mxc/gic.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/io.h>
+#include <asm/exception.h>
+#include <asm/localtimer.h>
+#include <asm/hardware/gic.h>
+#ifdef CONFIG_SMP
+#include <asm/smp.h>
+#endif
+
+asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
+{
+ u32 irqstat, irqnr;
+
+ do {
+ irqstat = readl_relaxed(gic_cpu_base_addr + GIC_CPU_INTACK);
+ irqnr = irqstat & 0x3ff;
+ if (irqnr == 1023)
+ break;
+
+ if (irqnr > 29 && irqnr < 1021)
+ handle_IRQ(irqnr, regs);
+#ifdef CONFIG_SMP
+ else if (irqnr < 16) {
+ writel_relaxed(irqstat, gic_cpu_base_addr +
+ GIC_CPU_EOI);
+ handle_IPI(irqnr, regs);
+ }
+#endif
+#ifdef CONFIG_LOCAL_TIMERS
+ else if (irqnr == 29) {
+ writel_relaxed(irqstat, gic_cpu_base_addr +
+ GIC_CPU_EOI);
+ handle_local_timer(regs);
+ }
+#endif
+ } while (1);
+}