1 /* 2 * linux/kernel/irq/spurious.c 3 * 4 * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar 5 * 6 * This file contains spurious interrupt handling. 7 */ 8 9 #include <linux/irq.h> 10 #include <linux/module.h> 11 #include <linux/kallsyms.h> 12 #include <linux/interrupt.h> 13 14 static int irqfixup; 15 16 /* 17 * Recovery handler for misrouted interrupts. 18 */ 19 20 static int misrouted_irq(int irq, struct pt_regs *regs) 21 { 22 int i; 23 irq_desc_t *desc; 24 int ok = 0; 25 int work = 0; /* Did we do work for a real IRQ */ 26 27 for(i = 1; i < NR_IRQS; i++) { 28 struct irqaction *action; 29 30 if (i == irq) /* Already tried */ 31 continue; 32 desc = &irq_desc[i]; 33 spin_lock(&desc->lock); 34 action = desc->action; 35 /* Already running on another processor */ 36 if (desc->status & IRQ_INPROGRESS) { 37 /* 38 * Already running: If it is shared get the other 39 * CPU to go looking for our mystery interrupt too 40 */ 41 if (desc->action && (desc->action->flags & SA_SHIRQ)) 42 desc->status |= IRQ_PENDING; 43 spin_unlock(&desc->lock); 44 continue; 45 } 46 /* Honour the normal IRQ locking */ 47 desc->status |= IRQ_INPROGRESS; 48 spin_unlock(&desc->lock); 49 while (action) { 50 /* Only shared IRQ handlers are safe to call */ 51 if (action->flags & SA_SHIRQ) { 52 if (action->handler(i, action->dev_id, regs) == 53 IRQ_HANDLED) 54 ok = 1; 55 } 56 action = action->next; 57 } 58 local_irq_disable(); 59 /* Now clean up the flags */ 60 spin_lock(&desc->lock); 61 action = desc->action; 62 63 /* 64 * While we were looking for a fixup someone queued a real 65 * IRQ clashing with our walk 66 */ 67 68 while ((desc->status & IRQ_PENDING) && action) { 69 /* 70 * Perform real IRQ processing for the IRQ we deferred 71 */ 72 work = 1; 73 spin_unlock(&desc->lock); 74 handle_IRQ_event(i, regs, action); 75 spin_lock(&desc->lock); 76 desc->status &= ~IRQ_PENDING; 77 } 78 desc->status &= ~IRQ_INPROGRESS; 79 /* 80 * If we did actual work for the real IRQ line we must let the 81 * IRQ controller clean up too 82 */ 83 if(work) 84 desc->handler->end(i); 85 spin_unlock(&desc->lock); 86 } 87 /* So the caller can adjust the irq error counts */ 88 return ok; 89 } 90 91 /* 92 * If 99,900 of the previous 100,000 interrupts have not been handled 93 * then assume that the IRQ is stuck in some manner. Drop a diagnostic 94 * and try to turn the IRQ off. 95 * 96 * (The other 100-of-100,000 interrupts may have been a correctly 97 * functioning device sharing an IRQ with the failing one) 98 * 99 * Called under desc->lock 100 */ 101 102 static void 103 __report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) 104 { 105 struct irqaction *action; 106 107 if (action_ret != IRQ_HANDLED && action_ret != IRQ_NONE) { 108 printk(KERN_ERR "irq event %d: bogus return value %x\n", 109 irq, action_ret); 110 } else { 111 printk(KERN_ERR "irq %d: nobody cared (try booting with " 112 "the \"irqpoll\" option)\n", irq); 113 } 114 dump_stack(); 115 printk(KERN_ERR "handlers:\n"); 116 action = desc->action; 117 while (action) { 118 printk(KERN_ERR "[<%p>]", action->handler); 119 print_symbol(" (%s)", 120 (unsigned long)action->handler); 121 printk("\n"); 122 action = action->next; 123 } 124 } 125 126 static void report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) 127 { 128 static int count = 100; 129 130 if (count > 0) { 131 count--; 132 __report_bad_irq(irq, desc, action_ret); 133 } 134 } 135 136 void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret, 137 struct pt_regs *regs) 138 { 139 if (action_ret != IRQ_HANDLED) { 140 desc->irqs_unhandled++; 141 if (action_ret != IRQ_NONE) 142 report_bad_irq(irq, desc, action_ret); 143 } 144 145 if (unlikely(irqfixup)) { 146 /* Don't punish working computers */ 147 if ((irqfixup == 2 && irq == 0) || action_ret == IRQ_NONE) { 148 int ok = misrouted_irq(irq, regs); 149 if (action_ret == IRQ_NONE) 150 desc->irqs_unhandled -= ok; 151 } 152 } 153 154 desc->irq_count++; 155 if (desc->irq_count < 100000) 156 return; 157 158 desc->irq_count = 0; 159 if (desc->irqs_unhandled > 99900) { 160 /* 161 * The interrupt is stuck 162 */ 163 __report_bad_irq(irq, desc, action_ret); 164 /* 165 * Now kill the IRQ 166 */ 167 printk(KERN_EMERG "Disabling IRQ #%d\n", irq); 168 desc->status |= IRQ_DISABLED; 169 desc->handler->disable(irq); 170 } 171 desc->irqs_unhandled = 0; 172 } 173 174 int noirqdebug; 175 176 int __init noirqdebug_setup(char *str) 177 { 178 noirqdebug = 1; 179 printk(KERN_INFO "IRQ lockup detection disabled\n"); 180 return 1; 181 } 182 183 __setup("noirqdebug", noirqdebug_setup); 184 185 static int __init irqfixup_setup(char *str) 186 { 187 irqfixup = 1; 188 printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n"); 189 printk(KERN_WARNING "This may impact system performance.\n"); 190 return 1; 191 } 192 193 __setup("irqfixup", irqfixup_setup); 194 195 static int __init irqpoll_setup(char *str) 196 { 197 irqfixup = 2; 198 printk(KERN_WARNING "Misrouted IRQ fixup and polling support " 199 "enabled\n"); 200 printk(KERN_WARNING "This may significantly impact system " 201 "performance\n"); 202 return 1; 203 } 204 205 __setup("irqpoll", irqpoll_setup); 206