1/* 2 * linux/kernel/irq/resend.c 3 * 4 * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar 5 * Copyright (C) 2005-2006, Thomas Gleixner 6 * 7 * This file contains the IRQ-resend code 8 * 9 * If the interrupt is waiting to be processed, we try to re-run it. 10 * We can't directly run it from here since the caller might be in an 11 * interrupt-protected region. Not all irq controller chips can 12 * retrigger interrupts at the hardware level, so in those cases 13 * we allow the resending of IRQs via a tasklet. 14 */ 15 16#include <linux/irq.h> 17#include <linux/module.h> 18#include <linux/random.h> 19#include <linux/interrupt.h> 20 21#include "internals.h" 22 23#ifdef CONFIG_HARDIRQS_SW_RESEND 24 25/* Bitmap to handle software resend of interrupts: */ 26static DECLARE_BITMAP(irqs_resend, IRQ_BITMAP_BITS); 27 28/* 29 * Run software resends of IRQ's 30 */ 31static void resend_irqs(unsigned long arg) 32{ 33 struct irq_desc *desc; 34 int irq; 35 36 while (!bitmap_empty(irqs_resend, nr_irqs)) { 37 irq = find_first_bit(irqs_resend, nr_irqs); 38 clear_bit(irq, irqs_resend); 39 desc = irq_to_desc(irq); 40 local_irq_disable(); 41 desc->handle_irq(irq, desc); 42 local_irq_enable(); 43 } 44} 45 46/* Tasklet to handle resend: */ 47static DECLARE_TASKLET(resend_tasklet, resend_irqs, 0); 48 49#endif 50 51/* 52 * IRQ resend 53 * 54 * Is called with interrupts disabled and desc->lock held. 55 */ 56void check_irq_resend(struct irq_desc *desc, unsigned int irq) 57{ 58 /* 59 * We do not resend level type interrupts. Level type 60 * interrupts are resent by hardware when they are still 61 * active. Clear the pending bit so suspend/resume does not 62 * get confused. 63 */ 64 if (irq_settings_is_level(desc)) { 65 desc->istate &= ~IRQS_PENDING; 66 return; 67 } 68 if (desc->istate & IRQS_REPLAY) 69 return; 70 if (desc->istate & IRQS_PENDING) { 71 desc->istate &= ~IRQS_PENDING; 72 desc->istate |= IRQS_REPLAY; 73 74 if (!desc->irq_data.chip->irq_retrigger || 75 !desc->irq_data.chip->irq_retrigger(&desc->irq_data)) { 76#ifdef CONFIG_HARDIRQS_SW_RESEND 77 /* 78 * If the interrupt is running in the thread 79 * context of the parent irq we need to be 80 * careful, because we cannot trigger it 81 * directly. 82 */ 83 if (irq_settings_is_nested_thread(desc)) { 84 /* 85 * If the parent_irq is valid, we 86 * retrigger the parent, otherwise we 87 * do nothing. 88 */ 89 if (!desc->parent_irq) 90 return; 91 irq = desc->parent_irq; 92 } 93 /* Set it pending and activate the softirq: */ 94 set_bit(irq, irqs_resend); 95 tasklet_schedule(&resend_tasklet); 96#endif 97 } 98 } 99} 100