1/* Modified by Broadcom Corp. Portions Copyright (c) Broadcom Corp, 2012. */ 2/* 3 * linux/kernel/irq/spurious.c 4 * 5 * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar 6 * 7 * This file contains spurious interrupt handling. 8 */ 9 10#include <linux/jiffies.h> 11#include <linux/irq.h> 12#include <linux/module.h> 13#include <linux/kallsyms.h> 14#include <linux/interrupt.h> 15#include <linux/moduleparam.h> 16#include <linux/timer.h> 17 18#if defined(CONFIG_BUZZZ) 19#include <asm/buzzz.h> 20#endif /* CONFIG_BUZZZ */ 21 22static int irqfixup __read_mostly; 23 24#define POLL_SPURIOUS_IRQ_INTERVAL (HZ/10) 25static void poll_spurious_irqs(unsigned long dummy); 26static DEFINE_TIMER(poll_spurious_irq_timer, poll_spurious_irqs, 0, 0); 27 28/* 29 * Recovery handler for misrouted interrupts. 30 */ 31static int try_one_irq(int irq, struct irq_desc *desc) 32{ 33 struct irqaction *action; 34 int ok = 0, work = 0; 35 36#if defined(BUZZZ_KEVT_LVL) && (BUZZZ_KEVT_LVL >= 1) 37 buzzz_kevt_log1(BUZZZ_KEVT_ID_IRQ_MISROUTED, irq); 38#endif /* BUZZZ_KEVT_LVL */ 39 40 raw_spin_lock(&desc->lock); 41 /* Already running on another processor */ 42 if (desc->status & IRQ_INPROGRESS) { 43 /* 44 * Already running: If it is shared get the other 45 * CPU to go looking for our mystery interrupt too 46 */ 47 if (desc->action && (desc->action->flags & IRQF_SHARED)) 48 desc->status |= IRQ_PENDING; 49 raw_spin_unlock(&desc->lock); 50 return ok; 51 } 52 /* Honour the normal IRQ locking */ 53 desc->status |= IRQ_INPROGRESS; 54 action = desc->action; 55 raw_spin_unlock(&desc->lock); 56 57 while (action) { 58 /* Only shared IRQ handlers are safe to call */ 59 if (action->flags & IRQF_SHARED) { 60 if (action->handler(irq, action->dev_id) == 61 IRQ_HANDLED) 62 ok = 1; 63 } 64 action = action->next; 65 } 66 local_irq_disable(); 67 /* Now clean up the flags */ 68 raw_spin_lock(&desc->lock); 69 action = desc->action; 70 71 /* 72 * While we were looking for a fixup someone queued a real 73 * IRQ clashing with our walk: 74 */ 75 while ((desc->status & IRQ_PENDING) && action) { 76 /* 77 * Perform real IRQ processing for the IRQ we deferred 78 */ 79 work = 1; 80 raw_spin_unlock(&desc->lock); 81 handle_IRQ_event(irq, action); 82 raw_spin_lock(&desc->lock); 83 desc->status &= ~IRQ_PENDING; 84 } 85 desc->status &= ~IRQ_INPROGRESS; 86 /* 87 * If we did actual work for the real IRQ line we must let the 88 * IRQ controller clean up too 89 */ 90 if (work && desc->chip && desc->chip->end) 91 desc->chip->end(irq); 92 raw_spin_unlock(&desc->lock); 93 94 return ok; 95} 96 97static int misrouted_irq(int irq) 98{ 99 struct irq_desc *desc; 100 int i, ok = 0; 101 102 for_each_irq_desc(i, desc) { 103 if (!i) 104 continue; 105 106 if (i == irq) /* Already tried */ 107 continue; 108 109 if (try_one_irq(i, desc)) 110 ok = 1; 111 } 112 /* So the caller can adjust the irq error counts */ 113 return ok; 114} 115 116static void poll_spurious_irqs(unsigned long dummy) 117{ 118 struct irq_desc *desc; 119 int i; 120 121 for_each_irq_desc(i, desc) { 122 unsigned int status; 123 124 if (!i) 125 continue; 126 127 /* Racy but it doesn't matter */ 128 status = desc->status; 129 barrier(); 130 if (!(status & IRQ_SPURIOUS_DISABLED)) 131 continue; 132 133 local_irq_disable(); 134 try_one_irq(i, desc); 135 local_irq_enable(); 136 } 137 138 mod_timer(&poll_spurious_irq_timer, 139 jiffies + POLL_SPURIOUS_IRQ_INTERVAL); 140} 141 142/* 143 * If 99,900 of the previous 100,000 interrupts have not been handled 144 * then assume that the IRQ is stuck in some manner. Drop a diagnostic 145 * and try to turn the IRQ off. 146 * 147 * (The other 100-of-100,000 interrupts may have been a correctly 148 * functioning device sharing an IRQ with the failing one) 149 * 150 * Called under desc->lock 151 */ 152 153static void 154__report_bad_irq(unsigned int irq, struct irq_desc *desc, 155 irqreturn_t action_ret) 156{ 157 struct irqaction *action; 158 159 if (action_ret != IRQ_HANDLED && action_ret != IRQ_NONE) { 160 printk(KERN_ERR "irq event %d: bogus return value %x\n", 161 irq, action_ret); 162 } else { 163 printk(KERN_ERR "irq %d: nobody cared (try booting with " 164 "the \"irqpoll\" option)\n", irq); 165 } 166 dump_stack(); 167 printk(KERN_ERR "handlers:\n"); 168 169 action = desc->action; 170 while (action) { 171 printk(KERN_ERR "[<%p>]", action->handler); 172 print_symbol(" (%s)", 173 (unsigned long)action->handler); 174 printk("\n"); 175 action = action->next; 176 } 177} 178 179static void 180report_bad_irq(unsigned int irq, struct irq_desc *desc, irqreturn_t action_ret) 181{ 182 static int count = 100; 183 184 if (count > 0) { 185 count--; 186 __report_bad_irq(irq, desc, action_ret); 187 } 188} 189 190static inline int 191try_misrouted_irq(unsigned int irq, struct irq_desc *desc, 192 irqreturn_t action_ret) 193{ 194 struct irqaction *action; 195 196 if (!irqfixup) 197 return 0; 198 199 /* We didn't actually handle the IRQ - see if it was misrouted? */ 200 if (action_ret == IRQ_NONE) 201 return 1; 202 203 /* 204 * But for 'irqfixup == 2' we also do it for handled interrupts if 205 * they are marked as IRQF_IRQPOLL (or for irq zero, which is the 206 * traditional PC timer interrupt.. Legacy) 207 */ 208 if (irqfixup < 2) 209 return 0; 210 211 if (!irq) 212 return 1; 213 214 /* 215 * Since we don't get the descriptor lock, "action" can 216 * change under us. We don't really care, but we don't 217 * want to follow a NULL pointer. So tell the compiler to 218 * just load it once by using a barrier. 219 */ 220 action = desc->action; 221 barrier(); 222 return action && (action->flags & IRQF_IRQPOLL); 223} 224 225void note_interrupt(unsigned int irq, struct irq_desc *desc, 226 irqreturn_t action_ret) 227{ 228 if (unlikely(action_ret != IRQ_HANDLED)) { 229 /* 230 * If we are seeing only the odd spurious IRQ caused by 231 * bus asynchronicity then don't eventually trigger an error, 232 * otherwise the counter becomes a doomsday timer for otherwise 233 * working systems 234 */ 235 if (time_after(jiffies, desc->last_unhandled + HZ/10)) 236 desc->irqs_unhandled = 1; 237 else 238 desc->irqs_unhandled++; 239 desc->last_unhandled = jiffies; 240 if (unlikely(action_ret != IRQ_NONE)) 241 report_bad_irq(irq, desc, action_ret); 242 } 243 244 if (unlikely(try_misrouted_irq(irq, desc, action_ret))) { 245 int ok = misrouted_irq(irq); 246 if (action_ret == IRQ_NONE) 247 desc->irqs_unhandled -= ok; 248 } 249 250 desc->irq_count++; 251 if (likely(desc->irq_count < 100000)) 252 return; 253 254 desc->irq_count = 0; 255 if (unlikely(desc->irqs_unhandled > 99900)) { 256 /* 257 * The interrupt is stuck 258 */ 259 __report_bad_irq(irq, desc, action_ret); 260 /* 261 * Now kill the IRQ 262 */ 263 printk(KERN_EMERG "Disabling IRQ #%d\n", irq); 264 desc->status |= IRQ_DISABLED | IRQ_SPURIOUS_DISABLED; 265 desc->depth++; 266 desc->chip->disable(irq); 267 268 mod_timer(&poll_spurious_irq_timer, 269 jiffies + POLL_SPURIOUS_IRQ_INTERVAL); 270 } 271 desc->irqs_unhandled = 0; 272} 273 274int noirqdebug __read_mostly; 275 276int noirqdebug_setup(char *str) 277{ 278 noirqdebug = 1; 279 printk(KERN_INFO "IRQ lockup detection disabled\n"); 280 281 return 1; 282} 283 284__setup("noirqdebug", noirqdebug_setup); 285module_param(noirqdebug, bool, 0644); 286MODULE_PARM_DESC(noirqdebug, "Disable irq lockup detection when true"); 287 288static int __init irqfixup_setup(char *str) 289{ 290 irqfixup = 1; 291 printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n"); 292 printk(KERN_WARNING "This may impact system performance.\n"); 293 294 return 1; 295} 296 297__setup("irqfixup", irqfixup_setup); 298module_param(irqfixup, int, 0644); 299 300static int __init irqpoll_setup(char *str) 301{ 302 irqfixup = 2; 303 printk(KERN_WARNING "Misrouted IRQ fixup and polling support " 304 "enabled\n"); 305 printk(KERN_WARNING "This may significantly impact system " 306 "performance\n"); 307 return 1; 308} 309 310__setup("irqpoll", irqpoll_setup); 311