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: */ 26 static DECLARE_BITMAP(irqs_resend, IRQ_BITMAP_BITS); 27 28 /* 29 * Run software resends of IRQ's 30 */ 31 static 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(desc); 42 local_irq_enable(); 43 } 44 } 45 46 /* Tasklet to handle resend: */ 47 static 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 */ 56 void check_irq_resend(struct irq_desc *desc) 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 unsigned int irq = irq_desc_get_irq(desc); 78 79 /* 80 * If the interrupt is running in the thread 81 * context of the parent irq we need to be 82 * careful, because we cannot trigger it 83 * directly. 84 */ 85 if (irq_settings_is_nested_thread(desc)) { 86 /* 87 * If the parent_irq is valid, we 88 * retrigger the parent, otherwise we 89 * do nothing. 90 */ 91 if (!desc->parent_irq) 92 return; 93 irq = desc->parent_irq; 94 } 95 /* Set it pending and activate the softirq: */ 96 set_bit(irq, irqs_resend); 97 tasklet_schedule(&resend_tasklet); 98 #endif 99 } 100 } 101 } 102