diff options
Diffstat (limited to 'kernel/irq/autoprobe.c')
-rw-r--r-- | kernel/irq/autoprobe.c | 57 |
1 files changed, 23 insertions, 34 deletions
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c index 2295a31ef110..342d8f44e401 100644 --- a/kernel/irq/autoprobe.c +++ b/kernel/irq/autoprobe.c | |||
@@ -17,7 +17,7 @@ | |||
17 | /* | 17 | /* |
18 | * Autodetection depends on the fact that any interrupt that | 18 | * Autodetection depends on the fact that any interrupt that |
19 | * comes in on to an unassigned handler will get stuck with | 19 | * comes in on to an unassigned handler will get stuck with |
20 | * "IRQ_WAITING" cleared and the interrupt disabled. | 20 | * "IRQS_WAITING" cleared and the interrupt disabled. |
21 | */ | 21 | */ |
22 | static DEFINE_MUTEX(probing_active); | 22 | static DEFINE_MUTEX(probing_active); |
23 | 23 | ||
@@ -32,7 +32,6 @@ unsigned long probe_irq_on(void) | |||
32 | { | 32 | { |
33 | struct irq_desc *desc; | 33 | struct irq_desc *desc; |
34 | unsigned long mask = 0; | 34 | unsigned long mask = 0; |
35 | unsigned int status; | ||
36 | int i; | 35 | int i; |
37 | 36 | ||
38 | /* | 37 | /* |
@@ -46,20 +45,15 @@ unsigned long probe_irq_on(void) | |||
46 | */ | 45 | */ |
47 | for_each_irq_desc_reverse(i, desc) { | 46 | for_each_irq_desc_reverse(i, desc) { |
48 | raw_spin_lock_irq(&desc->lock); | 47 | raw_spin_lock_irq(&desc->lock); |
49 | if (!desc->action && !(desc->status & IRQ_NOPROBE)) { | 48 | if (!desc->action && irq_settings_can_probe(desc)) { |
50 | /* | ||
51 | * An old-style architecture might still have | ||
52 | * the handle_bad_irq handler there: | ||
53 | */ | ||
54 | compat_irq_chip_set_default_handler(desc); | ||
55 | |||
56 | /* | 49 | /* |
57 | * Some chips need to know about probing in | 50 | * Some chips need to know about probing in |
58 | * progress: | 51 | * progress: |
59 | */ | 52 | */ |
60 | if (desc->chip->set_type) | 53 | if (desc->irq_data.chip->irq_set_type) |
61 | desc->chip->set_type(i, IRQ_TYPE_PROBE); | 54 | desc->irq_data.chip->irq_set_type(&desc->irq_data, |
62 | desc->chip->startup(i); | 55 | IRQ_TYPE_PROBE); |
56 | irq_startup(desc); | ||
63 | } | 57 | } |
64 | raw_spin_unlock_irq(&desc->lock); | 58 | raw_spin_unlock_irq(&desc->lock); |
65 | } | 59 | } |
@@ -74,10 +68,10 @@ unsigned long probe_irq_on(void) | |||
74 | */ | 68 | */ |
75 | for_each_irq_desc_reverse(i, desc) { | 69 | for_each_irq_desc_reverse(i, desc) { |
76 | raw_spin_lock_irq(&desc->lock); | 70 | raw_spin_lock_irq(&desc->lock); |
77 | if (!desc->action && !(desc->status & IRQ_NOPROBE)) { | 71 | if (!desc->action && irq_settings_can_probe(desc)) { |
78 | desc->status |= IRQ_AUTODETECT | IRQ_WAITING; | 72 | desc->istate |= IRQS_AUTODETECT | IRQS_WAITING; |
79 | if (desc->chip->startup(i)) | 73 | if (irq_startup(desc)) |
80 | desc->status |= IRQ_PENDING; | 74 | desc->istate |= IRQS_PENDING; |
81 | } | 75 | } |
82 | raw_spin_unlock_irq(&desc->lock); | 76 | raw_spin_unlock_irq(&desc->lock); |
83 | } | 77 | } |
@@ -92,13 +86,12 @@ unsigned long probe_irq_on(void) | |||
92 | */ | 86 | */ |
93 | for_each_irq_desc(i, desc) { | 87 | for_each_irq_desc(i, desc) { |
94 | raw_spin_lock_irq(&desc->lock); | 88 | raw_spin_lock_irq(&desc->lock); |
95 | status = desc->status; | ||
96 | 89 | ||
97 | if (status & IRQ_AUTODETECT) { | 90 | if (desc->istate & IRQS_AUTODETECT) { |
98 | /* It triggered already - consider it spurious. */ | 91 | /* It triggered already - consider it spurious. */ |
99 | if (!(status & IRQ_WAITING)) { | 92 | if (!(desc->istate & IRQS_WAITING)) { |
100 | desc->status = status & ~IRQ_AUTODETECT; | 93 | desc->istate &= ~IRQS_AUTODETECT; |
101 | desc->chip->shutdown(i); | 94 | irq_shutdown(desc); |
102 | } else | 95 | } else |
103 | if (i < 32) | 96 | if (i < 32) |
104 | mask |= 1 << i; | 97 | mask |= 1 << i; |
@@ -124,20 +117,18 @@ EXPORT_SYMBOL(probe_irq_on); | |||
124 | */ | 117 | */ |
125 | unsigned int probe_irq_mask(unsigned long val) | 118 | unsigned int probe_irq_mask(unsigned long val) |
126 | { | 119 | { |
127 | unsigned int status, mask = 0; | 120 | unsigned int mask = 0; |
128 | struct irq_desc *desc; | 121 | struct irq_desc *desc; |
129 | int i; | 122 | int i; |
130 | 123 | ||
131 | for_each_irq_desc(i, desc) { | 124 | for_each_irq_desc(i, desc) { |
132 | raw_spin_lock_irq(&desc->lock); | 125 | raw_spin_lock_irq(&desc->lock); |
133 | status = desc->status; | 126 | if (desc->istate & IRQS_AUTODETECT) { |
134 | 127 | if (i < 16 && !(desc->istate & IRQS_WAITING)) | |
135 | if (status & IRQ_AUTODETECT) { | ||
136 | if (i < 16 && !(status & IRQ_WAITING)) | ||
137 | mask |= 1 << i; | 128 | mask |= 1 << i; |
138 | 129 | ||
139 | desc->status = status & ~IRQ_AUTODETECT; | 130 | desc->istate &= ~IRQS_AUTODETECT; |
140 | desc->chip->shutdown(i); | 131 | irq_shutdown(desc); |
141 | } | 132 | } |
142 | raw_spin_unlock_irq(&desc->lock); | 133 | raw_spin_unlock_irq(&desc->lock); |
143 | } | 134 | } |
@@ -168,20 +159,18 @@ int probe_irq_off(unsigned long val) | |||
168 | { | 159 | { |
169 | int i, irq_found = 0, nr_of_irqs = 0; | 160 | int i, irq_found = 0, nr_of_irqs = 0; |
170 | struct irq_desc *desc; | 161 | struct irq_desc *desc; |
171 | unsigned int status; | ||
172 | 162 | ||
173 | for_each_irq_desc(i, desc) { | 163 | for_each_irq_desc(i, desc) { |
174 | raw_spin_lock_irq(&desc->lock); | 164 | raw_spin_lock_irq(&desc->lock); |
175 | status = desc->status; | ||
176 | 165 | ||
177 | if (status & IRQ_AUTODETECT) { | 166 | if (desc->istate & IRQS_AUTODETECT) { |
178 | if (!(status & IRQ_WAITING)) { | 167 | if (!(desc->istate & IRQS_WAITING)) { |
179 | if (!nr_of_irqs) | 168 | if (!nr_of_irqs) |
180 | irq_found = i; | 169 | irq_found = i; |
181 | nr_of_irqs++; | 170 | nr_of_irqs++; |
182 | } | 171 | } |
183 | desc->status = status & ~IRQ_AUTODETECT; | 172 | desc->istate &= ~IRQS_AUTODETECT; |
184 | desc->chip->shutdown(i); | 173 | irq_shutdown(desc); |
185 | } | 174 | } |
186 | raw_spin_unlock_irq(&desc->lock); | 175 | raw_spin_unlock_irq(&desc->lock); |
187 | } | 176 | } |