diff options
Diffstat (limited to 'kernel/irq/handle.c')
-rw-r--r-- | kernel/irq/handle.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index 9ebf77968871..fe8f45374e86 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c | |||
@@ -357,8 +357,37 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action) | |||
357 | 357 | ||
358 | do { | 358 | do { |
359 | ret = action->handler(irq, action->dev_id); | 359 | ret = action->handler(irq, action->dev_id); |
360 | if (ret == IRQ_HANDLED) | 360 | |
361 | switch (ret) { | ||
362 | case IRQ_WAKE_THREAD: | ||
363 | /* | ||
364 | * Wake up the handler thread for this | ||
365 | * action. In case the thread crashed and was | ||
366 | * killed we just pretend that we handled the | ||
367 | * interrupt. The hardirq handler above has | ||
368 | * disabled the device interrupt, so no irq | ||
369 | * storm is lurking. | ||
370 | */ | ||
371 | if (likely(!test_bit(IRQTF_DIED, | ||
372 | &action->thread_flags))) { | ||
373 | set_bit(IRQTF_RUNTHREAD, &action->thread_flags); | ||
374 | wake_up_process(action->thread); | ||
375 | } | ||
376 | |||
377 | /* | ||
378 | * Set it to handled so the spurious check | ||
379 | * does not trigger. | ||
380 | */ | ||
381 | ret = IRQ_HANDLED; | ||
382 | /* Fall through to add to randomness */ | ||
383 | case IRQ_HANDLED: | ||
361 | status |= action->flags; | 384 | status |= action->flags; |
385 | break; | ||
386 | |||
387 | default: | ||
388 | break; | ||
389 | } | ||
390 | |||
362 | retval |= ret; | 391 | retval |= ret; |
363 | action = action->next; | 392 | action = action->next; |
364 | } while (action); | 393 | } while (action); |