msm: board-msm7x27a: Add support for CONFIG_MULTI_IRQ_HANDLER

MULTI_IRQ_HANDLER support for 7x27a device

Change-Id: I5b2aeee7c9000cb5c349a57d9d1c7cadd3863e19
Signed-off-by: Taniya Das <tdas@codeaurora.org>
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 99655d0..0eb414f 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -229,6 +229,7 @@
 	bool
 	select MSM_DALRPC
 	select MSM_PROC_COMM_REGULATOR
+	select MULTI_IRQ_HANDLER
 
 config  MSM_VIC
 	bool
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 67b1dcc..51bd856 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -3249,6 +3249,7 @@
 	.init_machine	= msm7627a_rumi3_init,
 	.timer		= &msm_timer,
 	.init_early     = msm7x2x_init_early,
+	.handle_irq	= vic_handle_irq,
 MACHINE_END
 MACHINE_START(MSM7X27A_SURF, "QCT MSM7x27a SURF")
 	.boot_params	= PHYS_OFFSET + 0x100,
@@ -3258,6 +3259,7 @@
 	.init_machine	= msm7x2x_init,
 	.timer		= &msm_timer,
 	.init_early     = msm7x2x_init_early,
+	.handle_irq	= vic_handle_irq,
 MACHINE_END
 MACHINE_START(MSM7X27A_FFA, "QCT MSM7x27a FFA")
 	.boot_params	= PHYS_OFFSET + 0x100,
@@ -3267,6 +3269,7 @@
 	.init_machine	= msm7x2x_init,
 	.timer		= &msm_timer,
 	.init_early     = msm7x2x_init_early,
+	.handle_irq	= vic_handle_irq,
 MACHINE_END
 MACHINE_START(MSM7625A_SURF, "QCT MSM7625a SURF")
 	.boot_params    = PHYS_OFFSET + 0x100,
@@ -3276,6 +3279,7 @@
 	.init_machine   = msm7x2x_init,
 	.timer          = &msm_timer,
 	.init_early     = msm7x2x_init_early,
+	.handle_irq	= vic_handle_irq,
 MACHINE_END
 MACHINE_START(MSM7625A_FFA, "QCT MSM7625a FFA")
 	.boot_params    = PHYS_OFFSET + 0x100,
@@ -3285,4 +3289,5 @@
 	.init_machine   = msm7x2x_init,
 	.timer          = &msm_timer,
 	.init_early     = msm7x2x_init_early,
+	.handle_irq	= vic_handle_irq,
 MACHINE_END
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index df6a64c..349b2d0 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -419,6 +419,7 @@
 void __init msm_map_msm7x30_io(void);
 void __init msm_map_fsm9xxx_io(void);
 void __init msm_init_irq(void);
+void vic_handle_irq(struct pt_regs *regs);
 
 struct mmc_platform_data;
 int __init msm_add_sdcc(unsigned int controller,
diff --git a/arch/arm/mach-msm/include/mach/entry-macro.S b/arch/arm/mach-msm/include/mach/entry-macro.S
index eb5921f..d384366 100644
--- a/arch/arm/mach-msm/include/mach/entry-macro.S
+++ b/arch/arm/mach-msm/include/mach/entry-macro.S
@@ -10,11 +10,15 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
-
-#if defined(CONFIG_MSM_VIC)
+#if defined(CONFIG_MSM_VIC) && !defined(CONFIG_MULTI_IRQ_HANDLER)
 #include <mach/entry-macro-vic.S>
 #elif defined(CONFIG_ARM_GIC)
 #include <mach/entry-macro-qgic.S>
 #else
-#error "No interrupt controller selected!"
+	.macro	disable_fiq
+	.endm
+
+	.macro	arch_ret_to_user, tmp1, tmp2
+	.endm
+
 #endif
diff --git a/arch/arm/mach-msm/irq-vic.c b/arch/arm/mach-msm/irq-vic.c
index 109231a..660d530 100644
--- a/arch/arm/mach-msm/irq-vic.c
+++ b/arch/arm/mach-msm/irq-vic.c
@@ -610,6 +610,33 @@
 	mb();
 }
 
+static inline void msm_vic_handle_irq(void __iomem *base_addr, struct pt_regs
+		*regs)
+{
+	u32 irqnr;
+
+	do {
+		/* 0xD0 has irq# or old irq# if the irq has been handled
+		 * 0xD4 has irq# or -1 if none pending *but* if you just
+		 * read 0xD4 you never get the first irq for some reason
+		 */
+		irqnr = readl_relaxed(base_addr + 0xD0);
+		irqnr = readl_relaxed(base_addr + 0xD4);
+		if (irqnr == -1)
+			break;
+		handle_IRQ(irqnr, regs);
+	} while (1);
+}
+
+/* enable imprecise aborts */
+#define local_cpsie_enable()  __asm__ __volatile__("cpsie a    @ enable")
+
+asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs)
+{
+	local_cpsie_enable();
+	msm_vic_handle_irq((void __iomem *)MSM_VIC_BASE, regs);
+}
+
 #if defined(CONFIG_MSM_FIQ_SUPPORT)
 void msm_trigger_irq(int irq)
 {