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