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 __read_mostly; 15 16 /* 17 * Recovery handler for misrouted interrupts. 18 */ 19 static int misrouted_irq(int irq) 20 { 21 int i; 22 int ok = 0; 23 int work = 0; /* Did we do work for a real IRQ */ 24 25 for (i = 1; i < NR_IRQS; i++) { 26 struct irq_desc *desc = irq_desc + i; 27 struct irqaction *action; 28 29 if (i == irq) /* Already tried */ 30 continue; 31 32 spin_lock(&desc->lock); 33 /* Already running on another processor */ 34 if (desc->status & IRQ_INPROGRESS) { 35 /* 36 * Already running: If it is shared get the other 37 * CPU to go looking for our mystery interrupt too 38 */ 39 if (desc->action && (desc->action->flags & IRQF_SHARED)) 40 desc->status |= IRQ_PENDING; 41 spin_unlock(&desc->lock); 42 continue; 43 } 44 /* Honour the normal IRQ locking */ 45 desc->status |= IRQ_INPROGRESS; 46 action = desc->action; 47 spin_unlock(&desc->lock); 48 49 while (action) { 50 /* Only shared IRQ handlers are safe to call */ 51 if (action->flags & IRQF_SHARED) { 52 if (action->handler(i, action->dev_id) == 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 while ((desc->status & IRQ_PENDING) && action) { 68 /* 69 * Perform real IRQ processing for the IRQ we deferred 70 */ 71 work = 1; 72 spin_unlock(&desc->lock); 73 handle_IRQ_event(i, action); 74 spin_lock(&desc->lock); 75 desc->status &= ~IRQ_PENDING; 76 } 77 desc->status &= ~IRQ_INPROGRESS; 78 /* 79 * If we did actual work for the real IRQ line we must let the 80 * IRQ controller clean up too 81 */ 82 if (work && desc->chip && desc->chip->end) 83 desc->chip->end(i); 84 spin_unlock(&desc->lock); 85 } 86 /* So the caller can adjust the irq error counts */ 87 return ok; 88 } 89 90 /* 91 * If 99,900 of the previous 100,000 interrupts have not been handled 92 * then assume that the IRQ is stuck in some manner. Drop a diagnostic 93 * and try to turn the IRQ off. 94 * 95 * (The other 100-of-100,000 interrupts may have been a correctly 96 * functioning device sharing an IRQ with the failing one) 97 * 98 * Called under desc->lock 99 */ 100 101 static void 102 __report_bad_irq(unsigned int irq, struct irq_desc *desc, 103 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 117 action = desc->action; 118 while (action) { 119 printk(KERN_ERR "[<%p>]", action->handler); 120 print_symbol(" (%s)", 121 (unsigned long)action->handler); 122 printk("\n"); 123 action = action->next; 124 } 125 } 126 127 static void 128 report_bad_irq(unsigned int irq, struct irq_desc *desc, irqreturn_t action_ret) 129 { 130 static int count = 100; 131 132 if (count > 0) { 133 count--; 134 __report_bad_irq(irq, desc, action_ret); 135 } 136 } 137 138 void note_interrupt(unsigned int irq, struct irq_desc *desc, 139 irqreturn_t action_ret) 140 { 141 if (unlikely(action_ret != IRQ_HANDLED)) { 142 desc->irqs_unhandled++; 143 if (unlikely(action_ret != IRQ_NONE)) 144 report_bad_irq(irq, desc, action_ret); 145 } 146 147 if (unlikely(irqfixup)) { 148 /* Don't punish working computers */ 149 if ((irqfixup == 2 && irq == 0) || action_ret == IRQ_NONE) { 150 int ok = misrouted_irq(irq); 151 if (action_ret == IRQ_NONE) 152 desc->irqs_unhandled -= ok; 153 } 154 } 155 156 desc->irq_count++; 157 if (likely(desc->irq_count < 100000)) 158 return; 159 160 desc->irq_count = 0; 161 if (unlikely(desc->irqs_unhandled > 99900)) { 162 /* 163 * The interrupt is stuck 164 */ 165 __report_bad_irq(irq, desc, action_ret); 166 /* 167 * Now kill the IRQ 168 */ 169 printk(KERN_EMERG "Disabling IRQ #%d\n", irq); 170 desc->status |= IRQ_DISABLED; 171 desc->depth = 1; 172 desc->chip->disable(irq); 173 } 174 desc->irqs_unhandled = 0; 175 } 176 177 int noirqdebug __read_mostly; 178 179 int noirqdebug_setup(char *str) 180 { 181 noirqdebug = 1; 182 printk(KERN_INFO "IRQ lockup detection disabled\n"); 183 184 return 1; 185 } 186 187 __setup("noirqdebug", noirqdebug_setup); 188 189 static int __init irqfixup_setup(char *str) 190 { 191 irqfixup = 1; 192 printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n"); 193 printk(KERN_WARNING "This may impact system performance.\n"); 194 195 return 1; 196 } 197 198 __setup("irqfixup", irqfixup_setup); 199 200 static int __init irqpoll_setup(char *str) 201 { 202 irqfixup = 2; 203 printk(KERN_WARNING "Misrouted IRQ fixup and polling support " 204 "enabled\n"); 205 printk(KERN_WARNING "This may significantly impact system " 206 "performance\n"); 207 return 1; 208 } 209 210 __setup("irqpoll", irqpoll_setup); 211