diff options
| author | Jeremy Fitzhardinge <jeremy@goop.org> | 2009-02-06 17:09:41 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-02-09 06:16:05 -0500 |
| commit | 7c1d7cdcef1b54f4a78892b6b99d19f12c4f398e (patch) | |
| tree | b682c8a8d4ee0cf00de2ee6d00cd8fea37ad6339 | |
| parent | 9b2b76a3344146c4d8d300874e73af8161204f87 (diff) | |
x86: unify do_IRQ()
With the differences in interrupt handling hoisted into handle_irq(),
do_IRQ is more or less identical between 32 and 64 bit, so unify it.
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
| -rw-r--r-- | arch/x86/include/asm/irq.h | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/irq.c | 38 | ||||
| -rw-r--r-- | arch/x86/kernel/irq_32.c | 27 | ||||
| -rw-r--r-- | arch/x86/kernel/irq_64.c | 33 |
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) | |||
| 36 | extern void fixup_irqs(void); | 36 | extern void fixup_irqs(void); |
| 37 | #endif | 37 | #endif |
| 38 | 38 | ||
| 39 | extern unsigned int do_IRQ(struct pt_regs *regs); | ||
| 40 | extern void init_IRQ(void); | 39 | extern void init_IRQ(void); |
| 41 | extern void native_init_IRQ(void); | 40 | extern void native_init_IRQ(void); |
| 42 | extern bool handle_irq(unsigned irq, struct pt_regs *regs); | 41 | extern bool handle_irq(unsigned irq, struct pt_regs *regs); |
| 43 | 42 | ||
| 43 | extern unsigned int do_IRQ(struct pt_regs *regs); | ||
| 44 | |||
| 44 | /* Interrupt vector management */ | 45 | /* Interrupt vector management */ |
| 45 | extern DECLARE_BITMAP(used_vectors, NR_VECTORS); | 46 | extern DECLARE_BITMAP(used_vectors, NR_VECTORS); |
| 46 | extern int vector_used_by_percpu_irq(unsigned int vector); | 47 | extern 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 | ||
| 14 | atomic_t irq_err_count; | 16 | atomic_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 | */ | ||
| 199 | unsigned 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 | |||
| 191 | EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq); | 229 | EXPORT_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 | */ | ||
| 219 | unsigned 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 | */ | ||
| 70 | asmlinkage 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. */ |
| 100 | void fixup_irqs(void) | 67 | void fixup_irqs(void) |
