aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/irq.c')
-rw-r--r--arch/i386/kernel/irq.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
index 061533e0cb5e..16b491703967 100644
--- a/arch/i386/kernel/irq.c
+++ b/arch/i386/kernel/irq.c
@@ -53,13 +53,19 @@ static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
53 */ 53 */
54fastcall unsigned int do_IRQ(struct pt_regs *regs) 54fastcall unsigned int do_IRQ(struct pt_regs *regs)
55{ 55{
56 /* high bits used in ret_from_ code */ 56 /* high bit used in ret_from_ code */
57 int irq = regs->orig_eax & 0xff; 57 int irq = ~regs->orig_eax;
58#ifdef CONFIG_4KSTACKS 58#ifdef CONFIG_4KSTACKS
59 union irq_ctx *curctx, *irqctx; 59 union irq_ctx *curctx, *irqctx;
60 u32 *isp; 60 u32 *isp;
61#endif 61#endif
62 62
63 if (unlikely((unsigned)irq >= NR_IRQS)) {
64 printk(KERN_EMERG "%s: cannot handle IRQ %d\n",
65 __FUNCTION__, irq);
66 BUG();
67 }
68
63 irq_enter(); 69 irq_enter();
64#ifdef CONFIG_DEBUG_STACKOVERFLOW 70#ifdef CONFIG_DEBUG_STACKOVERFLOW
65 /* Debugging check for stack overflow: is there less than 1KB free? */ 71 /* Debugging check for stack overflow: is there less than 1KB free? */
@@ -76,6 +82,10 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs)
76 } 82 }
77#endif 83#endif
78 84
85 if (!irq_desc[irq].handle_irq) {
86 __do_IRQ(irq, regs);
87 goto out_exit;
88 }
79#ifdef CONFIG_4KSTACKS 89#ifdef CONFIG_4KSTACKS
80 90
81 curctx = (union irq_ctx *) current_thread_info(); 91 curctx = (union irq_ctx *) current_thread_info();
@@ -100,8 +110,8 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs)
100 * softirq checks work in the hardirq context. 110 * softirq checks work in the hardirq context.
101 */ 111 */
102 irqctx->tinfo.preempt_count = 112 irqctx->tinfo.preempt_count =
103 irqctx->tinfo.preempt_count & ~SOFTIRQ_MASK | 113 (irqctx->tinfo.preempt_count & ~SOFTIRQ_MASK) |
104 curctx->tinfo.preempt_count & SOFTIRQ_MASK; 114 (curctx->tinfo.preempt_count & SOFTIRQ_MASK);
105 115
106 asm volatile( 116 asm volatile(
107 " xchgl %%ebx,%%esp \n" 117 " xchgl %%ebx,%%esp \n"
@@ -115,6 +125,7 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs)
115#endif 125#endif
116 __do_IRQ(irq, regs); 126 __do_IRQ(irq, regs);
117 127
128out_exit:
118 irq_exit(); 129 irq_exit();
119 130
120 return 1; 131 return 1;
@@ -243,7 +254,7 @@ int show_interrupts(struct seq_file *p, void *v)
243 for_each_online_cpu(j) 254 for_each_online_cpu(j)
244 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); 255 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
245#endif 256#endif
246 seq_printf(p, " %14s", irq_desc[i].handler->typename); 257 seq_printf(p, " %14s", irq_desc[i].chip->typename);
247 seq_printf(p, " %s", action->name); 258 seq_printf(p, " %s", action->name);
248 259
249 for (action=action->next; action; action = action->next) 260 for (action=action->next; action; action = action->next)
@@ -285,13 +296,13 @@ void fixup_irqs(cpumask_t map)
285 if (irq == 2) 296 if (irq == 2)
286 continue; 297 continue;
287 298
288 cpus_and(mask, irq_affinity[irq], map); 299 cpus_and(mask, irq_desc[irq].affinity, map);
289 if (any_online_cpu(mask) == NR_CPUS) { 300 if (any_online_cpu(mask) == NR_CPUS) {
290 printk("Breaking affinity for irq %i\n", irq); 301 printk("Breaking affinity for irq %i\n", irq);
291 mask = map; 302 mask = map;
292 } 303 }
293 if (irq_desc[irq].handler->set_affinity) 304 if (irq_desc[irq].chip->set_affinity)
294 irq_desc[irq].handler->set_affinity(irq, mask); 305 irq_desc[irq].chip->set_affinity(irq, mask);
295 else if (irq_desc[irq].action && !(warned++)) 306 else if (irq_desc[irq].action && !(warned++))
296 printk("Cannot set affinity for irq %i\n", irq); 307 printk("Cannot set affinity for irq %i\n", irq);
297 } 308 }