aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq/spurious.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/irq/spurious.c')
-rw-r--r--kernel/irq/spurious.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index c9a78ba30b6..aa57d5da18c 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -167,6 +167,13 @@ out:
167 jiffies + POLL_SPURIOUS_IRQ_INTERVAL); 167 jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
168} 168}
169 169
170static inline int bad_action_ret(irqreturn_t action_ret)
171{
172 if (likely(action_ret <= (IRQ_HANDLED | IRQ_WAKE_THREAD)))
173 return 0;
174 return 1;
175}
176
170/* 177/*
171 * If 99,900 of the previous 100,000 interrupts have not been handled 178 * If 99,900 of the previous 100,000 interrupts have not been handled
172 * then assume that the IRQ is stuck in some manner. Drop a diagnostic 179 * then assume that the IRQ is stuck in some manner. Drop a diagnostic
@@ -182,7 +189,7 @@ __report_bad_irq(unsigned int irq, struct irq_desc *desc,
182 struct irqaction *action; 189 struct irqaction *action;
183 unsigned long flags; 190 unsigned long flags;
184 191
185 if (action_ret != IRQ_HANDLED && action_ret != IRQ_NONE) { 192 if (bad_action_ret(action_ret)) {
186 printk(KERN_ERR "irq event %d: bogus return value %x\n", 193 printk(KERN_ERR "irq event %d: bogus return value %x\n",
187 irq, action_ret); 194 irq, action_ret);
188 } else { 195 } else {
@@ -263,7 +270,16 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc,
263 if (desc->istate & IRQS_POLL_INPROGRESS) 270 if (desc->istate & IRQS_POLL_INPROGRESS)
264 return; 271 return;
265 272
266 if (unlikely(action_ret != IRQ_HANDLED)) { 273 /* we get here again via the threaded handler */
274 if (action_ret == IRQ_WAKE_THREAD)
275 return;
276
277 if (bad_action_ret(action_ret)) {
278 report_bad_irq(irq, desc, action_ret);
279 return;
280 }
281
282 if (unlikely(action_ret == IRQ_NONE)) {
267 /* 283 /*
268 * If we are seeing only the odd spurious IRQ caused by 284 * If we are seeing only the odd spurious IRQ caused by
269 * bus asynchronicity then don't eventually trigger an error, 285 * bus asynchronicity then don't eventually trigger an error,
@@ -275,8 +291,6 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc,
275 else 291 else
276 desc->irqs_unhandled++; 292 desc->irqs_unhandled++;
277 desc->last_unhandled = jiffies; 293 desc->last_unhandled = jiffies;
278 if (unlikely(action_ret != IRQ_NONE))
279 report_bad_irq(irq, desc, action_ret);
280 } 294 }
281 295
282 if (unlikely(try_misrouted_irq(irq, desc, action_ret))) { 296 if (unlikely(try_misrouted_irq(irq, desc, action_ret))) {