aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/irq')
-rw-r--r--kernel/irq/Makefile2
-rw-r--r--kernel/irq/autoprobe.c56
-rw-r--r--kernel/irq/chip.c533
-rw-r--r--kernel/irq/handle.c165
-rw-r--r--kernel/irq/internals.h46
-rw-r--r--kernel/irq/manage.c209
-rw-r--r--kernel/irq/migration.c20
-rw-r--r--kernel/irq/proc.c30
-rw-r--r--kernel/irq/resend.c77
-rw-r--r--kernel/irq/spurious.c37
10 files changed, 1003 insertions, 172 deletions
diff --git a/kernel/irq/Makefile b/kernel/irq/Makefile
index 9f77f50d8143..1dab0ac3f797 100644
--- a/kernel/irq/Makefile
+++ b/kernel/irq/Makefile
@@ -1,5 +1,5 @@
1 1
2obj-y := handle.o manage.o spurious.o 2obj-y := handle.o manage.o spurious.o resend.o chip.o
3obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o 3obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o
4obj-$(CONFIG_PROC_FS) += proc.o 4obj-$(CONFIG_PROC_FS) += proc.o
5obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o 5obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c
index 3467097ca61a..533068cfb607 100644
--- a/kernel/irq/autoprobe.c
+++ b/kernel/irq/autoprobe.c
@@ -11,12 +11,14 @@
11#include <linux/interrupt.h> 11#include <linux/interrupt.h>
12#include <linux/delay.h> 12#include <linux/delay.h>
13 13
14#include "internals.h"
15
14/* 16/*
15 * Autodetection depends on the fact that any interrupt that 17 * Autodetection depends on the fact that any interrupt that
16 * comes in on to an unassigned handler will get stuck with 18 * comes in on to an unassigned handler will get stuck with
17 * "IRQ_WAITING" cleared and the interrupt disabled. 19 * "IRQ_WAITING" cleared and the interrupt disabled.
18 */ 20 */
19static DECLARE_MUTEX(probe_sem); 21static DEFINE_MUTEX(probing_active);
20 22
21/** 23/**
22 * probe_irq_on - begin an interrupt autodetect 24 * probe_irq_on - begin an interrupt autodetect
@@ -27,11 +29,11 @@ static DECLARE_MUTEX(probe_sem);
27 */ 29 */
28unsigned long probe_irq_on(void) 30unsigned long probe_irq_on(void)
29{ 31{
30 unsigned long val; 32 struct irq_desc *desc;
31 irq_desc_t *desc; 33 unsigned long mask;
32 unsigned int i; 34 unsigned int i;
33 35
34 down(&probe_sem); 36 mutex_lock(&probing_active);
35 /* 37 /*
36 * something may have generated an irq long ago and we want to 38 * something may have generated an irq long ago and we want to
37 * flush such a longstanding irq before considering it as spurious. 39 * flush such a longstanding irq before considering it as spurious.
@@ -40,8 +42,21 @@ unsigned long probe_irq_on(void)
40 desc = irq_desc + i; 42 desc = irq_desc + i;
41 43
42 spin_lock_irq(&desc->lock); 44 spin_lock_irq(&desc->lock);
43 if (!irq_desc[i].action) 45 if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
44 irq_desc[i].handler->startup(i); 46 /*
47 * An old-style architecture might still have
48 * the handle_bad_irq handler there:
49 */
50 compat_irq_chip_set_default_handler(desc);
51
52 /*
53 * Some chips need to know about probing in
54 * progress:
55 */
56 if (desc->chip->set_type)
57 desc->chip->set_type(i, IRQ_TYPE_PROBE);
58 desc->chip->startup(i);
59 }
45 spin_unlock_irq(&desc->lock); 60 spin_unlock_irq(&desc->lock);
46 } 61 }
47 62
@@ -57,9 +72,9 @@ unsigned long probe_irq_on(void)
57 desc = irq_desc + i; 72 desc = irq_desc + i;
58 73
59 spin_lock_irq(&desc->lock); 74 spin_lock_irq(&desc->lock);
60 if (!desc->action) { 75 if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
61 desc->status |= IRQ_AUTODETECT | IRQ_WAITING; 76 desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
62 if (desc->handler->startup(i)) 77 if (desc->chip->startup(i))
63 desc->status |= IRQ_PENDING; 78 desc->status |= IRQ_PENDING;
64 } 79 }
65 spin_unlock_irq(&desc->lock); 80 spin_unlock_irq(&desc->lock);
@@ -73,11 +88,11 @@ unsigned long probe_irq_on(void)
73 /* 88 /*
74 * Now filter out any obviously spurious interrupts 89 * Now filter out any obviously spurious interrupts
75 */ 90 */
76 val = 0; 91 mask = 0;
77 for (i = 0; i < NR_IRQS; i++) { 92 for (i = 0; i < NR_IRQS; i++) {
78 irq_desc_t *desc = irq_desc + i;
79 unsigned int status; 93 unsigned int status;
80 94
95 desc = irq_desc + i;
81 spin_lock_irq(&desc->lock); 96 spin_lock_irq(&desc->lock);
82 status = desc->status; 97 status = desc->status;
83 98
@@ -85,17 +100,16 @@ unsigned long probe_irq_on(void)
85 /* It triggered already - consider it spurious. */ 100 /* It triggered already - consider it spurious. */
86 if (!(status & IRQ_WAITING)) { 101 if (!(status & IRQ_WAITING)) {
87 desc->status = status & ~IRQ_AUTODETECT; 102 desc->status = status & ~IRQ_AUTODETECT;
88 desc->handler->shutdown(i); 103 desc->chip->shutdown(i);
89 } else 104 } else
90 if (i < 32) 105 if (i < 32)
91 val |= 1 << i; 106 mask |= 1 << i;
92 } 107 }
93 spin_unlock_irq(&desc->lock); 108 spin_unlock_irq(&desc->lock);
94 } 109 }
95 110
96 return val; 111 return mask;
97} 112}
98
99EXPORT_SYMBOL(probe_irq_on); 113EXPORT_SYMBOL(probe_irq_on);
100 114
101/** 115/**
@@ -117,7 +131,7 @@ unsigned int probe_irq_mask(unsigned long val)
117 131
118 mask = 0; 132 mask = 0;
119 for (i = 0; i < NR_IRQS; i++) { 133 for (i = 0; i < NR_IRQS; i++) {
120 irq_desc_t *desc = irq_desc + i; 134 struct irq_desc *desc = irq_desc + i;
121 unsigned int status; 135 unsigned int status;
122 136
123 spin_lock_irq(&desc->lock); 137 spin_lock_irq(&desc->lock);
@@ -128,11 +142,11 @@ unsigned int probe_irq_mask(unsigned long val)
128 mask |= 1 << i; 142 mask |= 1 << i;
129 143
130 desc->status = status & ~IRQ_AUTODETECT; 144 desc->status = status & ~IRQ_AUTODETECT;
131 desc->handler->shutdown(i); 145 desc->chip->shutdown(i);
132 } 146 }
133 spin_unlock_irq(&desc->lock); 147 spin_unlock_irq(&desc->lock);
134 } 148 }
135 up(&probe_sem); 149 mutex_unlock(&probing_active);
136 150
137 return mask & val; 151 return mask & val;
138} 152}
@@ -160,7 +174,7 @@ int probe_irq_off(unsigned long val)
160 int i, irq_found = 0, nr_irqs = 0; 174 int i, irq_found = 0, nr_irqs = 0;
161 175
162 for (i = 0; i < NR_IRQS; i++) { 176 for (i = 0; i < NR_IRQS; i++) {
163 irq_desc_t *desc = irq_desc + i; 177 struct irq_desc *desc = irq_desc + i;
164 unsigned int status; 178 unsigned int status;
165 179
166 spin_lock_irq(&desc->lock); 180 spin_lock_irq(&desc->lock);
@@ -173,16 +187,16 @@ int probe_irq_off(unsigned long val)
173 nr_irqs++; 187 nr_irqs++;
174 } 188 }
175 desc->status = status & ~IRQ_AUTODETECT; 189 desc->status = status & ~IRQ_AUTODETECT;
176 desc->handler->shutdown(i); 190 desc->chip->shutdown(i);
177 } 191 }
178 spin_unlock_irq(&desc->lock); 192 spin_unlock_irq(&desc->lock);
179 } 193 }
180 up(&probe_sem); 194 mutex_unlock(&probing_active);
181 195
182 if (nr_irqs > 1) 196 if (nr_irqs > 1)
183 irq_found = -irq_found; 197 irq_found = -irq_found;
198
184 return irq_found; 199 return irq_found;
185} 200}
186
187EXPORT_SYMBOL(probe_irq_off); 201EXPORT_SYMBOL(probe_irq_off);
188 202
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
new file mode 100644
index 000000000000..736cb0bd498f
--- /dev/null
+++ b/kernel/irq/chip.c
@@ -0,0 +1,533 @@
1/*
2 * linux/kernel/irq/chip.c
3 *
4 * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar
5 * Copyright (C) 2005-2006, Thomas Gleixner, Russell King
6 *
7 * This file contains the core interrupt handling code, for irq-chip
8 * based architectures.
9 *
10 * Detailed information is available in Documentation/DocBook/genericirq
11 */
12
13#include <linux/irq.h>
14#include <linux/module.h>
15#include <linux/interrupt.h>
16#include <linux/kernel_stat.h>
17
18#include "internals.h"
19
20/**
21 * set_irq_chip - set the irq chip for an irq
22 * @irq: irq number
23 * @chip: pointer to irq chip description structure
24 */
25int set_irq_chip(unsigned int irq, struct irq_chip *chip)
26{
27 struct irq_desc *desc;
28 unsigned long flags;
29
30 if (irq >= NR_IRQS) {
31 printk(KERN_ERR "Trying to install chip for IRQ%d\n", irq);
32 WARN_ON(1);
33 return -EINVAL;
34 }
35
36 if (!chip)
37 chip = &no_irq_chip;
38
39 desc = irq_desc + irq;
40 spin_lock_irqsave(&desc->lock, flags);
41 irq_chip_set_defaults(chip);
42 desc->chip = chip;
43 spin_unlock_irqrestore(&desc->lock, flags);
44
45 return 0;
46}
47EXPORT_SYMBOL(set_irq_chip);
48
49/**
50 * set_irq_type - set the irq type for an irq
51 * @irq: irq number
52 * @type: interrupt type - see include/linux/interrupt.h
53 */
54int set_irq_type(unsigned int irq, unsigned int type)
55{
56 struct irq_desc *desc;
57 unsigned long flags;
58 int ret = -ENXIO;
59
60 if (irq >= NR_IRQS) {
61 printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq);
62 return -ENODEV;
63 }
64
65 desc = irq_desc + irq;
66 if (desc->chip->set_type) {
67 spin_lock_irqsave(&desc->lock, flags);
68 ret = desc->chip->set_type(irq, type);
69 spin_unlock_irqrestore(&desc->lock, flags);
70 }
71 return ret;
72}
73EXPORT_SYMBOL(set_irq_type);
74
75/**
76 * set_irq_data - set irq type data for an irq
77 * @irq: Interrupt number
78 * @data: Pointer to interrupt specific data
79 *
80 * Set the hardware irq controller data for an irq
81 */
82int set_irq_data(unsigned int irq, void *data)
83{
84 struct irq_desc *desc;
85 unsigned long flags;
86
87 if (irq >= NR_IRQS) {
88 printk(KERN_ERR
89 "Trying to install controller data for IRQ%d\n", irq);
90 return -EINVAL;
91 }
92
93 desc = irq_desc + irq;
94 spin_lock_irqsave(&desc->lock, flags);
95 desc->handler_data = data;
96 spin_unlock_irqrestore(&desc->lock, flags);
97 return 0;
98}
99EXPORT_SYMBOL(set_irq_data);
100
101/**
102 * set_irq_chip_data - set irq chip data for an irq
103 * @irq: Interrupt number
104 * @data: Pointer to chip specific data
105 *
106 * Set the hardware irq chip data for an irq
107 */
108int set_irq_chip_data(unsigned int irq, void *data)
109{
110 struct irq_desc *desc = irq_desc + irq;
111 unsigned long flags;
112
113 if (irq >= NR_IRQS || !desc->chip) {
114 printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", irq);
115 return -EINVAL;
116 }
117
118 spin_lock_irqsave(&desc->lock, flags);
119 desc->chip_data = data;
120 spin_unlock_irqrestore(&desc->lock, flags);
121
122 return 0;
123}
124EXPORT_SYMBOL(set_irq_chip_data);
125
126/*
127 * default enable function
128 */
129static void default_enable(unsigned int irq)
130{
131 struct irq_desc *desc = irq_desc + irq;
132
133 desc->chip->unmask(irq);
134 desc->status &= ~IRQ_MASKED;
135}
136
137/*
138 * default disable function
139 */
140static void default_disable(unsigned int irq)
141{
142 struct irq_desc *desc = irq_desc + irq;
143
144 if (!(desc->status & IRQ_DELAYED_DISABLE))
145 desc->chip->mask(irq);
146}
147
148/*
149 * default startup function
150 */
151static unsigned int default_startup(unsigned int irq)
152{
153 irq_desc[irq].chip->enable(irq);
154
155 return 0;
156}
157
158/*
159 * Fixup enable/disable function pointers
160 */
161void irq_chip_set_defaults(struct irq_chip *chip)
162{
163 if (!chip->enable)
164 chip->enable = default_enable;
165 if (!chip->disable)
166 chip->disable = default_disable;
167 if (!chip->startup)
168 chip->startup = default_startup;
169 if (!chip->shutdown)
170 chip->shutdown = chip->disable;
171 if (!chip->name)
172 chip->name = chip->typename;
173}
174
175static inline void mask_ack_irq(struct irq_desc *desc, int irq)
176{
177 if (desc->chip->mask_ack)
178 desc->chip->mask_ack(irq);
179 else {
180 desc->chip->mask(irq);
181 desc->chip->ack(irq);
182 }
183}
184
185/**
186 * handle_simple_irq - Simple and software-decoded IRQs.
187 * @irq: the interrupt number
188 * @desc: the interrupt description structure for this irq
189 * @regs: pointer to a register structure
190 *
191 * Simple interrupts are either sent from a demultiplexing interrupt
192 * handler or come from hardware, where no interrupt hardware control
193 * is necessary.
194 *
195 * Note: The caller is expected to handle the ack, clear, mask and
196 * unmask issues if necessary.
197 */
198void fastcall
199handle_simple_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
200{
201 struct irqaction *action;
202 irqreturn_t action_ret;
203 const unsigned int cpu = smp_processor_id();
204
205 spin_lock(&desc->lock);
206
207 if (unlikely(desc->status & IRQ_INPROGRESS))
208 goto out_unlock;
209 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
210 kstat_cpu(cpu).irqs[irq]++;
211
212 action = desc->action;
213 if (unlikely(!action || (desc->status & IRQ_DISABLED)))
214 goto out_unlock;
215
216 desc->status |= IRQ_INPROGRESS;
217 spin_unlock(&desc->lock);
218
219 action_ret = handle_IRQ_event(irq, regs, action);
220 if (!noirqdebug)
221 note_interrupt(irq, desc, action_ret, regs);
222
223 spin_lock(&desc->lock);
224 desc->status &= ~IRQ_INPROGRESS;
225out_unlock:
226 spin_unlock(&desc->lock);
227}
228
229/**
230 * handle_level_irq - Level type irq handler
231 * @irq: the interrupt number
232 * @desc: the interrupt description structure for this irq
233 * @regs: pointer to a register structure
234 *
235 * Level type interrupts are active as long as the hardware line has
236 * the active level. This may require to mask the interrupt and unmask
237 * it after the associated handler has acknowledged the device, so the
238 * interrupt line is back to inactive.
239 */
240void fastcall
241handle_level_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
242{
243 unsigned int cpu = smp_processor_id();
244 struct irqaction *action;
245 irqreturn_t action_ret;
246
247 spin_lock(&desc->lock);
248 mask_ack_irq(desc, irq);
249
250 if (unlikely(desc->status & IRQ_INPROGRESS))
251 goto out_unlock;
252 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
253 kstat_cpu(cpu).irqs[irq]++;
254
255 /*
256 * If its disabled or no action available
257 * keep it masked and get out of here
258 */
259 action = desc->action;
260 if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
261 desc->status |= IRQ_PENDING;
262 goto out_unlock;
263 }
264
265 desc->status |= IRQ_INPROGRESS;
266 desc->status &= ~IRQ_PENDING;
267 spin_unlock(&desc->lock);
268
269 action_ret = handle_IRQ_event(irq, regs, action);
270 if (!noirqdebug)
271 note_interrupt(irq, desc, action_ret, regs);
272
273 spin_lock(&desc->lock);
274 desc->status &= ~IRQ_INPROGRESS;
275 if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)
276 desc->chip->unmask(irq);
277out_unlock:
278 spin_unlock(&desc->lock);
279}
280
281/**
282 * handle_fasteoi_irq - irq handler for transparent controllers
283 * @irq: the interrupt number
284 * @desc: the interrupt description structure for this irq
285 * @regs: pointer to a register structure
286 *
287 * Only a single callback will be issued to the chip: an ->eoi()
288 * call when the interrupt has been serviced. This enables support
289 * for modern forms of interrupt handlers, which handle the flow
290 * details in hardware, transparently.
291 */
292void fastcall
293handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc,
294 struct pt_regs *regs)
295{
296 unsigned int cpu = smp_processor_id();
297 struct irqaction *action;
298 irqreturn_t action_ret;
299
300 spin_lock(&desc->lock);
301
302 if (unlikely(desc->status & IRQ_INPROGRESS))
303 goto out;
304
305 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
306 kstat_cpu(cpu).irqs[irq]++;
307
308 /*
309 * If its disabled or no action available
310 * keep it masked and get out of here
311 */
312 action = desc->action;
313 if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
314 desc->status |= IRQ_PENDING;
315 goto out;
316 }
317
318 desc->status |= IRQ_INPROGRESS;
319 desc->status &= ~IRQ_PENDING;
320 spin_unlock(&desc->lock);
321
322 action_ret = handle_IRQ_event(irq, regs, action);
323 if (!noirqdebug)
324 note_interrupt(irq, desc, action_ret, regs);
325
326 spin_lock(&desc->lock);
327 desc->status &= ~IRQ_INPROGRESS;
328out:
329 desc->chip->eoi(irq);
330
331 spin_unlock(&desc->lock);
332}
333
334/**
335 * handle_edge_irq - edge type IRQ handler
336 * @irq: the interrupt number
337 * @desc: the interrupt description structure for this irq
338 * @regs: pointer to a register structure
339 *
340 * Interrupt occures on the falling and/or rising edge of a hardware
341 * signal. The occurence is latched into the irq controller hardware
342 * and must be acked in order to be reenabled. After the ack another
343 * interrupt can happen on the same source even before the first one
344 * is handled by the assosiacted event handler. If this happens it
345 * might be necessary to disable (mask) the interrupt depending on the
346 * controller hardware. This requires to reenable the interrupt inside
347 * of the loop which handles the interrupts which have arrived while
348 * the handler was running. If all pending interrupts are handled, the
349 * loop is left.
350 */
351void fastcall
352handle_edge_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
353{
354 const unsigned int cpu = smp_processor_id();
355
356 spin_lock(&desc->lock);
357
358 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
359
360 /*
361 * If we're currently running this IRQ, or its disabled,
362 * we shouldn't process the IRQ. Mark it pending, handle
363 * the necessary masking and go out
364 */
365 if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) ||
366 !desc->action)) {
367 desc->status |= (IRQ_PENDING | IRQ_MASKED);
368 mask_ack_irq(desc, irq);
369 goto out_unlock;
370 }
371
372 kstat_cpu(cpu).irqs[irq]++;
373
374 /* Start handling the irq */
375 desc->chip->ack(irq);
376
377 /* Mark the IRQ currently in progress.*/
378 desc->status |= IRQ_INPROGRESS;
379
380 do {
381 struct irqaction *action = desc->action;
382 irqreturn_t action_ret;
383
384 if (unlikely(!action)) {
385 desc->chip->mask(irq);
386 goto out_unlock;
387 }
388
389 /*
390 * When another irq arrived while we were handling
391 * one, we could have masked the irq.
392 * Renable it, if it was not disabled in meantime.
393 */
394 if (unlikely((desc->status &
395 (IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) ==
396 (IRQ_PENDING | IRQ_MASKED))) {
397 desc->chip->unmask(irq);
398 desc->status &= ~IRQ_MASKED;
399 }
400
401 desc->status &= ~IRQ_PENDING;
402 spin_unlock(&desc->lock);
403 action_ret = handle_IRQ_event(irq, regs, action);
404 if (!noirqdebug)
405 note_interrupt(irq, desc, action_ret, regs);
406 spin_lock(&desc->lock);
407
408 } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);
409
410 desc->status &= ~IRQ_INPROGRESS;
411out_unlock:
412 spin_unlock(&desc->lock);
413}
414
415#ifdef CONFIG_SMP
416/**
417 * handle_percpu_IRQ - Per CPU local irq handler
418 * @irq: the interrupt number
419 * @desc: the interrupt description structure for this irq
420 * @regs: pointer to a register structure
421 *
422 * Per CPU interrupts on SMP machines without locking requirements
423 */
424void fastcall
425handle_percpu_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
426{
427 irqreturn_t action_ret;
428
429 kstat_this_cpu.irqs[irq]++;
430
431 if (desc->chip->ack)
432 desc->chip->ack(irq);
433
434 action_ret = handle_IRQ_event(irq, regs, desc->action);
435 if (!noirqdebug)
436 note_interrupt(irq, desc, action_ret, regs);
437
438 if (desc->chip->eoi)
439 desc->chip->eoi(irq);
440}
441
442#endif /* CONFIG_SMP */
443
444void
445__set_irq_handler(unsigned int irq,
446 void fastcall (*handle)(unsigned int, irq_desc_t *,
447 struct pt_regs *),
448 int is_chained)
449{
450 struct irq_desc *desc;
451 unsigned long flags;
452
453 if (irq >= NR_IRQS) {
454 printk(KERN_ERR
455 "Trying to install type control for IRQ%d\n", irq);
456 return;
457 }
458
459 desc = irq_desc + irq;
460
461 if (!handle)
462 handle = handle_bad_irq;
463
464 if (desc->chip == &no_irq_chip) {
465 printk(KERN_WARNING "Trying to install %sinterrupt handler "
466 "for IRQ%d\n", is_chained ? "chained " : " ", irq);
467 /*
468 * Some ARM implementations install a handler for really dumb
469 * interrupt hardware without setting an irq_chip. This worked
470 * with the ARM no_irq_chip but the check in setup_irq would
471 * prevent us to setup the interrupt at all. Switch it to
472 * dummy_irq_chip for easy transition.
473 */
474 desc->chip = &dummy_irq_chip;
475 }
476
477 spin_lock_irqsave(&desc->lock, flags);
478
479 /* Uninstall? */
480 if (handle == handle_bad_irq) {
481 if (desc->chip != &no_irq_chip) {
482 desc->chip->mask(irq);
483 desc->chip->ack(irq);
484 }
485 desc->status |= IRQ_DISABLED;
486 desc->depth = 1;
487 }
488 desc->handle_irq = handle;
489
490 if (handle != handle_bad_irq && is_chained) {
491 desc->status &= ~IRQ_DISABLED;
492 desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE;
493 desc->depth = 0;
494 desc->chip->unmask(irq);
495 }
496 spin_unlock_irqrestore(&desc->lock, flags);
497}
498
499void
500set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip,
501 void fastcall (*handle)(unsigned int,
502 struct irq_desc *,
503 struct pt_regs *))
504{
505 set_irq_chip(irq, chip);
506 __set_irq_handler(irq, handle, 0);
507}
508
509/*
510 * Get a descriptive string for the highlevel handler, for
511 * /proc/interrupts output:
512 */
513const char *
514handle_irq_name(void fastcall (*handle)(unsigned int, struct irq_desc *,
515 struct pt_regs *))
516{
517 if (handle == handle_level_irq)
518 return "level ";
519 if (handle == handle_fasteoi_irq)
520 return "fasteoi";
521 if (handle == handle_edge_irq)
522 return "edge ";
523 if (handle == handle_simple_irq)
524 return "simple ";
525#ifdef CONFIG_SMP
526 if (handle == handle_percpu_irq)
527 return "percpu ";
528#endif
529 if (handle == handle_bad_irq)
530 return "bad ";
531
532 return NULL;
533}
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 0f6530117105..4c6cdbaed661 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -1,9 +1,13 @@
1/* 1/*
2 * linux/kernel/irq/handle.c 2 * linux/kernel/irq/handle.c
3 * 3 *
4 * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar 4 * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar
5 * Copyright (C) 2005-2006, Thomas Gleixner, Russell King
5 * 6 *
6 * This file contains the core interrupt handling code. 7 * This file contains the core interrupt handling code.
8 *
9 * Detailed information is available in Documentation/DocBook/genericirq
10 *
7 */ 11 */
8 12
9#include <linux/irq.h> 13#include <linux/irq.h>
@@ -14,11 +18,27 @@
14 18
15#include "internals.h" 19#include "internals.h"
16 20
21/**
22 * handle_bad_irq - handle spurious and unhandled irqs
23 * @irq: the interrupt number
24 * @desc: description of the interrupt
25 * @regs: pointer to a register structure
26 *
27 * Handles spurious and unhandled IRQ's. It also prints a debugmessage.
28 */
29void fastcall
30handle_bad_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
31{
32 print_irq_desc(irq, desc);
33 kstat_this_cpu.irqs[irq]++;
34 ack_bad_irq(irq);
35}
36
17/* 37/*
18 * Linux has a controller-independent interrupt architecture. 38 * Linux has a controller-independent interrupt architecture.
19 * Every controller has a 'controller-template', that is used 39 * Every controller has a 'controller-template', that is used
20 * by the main code to do the right thing. Each driver-visible 40 * by the main code to do the right thing. Each driver-visible
21 * interrupt source is transparently wired to the apropriate 41 * interrupt source is transparently wired to the appropriate
22 * controller. Thus drivers need not be aware of the 42 * controller. Thus drivers need not be aware of the
23 * interrupt-controller. 43 * interrupt-controller.
24 * 44 *
@@ -28,41 +48,68 @@
28 * 48 *
29 * Controller mappings for all interrupt sources: 49 * Controller mappings for all interrupt sources:
30 */ 50 */
31irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = { 51struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned = {
32 [0 ... NR_IRQS-1] = { 52 [0 ... NR_IRQS-1] = {
33 .status = IRQ_DISABLED, 53 .status = IRQ_DISABLED,
34 .handler = &no_irq_type, 54 .chip = &no_irq_chip,
35 .lock = SPIN_LOCK_UNLOCKED 55 .handle_irq = handle_bad_irq,
56 .depth = 1,
57 .lock = SPIN_LOCK_UNLOCKED,
58#ifdef CONFIG_SMP
59 .affinity = CPU_MASK_ALL
60#endif
36 } 61 }
37}; 62};
38 63
39/* 64/*
40 * Generic 'no controller' code 65 * What should we do if we get a hw irq event on an illegal vector?
66 * Each architecture has to answer this themself.
41 */ 67 */
42static void end_none(unsigned int irq) { } 68static void ack_bad(unsigned int irq)
43static void enable_none(unsigned int irq) { }
44static void disable_none(unsigned int irq) { }
45static void shutdown_none(unsigned int irq) { }
46static unsigned int startup_none(unsigned int irq) { return 0; }
47
48static void ack_none(unsigned int irq)
49{ 69{
50 /* 70 print_irq_desc(irq, irq_desc + irq);
51 * 'what should we do if we get a hw irq event on an illegal vector'.
52 * each architecture has to answer this themself.
53 */
54 ack_bad_irq(irq); 71 ack_bad_irq(irq);
55} 72}
56 73
57struct hw_interrupt_type no_irq_type = { 74/*
58 .typename = "none", 75 * NOP functions
59 .startup = startup_none, 76 */
60 .shutdown = shutdown_none, 77static void noop(unsigned int irq)
61 .enable = enable_none, 78{
62 .disable = disable_none, 79}
63 .ack = ack_none, 80
64 .end = end_none, 81static unsigned int noop_ret(unsigned int irq)
65 .set_affinity = NULL 82{
83 return 0;
84}
85
86/*
87 * Generic no controller implementation
88 */
89struct irq_chip no_irq_chip = {
90 .name = "none",
91 .startup = noop_ret,
92 .shutdown = noop,
93 .enable = noop,
94 .disable = noop,
95 .ack = ack_bad,
96 .end = noop,
97};
98
99/*
100 * Generic dummy implementation which can be used for
101 * real dumb interrupt sources
102 */
103struct irq_chip dummy_irq_chip = {
104 .name = "dummy",
105 .startup = noop_ret,
106 .shutdown = noop,
107 .enable = noop,
108 .disable = noop,
109 .ack = noop,
110 .mask = noop,
111 .unmask = noop,
112 .end = noop,
66}; 113};
67 114
68/* 115/*
@@ -73,17 +120,24 @@ irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs)
73 return IRQ_NONE; 120 return IRQ_NONE;
74} 121}
75 122
76/* 123/**
77 * Have got an event to handle: 124 * handle_IRQ_event - irq action chain handler
125 * @irq: the interrupt number
126 * @regs: pointer to a register structure
127 * @action: the interrupt action chain for this irq
128 *
129 * Handles the action chain of an irq event
78 */ 130 */
79fastcall irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs, 131irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
80 struct irqaction *action) 132 struct irqaction *action)
81{ 133{
82 irqreturn_t ret, retval = IRQ_NONE; 134 irqreturn_t ret, retval = IRQ_NONE;
83 unsigned int status = 0; 135 unsigned int status = 0;
84 136
85 if (!(action->flags & SA_INTERRUPT)) 137 handle_dynamic_tick(action);
86 local_irq_enable(); 138
139 if (!(action->flags & IRQF_DISABLED))
140 local_irq_enable_in_hardirq();
87 141
88 do { 142 do {
89 ret = action->handler(irq, action->dev_id, regs); 143 ret = action->handler(irq, action->dev_id, regs);
@@ -93,22 +147,30 @@ fastcall irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
93 action = action->next; 147 action = action->next;
94 } while (action); 148 } while (action);
95 149
96 if (status & SA_SAMPLE_RANDOM) 150 if (status & IRQF_SAMPLE_RANDOM)
97 add_interrupt_randomness(irq); 151 add_interrupt_randomness(irq);
98 local_irq_disable(); 152 local_irq_disable();
99 153
100 return retval; 154 return retval;
101} 155}
102 156
103/* 157#ifndef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ
104 * do_IRQ handles all normal device IRQ's (the special 158/**
159 * __do_IRQ - original all in one highlevel IRQ handler
160 * @irq: the interrupt number
161 * @regs: pointer to a register structure
162 *
163 * __do_IRQ handles all normal device IRQ's (the special
105 * SMP cross-CPU interrupts have their own specific 164 * SMP cross-CPU interrupts have their own specific
106 * handlers). 165 * handlers).
166 *
167 * This is the original x86 implementation which is used for every
168 * interrupt type.
107 */ 169 */
108fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs) 170fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs)
109{ 171{
110 irq_desc_t *desc = irq_desc + irq; 172 struct irq_desc *desc = irq_desc + irq;
111 struct irqaction * action; 173 struct irqaction *action;
112 unsigned int status; 174 unsigned int status;
113 175
114 kstat_this_cpu.irqs[irq]++; 176 kstat_this_cpu.irqs[irq]++;
@@ -118,16 +180,16 @@ fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs)
118 /* 180 /*
119 * No locking required for CPU-local interrupts: 181 * No locking required for CPU-local interrupts:
120 */ 182 */
121 if (desc->handler->ack) 183 if (desc->chip->ack)
122 desc->handler->ack(irq); 184 desc->chip->ack(irq);
123 action_ret = handle_IRQ_event(irq, regs, desc->action); 185 action_ret = handle_IRQ_event(irq, regs, desc->action);
124 desc->handler->end(irq); 186 desc->chip->end(irq);
125 return 1; 187 return 1;
126 } 188 }
127 189
128 spin_lock(&desc->lock); 190 spin_lock(&desc->lock);
129 if (desc->handler->ack) 191 if (desc->chip->ack)
130 desc->handler->ack(irq); 192 desc->chip->ack(irq);
131 /* 193 /*
132 * REPLAY is when Linux resends an IRQ that was dropped earlier 194 * REPLAY is when Linux resends an IRQ that was dropped earlier
133 * WAITING is used by probe to mark irqs that are being tested 195 * WAITING is used by probe to mark irqs that are being tested
@@ -187,9 +249,26 @@ out:
187 * The ->end() handler has to deal with interrupts which got 249 * The ->end() handler has to deal with interrupts which got
188 * disabled while the handler was running. 250 * disabled while the handler was running.
189 */ 251 */
190 desc->handler->end(irq); 252 desc->chip->end(irq);
191 spin_unlock(&desc->lock); 253 spin_unlock(&desc->lock);
192 254
193 return 1; 255 return 1;
194} 256}
257#endif
258
259#ifdef CONFIG_TRACE_IRQFLAGS
260
261/*
262 * lockdep: we want to handle all irq_desc locks as a single lock-class:
263 */
264static struct lock_class_key irq_desc_lock_class;
265
266void early_init_irq_lock_class(void)
267{
268 int i;
269
270 for (i = 0; i < NR_IRQS; i++)
271 lockdep_set_class(&irq_desc[i].lock, &irq_desc_lock_class);
272}
195 273
274#endif
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index 46feba630266..08a849a22447 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -4,6 +4,12 @@
4 4
5extern int noirqdebug; 5extern int noirqdebug;
6 6
7/* Set default functions for irq_chip structures: */
8extern void irq_chip_set_defaults(struct irq_chip *chip);
9
10/* Set default handler: */
11extern void compat_irq_chip_set_default_handler(struct irq_desc *desc);
12
7#ifdef CONFIG_PROC_FS 13#ifdef CONFIG_PROC_FS
8extern void register_irq_proc(unsigned int irq); 14extern void register_irq_proc(unsigned int irq);
9extern void register_handler_proc(unsigned int irq, struct irqaction *action); 15extern void register_handler_proc(unsigned int irq, struct irqaction *action);
@@ -16,3 +22,43 @@ static inline void unregister_handler_proc(unsigned int irq,
16 struct irqaction *action) { } 22 struct irqaction *action) { }
17#endif 23#endif
18 24
25/*
26 * Debugging printout:
27 */
28
29#include <linux/kallsyms.h>
30
31#define P(f) if (desc->status & f) printk("%14s set\n", #f)
32
33static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc)
34{
35 printk("irq %d, desc: %p, depth: %d, count: %d, unhandled: %d\n",
36 irq, desc, desc->depth, desc->irq_count, desc->irqs_unhandled);
37 printk("->handle_irq(): %p, ", desc->handle_irq);
38 print_symbol("%s\n", (unsigned long)desc->handle_irq);
39 printk("->chip(): %p, ", desc->chip);
40 print_symbol("%s\n", (unsigned long)desc->chip);
41 printk("->action(): %p\n", desc->action);
42 if (desc->action) {
43 printk("->action->handler(): %p, ", desc->action->handler);
44 print_symbol("%s\n", (unsigned long)desc->action->handler);
45 }
46
47 P(IRQ_INPROGRESS);
48 P(IRQ_DISABLED);
49 P(IRQ_PENDING);
50 P(IRQ_REPLAY);
51 P(IRQ_AUTODETECT);
52 P(IRQ_WAITING);
53 P(IRQ_LEVEL);
54 P(IRQ_MASKED);
55#ifdef CONFIG_IRQ_PER_CPU
56 P(IRQ_PER_CPU);
57#endif
58 P(IRQ_NOPROBE);
59 P(IRQ_NOREQUEST);
60 P(IRQ_NOAUTOEN);
61}
62
63#undef P
64
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 1279e3499534..92be519eff26 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1,12 +1,12 @@
1/* 1/*
2 * linux/kernel/irq/manage.c 2 * linux/kernel/irq/manage.c
3 * 3 *
4 * Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar 4 * Copyright (C) 1992, 1998-2006 Linus Torvalds, Ingo Molnar
5 * Copyright (C) 2005-2006 Thomas Gleixner
5 * 6 *
6 * This file contains driver APIs to the irq subsystem. 7 * This file contains driver APIs to the irq subsystem.
7 */ 8 */
8 9
9#include <linux/config.h>
10#include <linux/irq.h> 10#include <linux/irq.h>
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/random.h> 12#include <linux/random.h>
@@ -16,12 +16,6 @@
16 16
17#ifdef CONFIG_SMP 17#ifdef CONFIG_SMP
18 18
19cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
20
21#if defined (CONFIG_GENERIC_PENDING_IRQ) || defined (CONFIG_IRQBALANCE)
22cpumask_t __cacheline_aligned pending_irq_cpumask[NR_IRQS];
23#endif
24
25/** 19/**
26 * synchronize_irq - wait for pending IRQ handlers (on other CPUs) 20 * synchronize_irq - wait for pending IRQ handlers (on other CPUs)
27 * @irq: interrupt number to wait for 21 * @irq: interrupt number to wait for
@@ -42,7 +36,6 @@ void synchronize_irq(unsigned int irq)
42 while (desc->status & IRQ_INPROGRESS) 36 while (desc->status & IRQ_INPROGRESS)
43 cpu_relax(); 37 cpu_relax();
44} 38}
45
46EXPORT_SYMBOL(synchronize_irq); 39EXPORT_SYMBOL(synchronize_irq);
47 40
48#endif 41#endif
@@ -60,7 +53,7 @@ EXPORT_SYMBOL(synchronize_irq);
60 */ 53 */
61void disable_irq_nosync(unsigned int irq) 54void disable_irq_nosync(unsigned int irq)
62{ 55{
63 irq_desc_t *desc = irq_desc + irq; 56 struct irq_desc *desc = irq_desc + irq;
64 unsigned long flags; 57 unsigned long flags;
65 58
66 if (irq >= NR_IRQS) 59 if (irq >= NR_IRQS)
@@ -69,11 +62,10 @@ void disable_irq_nosync(unsigned int irq)
69 spin_lock_irqsave(&desc->lock, flags); 62 spin_lock_irqsave(&desc->lock, flags);
70 if (!desc->depth++) { 63 if (!desc->depth++) {
71 desc->status |= IRQ_DISABLED; 64 desc->status |= IRQ_DISABLED;
72 desc->handler->disable(irq); 65 desc->chip->disable(irq);
73 } 66 }
74 spin_unlock_irqrestore(&desc->lock, flags); 67 spin_unlock_irqrestore(&desc->lock, flags);
75} 68}
76
77EXPORT_SYMBOL(disable_irq_nosync); 69EXPORT_SYMBOL(disable_irq_nosync);
78 70
79/** 71/**
@@ -90,7 +82,7 @@ EXPORT_SYMBOL(disable_irq_nosync);
90 */ 82 */
91void disable_irq(unsigned int irq) 83void disable_irq(unsigned int irq)
92{ 84{
93 irq_desc_t *desc = irq_desc + irq; 85 struct irq_desc *desc = irq_desc + irq;
94 86
95 if (irq >= NR_IRQS) 87 if (irq >= NR_IRQS)
96 return; 88 return;
@@ -99,7 +91,6 @@ void disable_irq(unsigned int irq)
99 if (desc->action) 91 if (desc->action)
100 synchronize_irq(irq); 92 synchronize_irq(irq);
101} 93}
102
103EXPORT_SYMBOL(disable_irq); 94EXPORT_SYMBOL(disable_irq);
104 95
105/** 96/**
@@ -114,7 +105,7 @@ EXPORT_SYMBOL(disable_irq);
114 */ 105 */
115void enable_irq(unsigned int irq) 106void enable_irq(unsigned int irq)
116{ 107{
117 irq_desc_t *desc = irq_desc + irq; 108 struct irq_desc *desc = irq_desc + irq;
118 unsigned long flags; 109 unsigned long flags;
119 110
120 if (irq >= NR_IRQS) 111 if (irq >= NR_IRQS)
@@ -123,17 +114,15 @@ void enable_irq(unsigned int irq)
123 spin_lock_irqsave(&desc->lock, flags); 114 spin_lock_irqsave(&desc->lock, flags);
124 switch (desc->depth) { 115 switch (desc->depth) {
125 case 0: 116 case 0:
117 printk(KERN_WARNING "Unbalanced enable for IRQ %d\n", irq);
126 WARN_ON(1); 118 WARN_ON(1);
127 break; 119 break;
128 case 1: { 120 case 1: {
129 unsigned int status = desc->status & ~IRQ_DISABLED; 121 unsigned int status = desc->status & ~IRQ_DISABLED;
130 122
131 desc->status = status; 123 /* Prevent probing on this irq: */
132 if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { 124 desc->status = status | IRQ_NOPROBE;
133 desc->status = status | IRQ_REPLAY; 125 check_irq_resend(desc, irq);
134 hw_resend_irq(desc->handler,irq);
135 }
136 desc->handler->enable(irq);
137 /* fall-through */ 126 /* fall-through */
138 } 127 }
139 default: 128 default:
@@ -141,9 +130,53 @@ void enable_irq(unsigned int irq)
141 } 130 }
142 spin_unlock_irqrestore(&desc->lock, flags); 131 spin_unlock_irqrestore(&desc->lock, flags);
143} 132}
144
145EXPORT_SYMBOL(enable_irq); 133EXPORT_SYMBOL(enable_irq);
146 134
135/**
136 * set_irq_wake - control irq power management wakeup
137 * @irq: interrupt to control
138 * @on: enable/disable power management wakeup
139 *
140 * Enable/disable power management wakeup mode, which is
141 * disabled by default. Enables and disables must match,
142 * just as they match for non-wakeup mode support.
143 *
144 * Wakeup mode lets this IRQ wake the system from sleep
145 * states like "suspend to RAM".
146 */
147int set_irq_wake(unsigned int irq, unsigned int on)
148{
149 struct irq_desc *desc = irq_desc + irq;
150 unsigned long flags;
151 int ret = -ENXIO;
152 int (*set_wake)(unsigned, unsigned) = desc->chip->set_wake;
153
154 /* wakeup-capable irqs can be shared between drivers that
155 * don't need to have the same sleep mode behaviors.
156 */
157 spin_lock_irqsave(&desc->lock, flags);
158 if (on) {
159 if (desc->wake_depth++ == 0)
160 desc->status |= IRQ_WAKEUP;
161 else
162 set_wake = NULL;
163 } else {
164 if (desc->wake_depth == 0) {
165 printk(KERN_WARNING "Unbalanced IRQ %d "
166 "wake disable\n", irq);
167 WARN_ON(1);
168 } else if (--desc->wake_depth == 0)
169 desc->status &= ~IRQ_WAKEUP;
170 else
171 set_wake = NULL;
172 }
173 if (set_wake)
174 ret = desc->chip->set_wake(irq, on);
175 spin_unlock_irqrestore(&desc->lock, flags);
176 return ret;
177}
178EXPORT_SYMBOL(set_irq_wake);
179
147/* 180/*
148 * Internal function that tells the architecture code whether a 181 * Internal function that tells the architecture code whether a
149 * particular irq has been exclusively allocated or is available 182 * particular irq has been exclusively allocated or is available
@@ -153,22 +186,33 @@ int can_request_irq(unsigned int irq, unsigned long irqflags)
153{ 186{
154 struct irqaction *action; 187 struct irqaction *action;
155 188
156 if (irq >= NR_IRQS) 189 if (irq >= NR_IRQS || irq_desc[irq].status & IRQ_NOREQUEST)
157 return 0; 190 return 0;
158 191
159 action = irq_desc[irq].action; 192 action = irq_desc[irq].action;
160 if (action) 193 if (action)
161 if (irqflags & action->flags & SA_SHIRQ) 194 if (irqflags & action->flags & IRQF_SHARED)
162 action = NULL; 195 action = NULL;
163 196
164 return !action; 197 return !action;
165} 198}
166 199
200void compat_irq_chip_set_default_handler(struct irq_desc *desc)
201{
202 /*
203 * If the architecture still has not overriden
204 * the flow handler then zap the default. This
205 * should catch incorrect flow-type setting.
206 */
207 if (desc->handle_irq == &handle_bad_irq)
208 desc->handle_irq = NULL;
209}
210
167/* 211/*
168 * Internal function to register an irqaction - typically used to 212 * Internal function to register an irqaction - typically used to
169 * allocate special interrupts that are part of the architecture. 213 * allocate special interrupts that are part of the architecture.
170 */ 214 */
171int setup_irq(unsigned int irq, struct irqaction * new) 215int setup_irq(unsigned int irq, struct irqaction *new)
172{ 216{
173 struct irq_desc *desc = irq_desc + irq; 217 struct irq_desc *desc = irq_desc + irq;
174 struct irqaction *old, **p; 218 struct irqaction *old, **p;
@@ -178,14 +222,14 @@ int setup_irq(unsigned int irq, struct irqaction * new)
178 if (irq >= NR_IRQS) 222 if (irq >= NR_IRQS)
179 return -EINVAL; 223 return -EINVAL;
180 224
181 if (desc->handler == &no_irq_type) 225 if (desc->chip == &no_irq_chip)
182 return -ENOSYS; 226 return -ENOSYS;
183 /* 227 /*
184 * Some drivers like serial.c use request_irq() heavily, 228 * Some drivers like serial.c use request_irq() heavily,
185 * so we have to be careful not to interfere with a 229 * so we have to be careful not to interfere with a
186 * running system. 230 * running system.
187 */ 231 */
188 if (new->flags & SA_SAMPLE_RANDOM) { 232 if (new->flags & IRQF_SAMPLE_RANDOM) {
189 /* 233 /*
190 * This function might sleep, we want to call it first, 234 * This function might sleep, we want to call it first,
191 * outside of the atomic block. 235 * outside of the atomic block.
@@ -200,16 +244,24 @@ int setup_irq(unsigned int irq, struct irqaction * new)
200 /* 244 /*
201 * The following block of code has to be executed atomically 245 * The following block of code has to be executed atomically
202 */ 246 */
203 spin_lock_irqsave(&desc->lock,flags); 247 spin_lock_irqsave(&desc->lock, flags);
204 p = &desc->action; 248 p = &desc->action;
205 if ((old = *p) != NULL) { 249 old = *p;
206 /* Can't share interrupts unless both agree to */ 250 if (old) {
207 if (!(old->flags & new->flags & SA_SHIRQ)) 251 /*
252 * Can't share interrupts unless both agree to and are
253 * the same type (level, edge, polarity). So both flag
254 * fields must have IRQF_SHARED set and the bits which
255 * set the trigger type must match.
256 */
257 if (!((old->flags & new->flags) & IRQF_SHARED) ||
258 ((old->flags ^ new->flags) & IRQF_TRIGGER_MASK))
208 goto mismatch; 259 goto mismatch;
209 260
210#if defined(ARCH_HAS_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ) 261#if defined(CONFIG_IRQ_PER_CPU)
211 /* All handlers must agree on per-cpuness */ 262 /* All handlers must agree on per-cpuness */
212 if ((old->flags & IRQ_PER_CPU) != (new->flags & IRQ_PER_CPU)) 263 if ((old->flags & IRQF_PERCPU) !=
264 (new->flags & IRQF_PERCPU))
213 goto mismatch; 265 goto mismatch;
214#endif 266#endif
215 267
@@ -222,20 +274,45 @@ int setup_irq(unsigned int irq, struct irqaction * new)
222 } 274 }
223 275
224 *p = new; 276 *p = new;
225#if defined(ARCH_HAS_IRQ_PER_CPU) && defined(SA_PERCPU_IRQ) 277#if defined(CONFIG_IRQ_PER_CPU)
226 if (new->flags & SA_PERCPU_IRQ) 278 if (new->flags & IRQF_PERCPU)
227 desc->status |= IRQ_PER_CPU; 279 desc->status |= IRQ_PER_CPU;
228#endif 280#endif
229 if (!shared) { 281 if (!shared) {
230 desc->depth = 0; 282 irq_chip_set_defaults(desc->chip);
231 desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | 283
232 IRQ_WAITING | IRQ_INPROGRESS); 284 /* Setup the type (level, edge polarity) if configured: */
233 if (desc->handler->startup) 285 if (new->flags & IRQF_TRIGGER_MASK) {
234 desc->handler->startup(irq); 286 if (desc->chip && desc->chip->set_type)
235 else 287 desc->chip->set_type(irq,
236 desc->handler->enable(irq); 288 new->flags & IRQF_TRIGGER_MASK);
289 else
290 /*
291 * IRQF_TRIGGER_* but the PIC does not support
292 * multiple flow-types?
293 */
294 printk(KERN_WARNING "No IRQF_TRIGGER set_type "
295 "function for IRQ %d (%s)\n", irq,
296 desc->chip ? desc->chip->name :
297 "unknown");
298 } else
299 compat_irq_chip_set_default_handler(desc);
300
301 desc->status &= ~(IRQ_AUTODETECT | IRQ_WAITING |
302 IRQ_INPROGRESS);
303
304 if (!(desc->status & IRQ_NOAUTOEN)) {
305 desc->depth = 0;
306 desc->status &= ~IRQ_DISABLED;
307 if (desc->chip->startup)
308 desc->chip->startup(irq);
309 else
310 desc->chip->enable(irq);
311 } else
312 /* Undo nested disables: */
313 desc->depth = 1;
237 } 314 }
238 spin_unlock_irqrestore(&desc->lock,flags); 315 spin_unlock_irqrestore(&desc->lock, flags);
239 316
240 new->irq = irq; 317 new->irq = irq;
241 register_irq_proc(irq); 318 register_irq_proc(irq);
@@ -246,8 +323,8 @@ int setup_irq(unsigned int irq, struct irqaction * new)
246 323
247mismatch: 324mismatch:
248 spin_unlock_irqrestore(&desc->lock, flags); 325 spin_unlock_irqrestore(&desc->lock, flags);
249 if (!(new->flags & SA_PROBEIRQ)) { 326 if (!(new->flags & IRQF_PROBE_SHARED)) {
250 printk(KERN_ERR "%s: irq handler mismatch\n", __FUNCTION__); 327 printk(KERN_ERR "IRQ handler type mismatch for IRQ %d\n", irq);
251 dump_stack(); 328 dump_stack();
252 } 329 }
253 return -EBUSY; 330 return -EBUSY;
@@ -278,10 +355,10 @@ void free_irq(unsigned int irq, void *dev_id)
278 return; 355 return;
279 356
280 desc = irq_desc + irq; 357 desc = irq_desc + irq;
281 spin_lock_irqsave(&desc->lock,flags); 358 spin_lock_irqsave(&desc->lock, flags);
282 p = &desc->action; 359 p = &desc->action;
283 for (;;) { 360 for (;;) {
284 struct irqaction * action = *p; 361 struct irqaction *action = *p;
285 362
286 if (action) { 363 if (action) {
287 struct irqaction **pp = p; 364 struct irqaction **pp = p;
@@ -295,18 +372,18 @@ void free_irq(unsigned int irq, void *dev_id)
295 372
296 /* Currently used only by UML, might disappear one day.*/ 373 /* Currently used only by UML, might disappear one day.*/
297#ifdef CONFIG_IRQ_RELEASE_METHOD 374#ifdef CONFIG_IRQ_RELEASE_METHOD
298 if (desc->handler->release) 375 if (desc->chip->release)
299 desc->handler->release(irq, dev_id); 376 desc->chip->release(irq, dev_id);
300#endif 377#endif
301 378
302 if (!desc->action) { 379 if (!desc->action) {
303 desc->status |= IRQ_DISABLED; 380 desc->status |= IRQ_DISABLED;
304 if (desc->handler->shutdown) 381 if (desc->chip->shutdown)
305 desc->handler->shutdown(irq); 382 desc->chip->shutdown(irq);
306 else 383 else
307 desc->handler->disable(irq); 384 desc->chip->disable(irq);
308 } 385 }
309 spin_unlock_irqrestore(&desc->lock,flags); 386 spin_unlock_irqrestore(&desc->lock, flags);
310 unregister_handler_proc(irq, action); 387 unregister_handler_proc(irq, action);
311 388
312 /* Make sure it's not being used on another CPU */ 389 /* Make sure it's not being used on another CPU */
@@ -314,12 +391,11 @@ void free_irq(unsigned int irq, void *dev_id)
314 kfree(action); 391 kfree(action);
315 return; 392 return;
316 } 393 }
317 printk(KERN_ERR "Trying to free free IRQ%d\n",irq); 394 printk(KERN_ERR "Trying to free already-free IRQ %d\n", irq);
318 spin_unlock_irqrestore(&desc->lock,flags); 395 spin_unlock_irqrestore(&desc->lock, flags);
319 return; 396 return;
320 } 397 }
321} 398}
322
323EXPORT_SYMBOL(free_irq); 399EXPORT_SYMBOL(free_irq);
324 400
325/** 401/**
@@ -346,28 +422,36 @@ EXPORT_SYMBOL(free_irq);
346 * 422 *
347 * Flags: 423 * Flags:
348 * 424 *
349 * SA_SHIRQ Interrupt is shared 425 * IRQF_SHARED Interrupt is shared
350 * SA_INTERRUPT Disable local interrupts while processing 426 * IRQF_DISABLED Disable local interrupts while processing
351 * SA_SAMPLE_RANDOM The interrupt can be used for entropy 427 * IRQF_SAMPLE_RANDOM The interrupt can be used for entropy
352 * 428 *
353 */ 429 */
354int request_irq(unsigned int irq, 430int request_irq(unsigned int irq,
355 irqreturn_t (*handler)(int, void *, struct pt_regs *), 431 irqreturn_t (*handler)(int, void *, struct pt_regs *),
356 unsigned long irqflags, const char * devname, void *dev_id) 432 unsigned long irqflags, const char *devname, void *dev_id)
357{ 433{
358 struct irqaction * action; 434 struct irqaction *action;
359 int retval; 435 int retval;
360 436
437#ifdef CONFIG_LOCKDEP
438 /*
439 * Lockdep wants atomic interrupt handlers:
440 */
441 irqflags |= SA_INTERRUPT;
442#endif
361 /* 443 /*
362 * Sanity-check: shared interrupts must pass in a real dev-ID, 444 * Sanity-check: shared interrupts must pass in a real dev-ID,
363 * otherwise we'll have trouble later trying to figure out 445 * otherwise we'll have trouble later trying to figure out
364 * which interrupt is which (messes up the interrupt freeing 446 * which interrupt is which (messes up the interrupt freeing
365 * logic etc). 447 * logic etc).
366 */ 448 */
367 if ((irqflags & SA_SHIRQ) && !dev_id) 449 if ((irqflags & IRQF_SHARED) && !dev_id)
368 return -EINVAL; 450 return -EINVAL;
369 if (irq >= NR_IRQS) 451 if (irq >= NR_IRQS)
370 return -EINVAL; 452 return -EINVAL;
453 if (irq_desc[irq].status & IRQ_NOREQUEST)
454 return -EINVAL;
371 if (!handler) 455 if (!handler)
372 return -EINVAL; 456 return -EINVAL;
373 457
@@ -390,6 +474,5 @@ int request_irq(unsigned int irq,
390 474
391 return retval; 475 return retval;
392} 476}
393
394EXPORT_SYMBOL(request_irq); 477EXPORT_SYMBOL(request_irq);
395 478
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index a12d00eb5e7c..a57ebe9fa6f6 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -3,19 +3,19 @@
3 3
4void set_pending_irq(unsigned int irq, cpumask_t mask) 4void set_pending_irq(unsigned int irq, cpumask_t mask)
5{ 5{
6 irq_desc_t *desc = irq_desc + irq; 6 struct irq_desc *desc = irq_desc + irq;
7 unsigned long flags; 7 unsigned long flags;
8 8
9 spin_lock_irqsave(&desc->lock, flags); 9 spin_lock_irqsave(&desc->lock, flags);
10 desc->move_irq = 1; 10 desc->move_irq = 1;
11 pending_irq_cpumask[irq] = mask; 11 irq_desc[irq].pending_mask = mask;
12 spin_unlock_irqrestore(&desc->lock, flags); 12 spin_unlock_irqrestore(&desc->lock, flags);
13} 13}
14 14
15void move_native_irq(int irq) 15void move_native_irq(int irq)
16{ 16{
17 struct irq_desc *desc = irq_desc + irq;
17 cpumask_t tmp; 18 cpumask_t tmp;
18 irq_desc_t *desc = irq_descp(irq);
19 19
20 if (likely(!desc->move_irq)) 20 if (likely(!desc->move_irq))
21 return; 21 return;
@@ -30,15 +30,15 @@ void move_native_irq(int irq)
30 30
31 desc->move_irq = 0; 31 desc->move_irq = 0;
32 32
33 if (unlikely(cpus_empty(pending_irq_cpumask[irq]))) 33 if (unlikely(cpus_empty(irq_desc[irq].pending_mask)))
34 return; 34 return;
35 35
36 if (!desc->handler->set_affinity) 36 if (!desc->chip->set_affinity)
37 return; 37 return;
38 38
39 assert_spin_locked(&desc->lock); 39 assert_spin_locked(&desc->lock);
40 40
41 cpus_and(tmp, pending_irq_cpumask[irq], cpu_online_map); 41 cpus_and(tmp, irq_desc[irq].pending_mask, cpu_online_map);
42 42
43 /* 43 /*
44 * If there was a valid mask to work with, please 44 * If there was a valid mask to work with, please
@@ -51,12 +51,12 @@ void move_native_irq(int irq)
51 */ 51 */
52 if (likely(!cpus_empty(tmp))) { 52 if (likely(!cpus_empty(tmp))) {
53 if (likely(!(desc->status & IRQ_DISABLED))) 53 if (likely(!(desc->status & IRQ_DISABLED)))
54 desc->handler->disable(irq); 54 desc->chip->disable(irq);
55 55
56 desc->handler->set_affinity(irq,tmp); 56 desc->chip->set_affinity(irq,tmp);
57 57
58 if (likely(!(desc->status & IRQ_DISABLED))) 58 if (likely(!(desc->status & IRQ_DISABLED)))
59 desc->handler->enable(irq); 59 desc->chip->enable(irq);
60 } 60 }
61 cpus_clear(pending_irq_cpumask[irq]); 61 cpus_clear(irq_desc[irq].pending_mask);
62} 62}
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index afacd6f585fa..607c7809ad01 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -12,15 +12,10 @@
12 12
13#include "internals.h" 13#include "internals.h"
14 14
15static struct proc_dir_entry *root_irq_dir, *irq_dir[NR_IRQS]; 15static struct proc_dir_entry *root_irq_dir;
16 16
17#ifdef CONFIG_SMP 17#ifdef CONFIG_SMP
18 18
19/*
20 * The /proc/irq/<irq>/smp_affinity values:
21 */
22static struct proc_dir_entry *smp_affinity_entry[NR_IRQS];
23
24#ifdef CONFIG_GENERIC_PENDING_IRQ 19#ifdef CONFIG_GENERIC_PENDING_IRQ
25void proc_set_irq_affinity(unsigned int irq, cpumask_t mask_val) 20void proc_set_irq_affinity(unsigned int irq, cpumask_t mask_val)
26{ 21{
@@ -36,15 +31,15 @@ void proc_set_irq_affinity(unsigned int irq, cpumask_t mask_val)
36void proc_set_irq_affinity(unsigned int irq, cpumask_t mask_val) 31void proc_set_irq_affinity(unsigned int irq, cpumask_t mask_val)
37{ 32{
38 set_balance_irq_affinity(irq, mask_val); 33 set_balance_irq_affinity(irq, mask_val);
39 irq_affinity[irq] = mask_val; 34 irq_desc[irq].affinity = mask_val;
40 irq_desc[irq].handler->set_affinity(irq, mask_val); 35 irq_desc[irq].chip->set_affinity(irq, mask_val);
41} 36}
42#endif 37#endif
43 38
44static int irq_affinity_read_proc(char *page, char **start, off_t off, 39static int irq_affinity_read_proc(char *page, char **start, off_t off,
45 int count, int *eof, void *data) 40 int count, int *eof, void *data)
46{ 41{
47 int len = cpumask_scnprintf(page, count, irq_affinity[(long)data]); 42 int len = cpumask_scnprintf(page, count, irq_desc[(long)data].affinity);
48 43
49 if (count - len < 2) 44 if (count - len < 2)
50 return -EINVAL; 45 return -EINVAL;
@@ -59,7 +54,7 @@ static int irq_affinity_write_proc(struct file *file, const char __user *buffer,
59 unsigned int irq = (int)(long)data, full_count = count, err; 54 unsigned int irq = (int)(long)data, full_count = count, err;
60 cpumask_t new_value, tmp; 55 cpumask_t new_value, tmp;
61 56
62 if (!irq_desc[irq].handler->set_affinity || no_irq_affinity) 57 if (!irq_desc[irq].chip->set_affinity || no_irq_affinity)
63 return -EIO; 58 return -EIO;
64 59
65 err = cpumask_parse(buffer, count, new_value); 60 err = cpumask_parse(buffer, count, new_value);
@@ -102,7 +97,7 @@ void register_handler_proc(unsigned int irq, struct irqaction *action)
102{ 97{
103 char name [MAX_NAMELEN]; 98 char name [MAX_NAMELEN];
104 99
105 if (!irq_dir[irq] || action->dir || !action->name || 100 if (!irq_desc[irq].dir || action->dir || !action->name ||
106 !name_unique(irq, action)) 101 !name_unique(irq, action))
107 return; 102 return;
108 103
@@ -110,7 +105,7 @@ void register_handler_proc(unsigned int irq, struct irqaction *action)
110 snprintf(name, MAX_NAMELEN, "%s", action->name); 105 snprintf(name, MAX_NAMELEN, "%s", action->name);
111 106
112 /* create /proc/irq/1234/handler/ */ 107 /* create /proc/irq/1234/handler/ */
113 action->dir = proc_mkdir(name, irq_dir[irq]); 108 action->dir = proc_mkdir(name, irq_desc[irq].dir);
114} 109}
115 110
116#undef MAX_NAMELEN 111#undef MAX_NAMELEN
@@ -122,22 +117,22 @@ void register_irq_proc(unsigned int irq)
122 char name [MAX_NAMELEN]; 117 char name [MAX_NAMELEN];
123 118
124 if (!root_irq_dir || 119 if (!root_irq_dir ||
125 (irq_desc[irq].handler == &no_irq_type) || 120 (irq_desc[irq].chip == &no_irq_chip) ||
126 irq_dir[irq]) 121 irq_desc[irq].dir)
127 return; 122 return;
128 123
129 memset(name, 0, MAX_NAMELEN); 124 memset(name, 0, MAX_NAMELEN);
130 sprintf(name, "%d", irq); 125 sprintf(name, "%d", irq);
131 126
132 /* create /proc/irq/1234 */ 127 /* create /proc/irq/1234 */
133 irq_dir[irq] = proc_mkdir(name, root_irq_dir); 128 irq_desc[irq].dir = proc_mkdir(name, root_irq_dir);
134 129
135#ifdef CONFIG_SMP 130#ifdef CONFIG_SMP
136 { 131 {
137 struct proc_dir_entry *entry; 132 struct proc_dir_entry *entry;
138 133
139 /* create /proc/irq/<irq>/smp_affinity */ 134 /* create /proc/irq/<irq>/smp_affinity */
140 entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]); 135 entry = create_proc_entry("smp_affinity", 0600, irq_desc[irq].dir);
141 136
142 if (entry) { 137 if (entry) {
143 entry->nlink = 1; 138 entry->nlink = 1;
@@ -145,7 +140,6 @@ void register_irq_proc(unsigned int irq)
145 entry->read_proc = irq_affinity_read_proc; 140 entry->read_proc = irq_affinity_read_proc;
146 entry->write_proc = irq_affinity_write_proc; 141 entry->write_proc = irq_affinity_write_proc;
147 } 142 }
148 smp_affinity_entry[irq] = entry;
149 } 143 }
150#endif 144#endif
151} 145}
@@ -155,7 +149,7 @@ void register_irq_proc(unsigned int irq)
155void unregister_handler_proc(unsigned int irq, struct irqaction *action) 149void unregister_handler_proc(unsigned int irq, struct irqaction *action)
156{ 150{
157 if (action->dir) 151 if (action->dir)
158 remove_proc_entry(action->dir->name, irq_dir[irq]); 152 remove_proc_entry(action->dir->name, irq_desc[irq].dir);
159} 153}
160 154
161void init_irq_proc(void) 155void init_irq_proc(void)
diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c
new file mode 100644
index 000000000000..35f10f7ff94a
--- /dev/null
+++ b/kernel/irq/resend.c
@@ -0,0 +1,77 @@
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: */
26static DECLARE_BITMAP(irqs_resend, NR_IRQS);
27
28/*
29 * Run software resends of IRQ's
30 */
31static 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_desc + irq;
40 local_irq_disable();
41 desc->handle_irq(irq, desc, NULL);
42 local_irq_enable();
43 }
44}
45
46/* Tasklet to handle resend: */
47static 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 */
56void 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->chip->enable(irq);
64
65 if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
66 desc->status = (status & ~IRQ_PENDING) | IRQ_REPLAY;
67
68 if (!desc->chip || !desc->chip->retrigger ||
69 !desc->chip->retrigger(irq)) {
70#ifdef CONFIG_HARDIRQS_SW_RESEND
71 /* Set it pending and activate the softirq: */
72 set_bit(irq, irqs_resend);
73 tasklet_schedule(&resend_tasklet);
74#endif
75 }
76 }
77}
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index b2fb3c18d06b..417e98092cf2 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -16,39 +16,39 @@ static int irqfixup __read_mostly;
16/* 16/*
17 * Recovery handler for misrouted interrupts. 17 * Recovery handler for misrouted interrupts.
18 */ 18 */
19
20static int misrouted_irq(int irq, struct pt_regs *regs) 19static int misrouted_irq(int irq, struct pt_regs *regs)
21{ 20{
22 int i; 21 int i;
23 irq_desc_t *desc;
24 int ok = 0; 22 int ok = 0;
25 int work = 0; /* Did we do work for a real IRQ */ 23 int work = 0; /* Did we do work for a real IRQ */
26 24
27 for(i = 1; i < NR_IRQS; i++) { 25 for (i = 1; i < NR_IRQS; i++) {
26 struct irq_desc *desc = irq_desc + i;
28 struct irqaction *action; 27 struct irqaction *action;
29 28
30 if (i == irq) /* Already tried */ 29 if (i == irq) /* Already tried */
31 continue; 30 continue;
32 desc = &irq_desc[i]; 31
33 spin_lock(&desc->lock); 32 spin_lock(&desc->lock);
34 action = desc->action;
35 /* Already running on another processor */ 33 /* Already running on another processor */
36 if (desc->status & IRQ_INPROGRESS) { 34 if (desc->status & IRQ_INPROGRESS) {
37 /* 35 /*
38 * Already running: If it is shared get the other 36 * Already running: If it is shared get the other
39 * CPU to go looking for our mystery interrupt too 37 * CPU to go looking for our mystery interrupt too
40 */ 38 */
41 if (desc->action && (desc->action->flags & SA_SHIRQ)) 39 if (desc->action && (desc->action->flags & IRQF_SHARED))
42 desc->status |= IRQ_PENDING; 40 desc->status |= IRQ_PENDING;
43 spin_unlock(&desc->lock); 41 spin_unlock(&desc->lock);
44 continue; 42 continue;
45 } 43 }
46 /* Honour the normal IRQ locking */ 44 /* Honour the normal IRQ locking */
47 desc->status |= IRQ_INPROGRESS; 45 desc->status |= IRQ_INPROGRESS;
46 action = desc->action;
48 spin_unlock(&desc->lock); 47 spin_unlock(&desc->lock);
48
49 while (action) { 49 while (action) {
50 /* Only shared IRQ handlers are safe to call */ 50 /* Only shared IRQ handlers are safe to call */
51 if (action->flags & SA_SHIRQ) { 51 if (action->flags & IRQF_SHARED) {
52 if (action->handler(i, action->dev_id, regs) == 52 if (action->handler(i, action->dev_id, regs) ==
53 IRQ_HANDLED) 53 IRQ_HANDLED)
54 ok = 1; 54 ok = 1;
@@ -62,9 +62,8 @@ static int misrouted_irq(int irq, struct pt_regs *regs)
62 62
63 /* 63 /*
64 * While we were looking for a fixup someone queued a real 64 * While we were looking for a fixup someone queued a real
65 * IRQ clashing with our walk 65 * IRQ clashing with our walk:
66 */ 66 */
67
68 while ((desc->status & IRQ_PENDING) && action) { 67 while ((desc->status & IRQ_PENDING) && action) {
69 /* 68 /*
70 * Perform real IRQ processing for the IRQ we deferred 69 * Perform real IRQ processing for the IRQ we deferred
@@ -80,8 +79,8 @@ static int misrouted_irq(int irq, struct pt_regs *regs)
80 * If we did actual work for the real IRQ line we must let the 79 * If we did actual work for the real IRQ line we must let the
81 * IRQ controller clean up too 80 * IRQ controller clean up too
82 */ 81 */
83 if(work) 82 if (work && desc->chip && desc->chip->end)
84 desc->handler->end(i); 83 desc->chip->end(i);
85 spin_unlock(&desc->lock); 84 spin_unlock(&desc->lock);
86 } 85 }
87 /* So the caller can adjust the irq error counts */ 86 /* So the caller can adjust the irq error counts */
@@ -100,7 +99,8 @@ static int misrouted_irq(int irq, struct pt_regs *regs)
100 */ 99 */
101 100
102static void 101static void
103__report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) 102__report_bad_irq(unsigned int irq, struct irq_desc *desc,
103 irqreturn_t action_ret)
104{ 104{
105 struct irqaction *action; 105 struct irqaction *action;
106 106
@@ -113,6 +113,7 @@ __report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret)
113 } 113 }
114 dump_stack(); 114 dump_stack();
115 printk(KERN_ERR "handlers:\n"); 115 printk(KERN_ERR "handlers:\n");
116
116 action = desc->action; 117 action = desc->action;
117 while (action) { 118 while (action) {
118 printk(KERN_ERR "[<%p>]", action->handler); 119 printk(KERN_ERR "[<%p>]", action->handler);
@@ -123,7 +124,8 @@ __report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret)
123 } 124 }
124} 125}
125 126
126static void report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) 127static void
128report_bad_irq(unsigned int irq, struct irq_desc *desc, irqreturn_t action_ret)
127{ 129{
128 static int count = 100; 130 static int count = 100;
129 131
@@ -133,8 +135,8 @@ static void report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t actio
133 } 135 }
134} 136}
135 137
136void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret, 138void note_interrupt(unsigned int irq, struct irq_desc *desc,
137 struct pt_regs *regs) 139 irqreturn_t action_ret, struct pt_regs *regs)
138{ 140{
139 if (unlikely(action_ret != IRQ_HANDLED)) { 141 if (unlikely(action_ret != IRQ_HANDLED)) {
140 desc->irqs_unhandled++; 142 desc->irqs_unhandled++;
@@ -166,7 +168,8 @@ void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret,
166 */ 168 */
167 printk(KERN_EMERG "Disabling IRQ #%d\n", irq); 169 printk(KERN_EMERG "Disabling IRQ #%d\n", irq);
168 desc->status |= IRQ_DISABLED; 170 desc->status |= IRQ_DISABLED;
169 desc->handler->disable(irq); 171 desc->depth = 1;
172 desc->chip->disable(irq);
170 } 173 }
171 desc->irqs_unhandled = 0; 174 desc->irqs_unhandled = 0;
172} 175}
@@ -177,6 +180,7 @@ int __init noirqdebug_setup(char *str)
177{ 180{
178 noirqdebug = 1; 181 noirqdebug = 1;
179 printk(KERN_INFO "IRQ lockup detection disabled\n"); 182 printk(KERN_INFO "IRQ lockup detection disabled\n");
183
180 return 1; 184 return 1;
181} 185}
182 186
@@ -187,6 +191,7 @@ static int __init irqfixup_setup(char *str)
187 irqfixup = 1; 191 irqfixup = 1;
188 printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n"); 192 printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n");
189 printk(KERN_WARNING "This may impact system performance.\n"); 193 printk(KERN_WARNING "This may impact system performance.\n");
194
190 return 1; 195 return 1;
191} 196}
192 197