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); |
eddf3e9c YY |
39 | if (!desc) |
40 | continue; | |
6a6de9ef | 41 | local_irq_disable(); |
bd0b9ac4 | 42 | desc->handle_irq(desc); |
6a6de9ef | 43 | local_irq_enable(); |
a4633adc TG |
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 | */ | |
0798abeb | 57 | void check_irq_resend(struct irq_desc *desc) |
a4633adc | 58 | { |
2464286a TG |
59 | /* |
60 | * We do not resend level type interrupts. Level type | |
61 | * interrupts are resent by hardware when they are still | |
d4dc0f90 TG |
62 | * active. Clear the pending bit so suspend/resume does not |
63 | * get confused. | |
2464286a | 64 | */ |
d4dc0f90 TG |
65 | if (irq_settings_is_level(desc)) { |
66 | desc->istate &= ~IRQS_PENDING; | |
87923470 | 67 | return; |
d4dc0f90 | 68 | } |
163ef309 TG |
69 | if (desc->istate & IRQS_REPLAY) |
70 | return; | |
2a0d6fb3 | 71 | if (desc->istate & IRQS_PENDING) { |
2a0d6fb3 | 72 | desc->istate &= ~IRQS_PENDING; |
163ef309 | 73 | desc->istate |= IRQS_REPLAY; |
a4633adc | 74 | |
21e2b8c6 TG |
75 | if (!desc->irq_data.chip->irq_retrigger || |
76 | !desc->irq_data.chip->irq_retrigger(&desc->irq_data)) { | |
a4633adc | 77 | #ifdef CONFIG_HARDIRQS_SW_RESEND |
0798abeb JL |
78 | unsigned int irq = irq_desc_get_irq(desc); |
79 | ||
293a7a0a | 80 | /* |
75a06189 TG |
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. | |
293a7a0a | 85 | */ |
75a06189 TG |
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; | |
293a7a0a | 94 | irq = desc->parent_irq; |
75a06189 | 95 | } |
a4633adc TG |
96 | /* Set it pending and activate the softirq: */ |
97 | set_bit(irq, irqs_resend); | |
98 | tasklet_schedule(&resend_tasklet); | |
99 | #endif | |
100 | } | |
101 | } | |
102 | } |