diff options
-rw-r--r-- | include/linux/irq.h | 1 | ||||
-rw-r--r-- | kernel/irq/spurious.c | 12 |
2 files changed, 12 insertions, 1 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h index 1695054e8c63..44657197fcb0 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -161,6 +161,7 @@ struct irq_desc { | |||
161 | unsigned int wake_depth; /* nested wake enables */ | 161 | unsigned int wake_depth; /* nested wake enables */ |
162 | unsigned int irq_count; /* For detecting broken IRQs */ | 162 | unsigned int irq_count; /* For detecting broken IRQs */ |
163 | unsigned int irqs_unhandled; | 163 | unsigned int irqs_unhandled; |
164 | unsigned long last_unhandled; /* Aging timer for unhandled count */ | ||
164 | spinlock_t lock; | 165 | spinlock_t lock; |
165 | #ifdef CONFIG_SMP | 166 | #ifdef CONFIG_SMP |
166 | cpumask_t affinity; | 167 | cpumask_t affinity; |
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c index bd9e272d55e9..32b161972fad 100644 --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c | |||
@@ -172,7 +172,17 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc, | |||
172 | irqreturn_t action_ret) | 172 | irqreturn_t action_ret) |
173 | { | 173 | { |
174 | if (unlikely(action_ret != IRQ_HANDLED)) { | 174 | if (unlikely(action_ret != IRQ_HANDLED)) { |
175 | desc->irqs_unhandled++; | 175 | /* |
176 | * If we are seeing only the odd spurious IRQ caused by | ||
177 | * bus asynchronicity then don't eventually trigger an error, | ||
178 | * otherwise the couter becomes a doomsday timer for otherwise | ||
179 | * working systems | ||
180 | */ | ||
181 | if (jiffies - desc->last_unhandled > HZ/10) | ||
182 | desc->irqs_unhandled = 1; | ||
183 | else | ||
184 | desc->irqs_unhandled++; | ||
185 | desc->last_unhandled = jiffies; | ||
176 | if (unlikely(action_ret != IRQ_NONE)) | 186 | if (unlikely(action_ret != IRQ_NONE)) |
177 | report_bad_irq(irq, desc, action_ret); | 187 | report_bad_irq(irq, desc, action_ret); |
178 | } | 188 | } |