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