Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
a4633adc | 2 | /* |
a4633adc TG |
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: */ | |
c1ee6264 | 25 | static DECLARE_BITMAP(irqs_resend, IRQ_BITMAP_BITS); |
a4633adc TG |
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 | ||
85c0f909 YL |
35 | while (!bitmap_empty(irqs_resend, nr_irqs)) { |
36 | irq = find_first_bit(irqs_resend, nr_irqs); | |
a4633adc | 37 | clear_bit(irq, irqs_resend); |
08678b08 | 38 | desc = irq_to_desc(irq); |
6a6de9ef | 39 | local_irq_disable(); |
bd0b9ac4 | 40 | desc->handle_irq(desc); |
6a6de9ef | 41 | local_irq_enable(); |
a4633adc TG |
42 | } |
43 | } | |
44 | ||
45 | /* Tasklet to handle resend: */ | |
46 | static DECLARE_TASKLET(resend_tasklet, resend_irqs, 0); | |
47 | ||
48 | #endif | |
49 | ||
50 | /* | |
51 | * IRQ resend | |
52 | * | |
53 | * Is called with interrupts disabled and desc->lock held. | |
54 | */ | |
0798abeb | 55 | void check_irq_resend(struct irq_desc *desc) |
a4633adc | 56 | { |
2464286a TG |
57 | /* |
58 | * We do not resend level type interrupts. Level type | |
59 | * interrupts are resent by hardware when they are still | |
d4dc0f90 TG |
60 | * active. Clear the pending bit so suspend/resume does not |
61 | * get confused. | |
2464286a | 62 | */ |
d4dc0f90 TG |
63 | if (irq_settings_is_level(desc)) { |
64 | desc->istate &= ~IRQS_PENDING; | |
87923470 | 65 | return; |
d4dc0f90 | 66 | } |
163ef309 TG |
67 | if (desc->istate & IRQS_REPLAY) |
68 | return; | |
2a0d6fb3 | 69 | if (desc->istate & IRQS_PENDING) { |
2a0d6fb3 | 70 | desc->istate &= ~IRQS_PENDING; |
163ef309 | 71 | desc->istate |= IRQS_REPLAY; |
a4633adc | 72 | |
21e2b8c6 TG |
73 | if (!desc->irq_data.chip->irq_retrigger || |
74 | !desc->irq_data.chip->irq_retrigger(&desc->irq_data)) { | |
a4633adc | 75 | #ifdef CONFIG_HARDIRQS_SW_RESEND |
0798abeb JL |
76 | unsigned int irq = irq_desc_get_irq(desc); |
77 | ||
293a7a0a | 78 | /* |
75a06189 TG |
79 | * If the interrupt is running in the thread |
80 | * context of the parent irq we need to be | |
81 | * careful, because we cannot trigger it | |
82 | * directly. | |
293a7a0a | 83 | */ |
75a06189 TG |
84 | if (irq_settings_is_nested_thread(desc)) { |
85 | /* | |
86 | * If the parent_irq is valid, we | |
87 | * retrigger the parent, otherwise we | |
88 | * do nothing. | |
89 | */ | |
90 | if (!desc->parent_irq) | |
91 | return; | |
293a7a0a | 92 | irq = desc->parent_irq; |
75a06189 | 93 | } |
a4633adc TG |
94 | /* Set it pending and activate the softirq: */ |
95 | set_bit(irq, irqs_resend); | |
96 | tasklet_schedule(&resend_tasklet); | |
97 | #endif | |
98 | } | |
99 | } | |
100 | } |