aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/irq_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/irq_64.c')
-rw-r--r--arch/x86/kernel/irq_64.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index 018963aa6ee3..a93f3b0dc7f2 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -48,6 +48,20 @@ static inline void stack_overflow_check(struct pt_regs *regs)
48#endif 48#endif
49} 49}
50 50
51bool handle_irq(unsigned irq, struct pt_regs *regs)
52{
53 struct irq_desc *desc;
54
55 stack_overflow_check(regs);
56
57 desc = irq_to_desc(irq);
58 if (unlikely(!desc))
59 return false;
60
61 generic_handle_irq_desc(irq, desc);
62 return true;
63}
64
51/* 65/*
52 * do_IRQ handles all normal device IRQ's (the special 66 * do_IRQ handles all normal device IRQ's (the special
53 * SMP cross-CPU interrupts have their own specific 67 * SMP cross-CPU interrupts have their own specific
@@ -56,7 +70,6 @@ static inline void stack_overflow_check(struct pt_regs *regs)
56asmlinkage unsigned int __irq_entry do_IRQ(struct pt_regs *regs) 70asmlinkage unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
57{ 71{
58 struct pt_regs *old_regs = set_irq_regs(regs); 72 struct pt_regs *old_regs = set_irq_regs(regs);
59 struct irq_desc *desc;
60 73
61 /* high bit used in ret_from_ code */ 74 /* high bit used in ret_from_ code */
62 unsigned vector = ~regs->orig_ax; 75 unsigned vector = ~regs->orig_ax;
@@ -64,14 +77,10 @@ asmlinkage unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
64 77
65 exit_idle(); 78 exit_idle();
66 irq_enter(); 79 irq_enter();
67 irq = __get_cpu_var(vector_irq)[vector];
68 80
69 stack_overflow_check(regs); 81 irq = __get_cpu_var(vector_irq)[vector];
70 82
71 desc = irq_to_desc(irq); 83 if (!handle_irq(irq, regs)) {
72 if (likely(desc))
73 generic_handle_irq_desc(irq, desc);
74 else {
75 if (!disable_apic) 84 if (!disable_apic)
76 ack_APIC_irq(); 85 ack_APIC_irq();
77 86