This source file includes following definitions.
- probe_irq_on
- probe_irq_mask
- probe_irq_off
1
2
3
4
5
6
7
8 #include <linux/irq.h>
9 #include <linux/module.h>
10 #include <linux/interrupt.h>
11 #include <linux/delay.h>
12 #include <linux/async.h>
13
14 #include "internals.h"
15
16
17
18
19
20
21 static DEFINE_MUTEX(probing_active);
22
23
24
25
26
27
28
29
30 unsigned long probe_irq_on(void)
31 {
32 struct irq_desc *desc;
33 unsigned long mask = 0;
34 int i;
35
36
37
38
39 async_synchronize_full();
40 mutex_lock(&probing_active);
41
42
43
44
45 for_each_irq_desc_reverse(i, desc) {
46 raw_spin_lock_irq(&desc->lock);
47 if (!desc->action && irq_settings_can_probe(desc)) {
48
49
50
51
52 if (desc->irq_data.chip->irq_set_type)
53 desc->irq_data.chip->irq_set_type(&desc->irq_data,
54 IRQ_TYPE_PROBE);
55 irq_activate_and_startup(desc, IRQ_NORESEND);
56 }
57 raw_spin_unlock_irq(&desc->lock);
58 }
59
60
61 msleep(20);
62
63
64
65
66
67
68 for_each_irq_desc_reverse(i, desc) {
69 raw_spin_lock_irq(&desc->lock);
70 if (!desc->action && irq_settings_can_probe(desc)) {
71 desc->istate |= IRQS_AUTODETECT | IRQS_WAITING;
72 if (irq_activate_and_startup(desc, IRQ_NORESEND))
73 desc->istate |= IRQS_PENDING;
74 }
75 raw_spin_unlock_irq(&desc->lock);
76 }
77
78
79
80
81 msleep(100);
82
83
84
85
86 for_each_irq_desc(i, desc) {
87 raw_spin_lock_irq(&desc->lock);
88
89 if (desc->istate & IRQS_AUTODETECT) {
90
91 if (!(desc->istate & IRQS_WAITING)) {
92 desc->istate &= ~IRQS_AUTODETECT;
93 irq_shutdown_and_deactivate(desc);
94 } else
95 if (i < 32)
96 mask |= 1 << i;
97 }
98 raw_spin_unlock_irq(&desc->lock);
99 }
100
101 return mask;
102 }
103 EXPORT_SYMBOL(probe_irq_on);
104
105
106
107
108
109
110
111
112
113
114
115
116
117 unsigned int probe_irq_mask(unsigned long val)
118 {
119 unsigned int mask = 0;
120 struct irq_desc *desc;
121 int i;
122
123 for_each_irq_desc(i, desc) {
124 raw_spin_lock_irq(&desc->lock);
125 if (desc->istate & IRQS_AUTODETECT) {
126 if (i < 16 && !(desc->istate & IRQS_WAITING))
127 mask |= 1 << i;
128
129 desc->istate &= ~IRQS_AUTODETECT;
130 irq_shutdown_and_deactivate(desc);
131 }
132 raw_spin_unlock_irq(&desc->lock);
133 }
134 mutex_unlock(&probing_active);
135
136 return mask & val;
137 }
138 EXPORT_SYMBOL(probe_irq_mask);
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157 int probe_irq_off(unsigned long val)
158 {
159 int i, irq_found = 0, nr_of_irqs = 0;
160 struct irq_desc *desc;
161
162 for_each_irq_desc(i, desc) {
163 raw_spin_lock_irq(&desc->lock);
164
165 if (desc->istate & IRQS_AUTODETECT) {
166 if (!(desc->istate & IRQS_WAITING)) {
167 if (!nr_of_irqs)
168 irq_found = i;
169 nr_of_irqs++;
170 }
171 desc->istate &= ~IRQS_AUTODETECT;
172 irq_shutdown_and_deactivate(desc);
173 }
174 raw_spin_unlock_irq(&desc->lock);
175 }
176 mutex_unlock(&probing_active);
177
178 if (nr_of_irqs > 1)
179 irq_found = -irq_found;
180
181 return irq_found;
182 }
183 EXPORT_SYMBOL(probe_irq_off);
184