]>
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 | */ | |
c2609541 | 30 | static void resend_irqs(struct tasklet_struct *unused) |
a4633adc TG |
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: */ | |
c2609541 | 48 | static DECLARE_TASKLET(resend_tasklet, resend_irqs); |
a4633adc | 49 | |
1f85b1f5 TG |
50 | static int irq_sw_resend(struct irq_desc *desc) |
51 | { | |
52 | unsigned int irq = irq_desc_get_irq(desc); | |
53 | ||
54 | /* | |
55 | * Validate whether this interrupt can be safely injected from | |
56 | * non interrupt context | |
57 | */ | |
58 | if (handle_enforce_irqctx(&desc->irq_data)) | |
59 | return -EINVAL; | |
60 | ||
61 | /* | |
62 | * If the interrupt is running in the thread context of the parent | |
63 | * irq we need to be careful, because we cannot trigger it | |
64 | * directly. | |
65 | */ | |
66 | if (irq_settings_is_nested_thread(desc)) { | |
67 | /* | |
68 | * If the parent_irq is valid, we retrigger the parent, | |
69 | * otherwise we do nothing. | |
70 | */ | |
71 | if (!desc->parent_irq) | |
72 | return -EINVAL; | |
73 | irq = desc->parent_irq; | |
74 | } | |
75 | ||
76 | /* Set it pending and activate the softirq: */ | |
77 | set_bit(irq, irqs_resend); | |
78 | tasklet_schedule(&resend_tasklet); | |
79 | return 0; | |
80 | } | |
81 | ||
82 | #else | |
83 | static int irq_sw_resend(struct irq_desc *desc) | |
84 | { | |
85 | return -EINVAL; | |
86 | } | |
a4633adc TG |
87 | #endif |
88 | ||
cd1752d3 MZ |
89 | static int try_retrigger(struct irq_desc *desc) |
90 | { | |
91 | if (desc->irq_data.chip->irq_retrigger) | |
92 | return desc->irq_data.chip->irq_retrigger(&desc->irq_data); | |
93 | ||
94 | #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY | |
95 | return irq_chip_retrigger_hierarchy(&desc->irq_data); | |
96 | #else | |
97 | return 0; | |
98 | #endif | |
99 | } | |
100 | ||
a4633adc TG |
101 | /* |
102 | * IRQ resend | |
103 | * | |
104 | * Is called with interrupts disabled and desc->lock held. | |
105 | */ | |
acd26bcf | 106 | int check_irq_resend(struct irq_desc *desc, bool inject) |
a4633adc | 107 | { |
da90921a TG |
108 | int err = 0; |
109 | ||
2464286a | 110 | /* |
1f85b1f5 TG |
111 | * We do not resend level type interrupts. Level type interrupts |
112 | * are resent by hardware when they are still active. Clear the | |
113 | * pending bit so suspend/resume does not get confused. | |
2464286a | 114 | */ |
d4dc0f90 TG |
115 | if (irq_settings_is_level(desc)) { |
116 | desc->istate &= ~IRQS_PENDING; | |
1f85b1f5 | 117 | return -EINVAL; |
d4dc0f90 | 118 | } |
1f85b1f5 | 119 | |
163ef309 | 120 | if (desc->istate & IRQS_REPLAY) |
1f85b1f5 TG |
121 | return -EBUSY; |
122 | ||
acd26bcf | 123 | if (!(desc->istate & IRQS_PENDING) && !inject) |
da90921a | 124 | return 0; |
a4633adc | 125 | |
da90921a TG |
126 | desc->istate &= ~IRQS_PENDING; |
127 | ||
cd1752d3 | 128 | if (!try_retrigger(desc)) |
da90921a TG |
129 | err = irq_sw_resend(desc); |
130 | ||
5c982c58 | 131 | /* If the retrigger was successful, mark it with the REPLAY bit */ |
da90921a TG |
132 | if (!err) |
133 | desc->istate |= IRQS_REPLAY; | |
134 | return err; | |
a4633adc | 135 | } |
acd26bcf TG |
136 | |
137 | #ifdef CONFIG_GENERIC_IRQ_INJECTION | |
138 | /** | |
139 | * irq_inject_interrupt - Inject an interrupt for testing/error injection | |
140 | * @irq: The interrupt number | |
141 | * | |
142 | * This function must only be used for debug and testing purposes! | |
143 | * | |
144 | * Especially on x86 this can cause a premature completion of an interrupt | |
145 | * affinity change causing the interrupt line to become stale. Very | |
146 | * unlikely, but possible. | |
147 | * | |
148 | * The injection can fail for various reasons: | |
149 | * - Interrupt is not activated | |
150 | * - Interrupt is NMI type or currently replaying | |
151 | * - Interrupt is level type | |
152 | * - Interrupt does not support hardware retrigger and software resend is | |
153 | * either not enabled or not possible for the interrupt. | |
154 | */ | |
155 | int irq_inject_interrupt(unsigned int irq) | |
156 | { | |
157 | struct irq_desc *desc; | |
158 | unsigned long flags; | |
159 | int err; | |
160 | ||
161 | /* Try the state injection hardware interface first */ | |
162 | if (!irq_set_irqchip_state(irq, IRQCHIP_STATE_PENDING, true)) | |
163 | return 0; | |
164 | ||
165 | /* That failed, try via the resend mechanism */ | |
166 | desc = irq_get_desc_buslock(irq, &flags, 0); | |
167 | if (!desc) | |
168 | return -EINVAL; | |
169 | ||
170 | /* | |
171 | * Only try to inject when the interrupt is: | |
172 | * - not NMI type | |
173 | * - activated | |
174 | */ | |
175 | if ((desc->istate & IRQS_NMI) || !irqd_is_activated(&desc->irq_data)) | |
176 | err = -EINVAL; | |
177 | else | |
178 | err = check_irq_resend(desc, true); | |
179 | ||
180 | irq_put_desc_busunlock(desc, flags); | |
181 | return err; | |
182 | } | |
183 | EXPORT_SYMBOL_GPL(irq_inject_interrupt); | |
184 | #endif |