Root/
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: */ |
26 | static DECLARE_BITMAP(irqs_resend, IRQ_BITMAP_BITS); |
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 | |
36 | while (!bitmap_empty(irqs_resend, nr_irqs)) { |
37 | irq = find_first_bit(irqs_resend, nr_irqs); |
38 | clear_bit(irq, irqs_resend); |
39 | desc = irq_to_desc(irq); |
40 | local_irq_disable(); |
41 | desc->handle_irq(irq, desc); |
42 | local_irq_enable(); |
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 | */ |
56 | void check_irq_resend(struct irq_desc *desc, unsigned int irq) |
57 | { |
58 | unsigned int status = desc->status; |
59 | |
60 | /* |
61 | * Make sure the interrupt is enabled, before resending it: |
62 | */ |
63 | desc->irq_data.chip->irq_enable(&desc->irq_data); |
64 | |
65 | /* |
66 | * We do not resend level type interrupts. Level type |
67 | * interrupts are resent by hardware when they are still |
68 | * active. |
69 | */ |
70 | if ((status & (IRQ_LEVEL | IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { |
71 | desc->status = (status & ~IRQ_PENDING) | IRQ_REPLAY; |
72 | |
73 | if (!desc->irq_data.chip->irq_retrigger || |
74 | !desc->irq_data.chip->irq_retrigger(&desc->irq_data)) { |
75 | #ifdef CONFIG_HARDIRQS_SW_RESEND |
76 | /* Set it pending and activate the softirq: */ |
77 | set_bit(irq, irqs_resend); |
78 | tasklet_schedule(&resend_tasklet); |
79 | #endif |
80 | } |
81 | } |
82 | } |
83 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9