arm/imx: add gic_handle_irq function
authorShawn Guo <shawn.guo@linaro.org>
Fri, 23 Sep 2011 16:43:06 +0000 (00:43 +0800)
committerArnd Bergmann <arnd@arndb.de>
Mon, 31 Oct 2011 13:26:22 +0000 (14:26 +0100)
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>
arch/arm/plat-mxc/Makefile
arch/arm/plat-mxc/gic.c [new file with mode: 0644]
arch/arm/plat-mxc/include/mach/common.h
arch/arm/plat-mxc/include/mach/entry-macro.S

index d53c35f..b9f0f5f 100644 (file)
@@ -5,7 +5,7 @@
 # Common support
 obj-y := clock.o time.o devices.o cpu.o system.o irq-common.o
 
-# MX51 uses the TZIC interrupt controller, older platforms use AVIC
+obj-$(CONFIG_ARM_GIC) += gic.o
 obj-$(CONFIG_MXC_TZIC) += tzic.o
 obj-$(CONFIG_MXC_AVIC) += avic.o
 
diff --git a/arch/arm/plat-mxc/gic.c b/arch/arm/plat-mxc/gic.c
new file mode 100644 (file)
index 0000000..b3b8eed
--- /dev/null
@@ -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);
+}
index ace4bb5..c225837 100644 (file)
@@ -86,6 +86,7 @@ extern void imx_print_silicon_rev(const char *cpu, int srev);
 
 void avic_handle_irq(struct pt_regs *);
 void tzic_handle_irq(struct pt_regs *);
+void gic_handle_irq(struct pt_regs *);
 
 #define imx1_handle_irq avic_handle_irq
 #define imx21_handle_irq avic_handle_irq
@@ -96,5 +97,6 @@ void tzic_handle_irq(struct pt_regs *);
 #define imx50_handle_irq tzic_handle_irq
 #define imx51_handle_irq tzic_handle_irq
 #define imx53_handle_irq tzic_handle_irq
+#define imx6q_handle_irq gic_handle_irq
 
 #endif
index 842fbcb..9fe0dfc 100644 (file)
@@ -22,3 +22,9 @@
 
        .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
        .endm
+
+       .macro test_for_ipi, irqnr, irqstat, base, tmp
+       .endm
+
+       .macro test_for_ltirq, irqnr, irqstat, base, tmp
+       .endm