aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/irq.h3
-rw-r--r--arch/x86/kernel/irq.c38
-rw-r--r--arch/x86/kernel/irq_32.c27
-rw-r--r--arch/x86/kernel/irq_64.c33
4 files changed, 40 insertions, 61 deletions
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
index d0f6f7d1771c..107eb2196691 100644
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -36,11 +36,12 @@ static inline int irq_canonicalize(int irq)
36extern void fixup_irqs(void); 36extern void fixup_irqs(void);
37#endif 37#endif
38 38
39extern unsigned int do_IRQ(struct pt_regs *regs);
40extern void init_IRQ(void); 39extern void init_IRQ(void);
41extern void native_init_IRQ(void); 40extern void native_init_IRQ(void);
42extern bool handle_irq(unsigned irq, struct pt_regs *regs); 41extern bool handle_irq(unsigned irq, struct pt_regs *regs);
43 42
43extern unsigned int do_IRQ(struct pt_regs *regs);
44
44/* Interrupt vector management */ 45/* Interrupt vector management */
45extern DECLARE_BITMAP(used_vectors, NR_VECTORS); 46extern DECLARE_BITMAP(used_vectors, NR_VECTORS);
46extern int vector_used_by_percpu_irq(unsigned int vector); 47extern int vector_used_by_percpu_irq(unsigned int vector);
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 8b30d0c2512c..f13ca1650aaf 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -6,10 +6,12 @@
6#include <linux/kernel_stat.h> 6#include <linux/kernel_stat.h>
7#include <linux/seq_file.h> 7#include <linux/seq_file.h>
8#include <linux/smp.h> 8#include <linux/smp.h>
9#include <linux/ftrace.h>
9 10
10#include <asm/apic.h> 11#include <asm/apic.h>
11#include <asm/io_apic.h> 12#include <asm/io_apic.h>
12#include <asm/irq.h> 13#include <asm/irq.h>
14#include <asm/idle.h>
13 15
14atomic_t irq_err_count; 16atomic_t irq_err_count;
15 17
@@ -188,4 +190,40 @@ u64 arch_irq_stat(void)
188 return sum; 190 return sum;
189} 191}
190 192
193
194/*
195 * do_IRQ handles all normal device IRQ's (the special
196 * SMP cross-CPU interrupts have their own specific
197 * handlers).
198 */
199unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
200{
201 struct pt_regs *old_regs = set_irq_regs(regs);
202
203 /* high bit used in ret_from_ code */
204 unsigned vector = ~regs->orig_ax;
205 unsigned irq;
206
207 exit_idle();
208 irq_enter();
209
210 irq = __get_cpu_var(vector_irq)[vector];
211
212 if (!handle_irq(irq, regs)) {
213#ifdef CONFIG_X86_64
214 if (!disable_apic)
215 ack_APIC_irq();
216#endif
217
218 if (printk_ratelimit())
219 printk(KERN_EMERG "%s: %d.%d No irq handler for vector (irq %d)\n",
220 __func__, smp_processor_id(), vector, irq);
221 }
222
223 irq_exit();
224
225 set_irq_regs(old_regs);
226 return 1;
227}
228
191EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq); 229EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq);
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index 61f09fb969ee..4beb9a13873d 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -211,33 +211,6 @@ bool handle_irq(unsigned irq, struct pt_regs *regs)
211 return true; 211 return true;
212} 212}
213 213
214/*
215 * do_IRQ handles all normal device IRQ's (the special
216 * SMP cross-CPU interrupts have their own specific
217 * handlers).
218 */
219unsigned int do_IRQ(struct pt_regs *regs)
220{
221 struct pt_regs *old_regs;
222 /* high bit used in ret_from_ code */
223 unsigned vector = ~regs->orig_ax;
224 unsigned irq;
225
226 old_regs = set_irq_regs(regs);
227 irq_enter();
228 irq = __get_cpu_var(vector_irq)[vector];
229
230 if (!handle_irq(irq, regs)) {
231 printk(KERN_EMERG "%s: cannot handle IRQ %d vector %#x cpu %d\n",
232 __func__, irq, vector, smp_processor_id());
233 BUG();
234 }
235
236 irq_exit();
237 set_irq_regs(old_regs);
238 return 1;
239}
240
241#ifdef CONFIG_HOTPLUG_CPU 214#ifdef CONFIG_HOTPLUG_CPU
242#include <asm/genapic.h> 215#include <asm/genapic.h>
243 216
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index a93f3b0dc7f2..977d8b43a0dd 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -62,39 +62,6 @@ bool handle_irq(unsigned irq, struct pt_regs *regs)
62 return true; 62 return true;
63} 63}
64 64
65/*
66 * do_IRQ handles all normal device IRQ's (the special
67 * SMP cross-CPU interrupts have their own specific
68 * handlers).
69 */
70asmlinkage unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
71{
72 struct pt_regs *old_regs = set_irq_regs(regs);
73
74 /* high bit used in ret_from_ code */
75 unsigned vector = ~regs->orig_ax;
76 unsigned irq;
77
78 exit_idle();
79 irq_enter();
80
81 irq = __get_cpu_var(vector_irq)[vector];
82
83 if (!handle_irq(irq, regs)) {
84 if (!disable_apic)
85 ack_APIC_irq();
86
87 if (printk_ratelimit())
88 printk(KERN_EMERG "%s: %d.%d No irq handler for vector\n",
89 __func__, smp_processor_id(), vector);
90 }
91
92 irq_exit();
93
94 set_irq_regs(old_regs);
95 return 1;
96}
97
98#ifdef CONFIG_HOTPLUG_CPU 65#ifdef CONFIG_HOTPLUG_CPU
99/* A cpu has been removed from cpu_online_mask. Reset irq affinities. */ 66/* A cpu has been removed from cpu_online_mask. Reset irq affinities. */
100void fixup_irqs(void) 67void fixup_irqs(void)