]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
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>
Thu, 20 Oct 2011 21:38:56 +0000 (23:38 +0200)
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 d53c35fe2ea71cfb67f8684446b017457862e07b..b9f0f5f499a4e7906f19e69568c59938adcd5fcf 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 ace4bb550edc6d7e02fd9d58da572a38e4e3a4e8..c2258374488a41efefce55c66ed2ffa7265b28b0 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 842fbcb0d6cc6263cd6a7dca269a274200214393..9fe0dfcf4e7e02a85e0d4e944829d9f43305d74c 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