select GENERIC_SCHED_CLOCK
        select GENERIC_SMP_IDLE_THREAD
        select HANDLE_DOMAIN_IRQ
-       select HANDLE_DOMAIN_IRQ_IRQENTRY
        select HARDIRQS_SW_RESEND
        select HAVE_ARCH_AUDITSYSCALL if AEABI && !OABI_COMPAT
        select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6
 
  */
        .macro  irq_handler
 #ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER
-       ldr     r1, =handle_arch_irq
        mov     r0, sp
-       badr    lr, 9997f
-       ldr     pc, [r1]
+       bl      generic_handle_arch_irq
 #else
        arch_irq_handler_default
 #endif
-9997:
        .endm
 
        .macro  pabt_helper
 
  */
 void handle_IRQ(unsigned int irq, struct pt_regs *regs)
 {
-       struct pt_regs *old_regs = set_irq_regs(regs);
        struct irq_desc *desc;
 
-       irq_enter();
-
        /*
         * Some hardware gives randomly wrong interrupts.  Rather
         * than crashing, do something sensible.
                handle_irq_desc(desc);
        else
                ack_bad_irq(irq);
-
-       irq_exit();
-       set_irq_regs(old_regs);
 }
 
 /*
 asmlinkage void __exception_irq_entry
 asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
 {
+       struct pt_regs *old_regs;
+
+       irq_enter();
+       old_regs = set_irq_regs(regs);
+
        handle_IRQ(irq, regs);
+
+       set_irq_regs(old_regs);
+       irq_exit();
 }
 
 void __init init_IRQ(void)
 
 
 static struct irq_domain *nvic_irq_domain;
 
+static void __nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs)
+{
+       handle_domain_irq(nvic_irq_domain, hwirq, regs);
+}
+
+/*
+ * TODO: restructure the ARMv7M entry logic so that this entry logic can live
+ * in arch code.
+ */
 asmlinkage void __exception_irq_entry
 nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs)
 {
-       handle_domain_irq(nvic_irq_domain, hwirq, regs);
+       struct pt_regs *old_regs;
+
+       irq_enter();
+       old_regs = set_irq_regs(regs);
+       __nvic_handle_irq(hwirq, regs);
+       set_irq_regs(old_regs);
+       irq_exit();
 }
 
 static int nvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,