irq: arm: perform irqentry in entry code
In preparation for removing HANDLE_DOMAIN_IRQ_IRQENTRY, have arch/arm perform all the irqentry accounting in its entry code. For configurations with CONFIG_GENERIC_IRQ_MULTI_HANDLER, we can use generic_handle_arch_irq(). Other than asm_do_IRQ(), all C calls to handle_IRQ() are from irqchip handlers which will be called from generic_handle_arch_irq(), so to avoid double accounting IRQ entry, the entry logic is moved from handle_IRQ() into asm_do_IRQ(). For ARMv7M the entry assembly is tightly coupled with the NVIC irqchip, and while the entry code should logically live under arch/arm/, moving the entry logic there makes things more convoluted. So for now, place the entry logic in the NVIC irqchip, but separated into a separate function to make the split of responsibility clear. For all other configurations without CONFIG_GENERIC_IRQ_MULTI_HANDLER, IRQ entry is already handled in arch code, and requires no changes. There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Marc Zyngier <maz@kernel.org> Tested-by: Vladimir Murzin <vladimir.murzin@arm.com> # ARMv7M Cc: Russell King <linux@armlinux.org.uk> Cc: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
2fe35f8ee7
commit
a7b0872e96
|
@ -65,7 +65,6 @@ config ARM
|
|||
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
|
||||
|
|
|
@ -38,14 +38,11 @@
|
|||
*/
|
||||
.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
|
||||
|
|
|
@ -63,11 +63,8 @@ int arch_show_interrupts(struct seq_file *p, int prec)
|
|||
*/
|
||||
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.
|
||||
|
@ -81,9 +78,6 @@ void handle_IRQ(unsigned int irq, struct pt_regs *regs)
|
|||
handle_irq_desc(desc);
|
||||
else
|
||||
ack_bad_irq(irq);
|
||||
|
||||
irq_exit();
|
||||
set_irq_regs(old_regs);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -92,7 +86,15 @@ void handle_IRQ(unsigned int irq, struct pt_regs *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)
|
||||
|
|
|
@ -37,10 +37,25 @@
|
|||
|
||||
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,
|
||||
|
|
Loading…
Reference in New Issue