aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/irq')
-rw-r--r--kernel/irq/autoprobe.c9
-rw-r--r--kernel/irq/handle.c10
-rw-r--r--kernel/irq/internals.h6
-rw-r--r--kernel/irq/manage.c14
-rw-r--r--kernel/irq/resend.c4
-rw-r--r--kernel/irq/spurious.c1
6 files changed, 41 insertions, 3 deletions
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c
index ed98c7d46cf2..cfdb63eb5c94 100644
--- a/kernel/irq/autoprobe.c
+++ b/kernel/irq/autoprobe.c
@@ -40,8 +40,15 @@ unsigned long probe_irq_on(void)
40 desc = irq_desc + i; 40 desc = irq_desc + i;
41 41
42 spin_lock_irq(&desc->lock); 42 spin_lock_irq(&desc->lock);
43 if (!desc->action && !(desc->status & IRQ_NOPROBE)) 43 if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
44 /*
45 * Some chips need to know about probing in
46 * progress:
47 */
48 if (desc->chip->set_type)
49 desc->chip->set_type(i, IRQ_TYPE_PROBE);
44 desc->chip->startup(i); 50 desc->chip->startup(i);
51 }
45 spin_unlock_irq(&desc->lock); 52 spin_unlock_irq(&desc->lock);
46 } 53 }
47 54
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index bddcb8f5fea4..a04b516afa59 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -18,6 +18,16 @@
18 18
19#include "internals.h" 19#include "internals.h"
20 20
21/**
22 * handle_bad_irq - handle spurious and unhandled irqs
23 */
24void fastcall
25handle_bad_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs)
26{
27 kstat_this_cpu.irqs[irq]++;
28 ack_bad_irq(irq);
29}
30
21/* 31/*
22 * Linux has a controller-independent interrupt architecture. 32 * Linux has a controller-independent interrupt architecture.
23 * Every controller has a 'controller-template', that is used 33 * Every controller has a 'controller-template', that is used
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index 46feba630266..2ba8ae3c8e96 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);
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 1a2e7663096a..b61784ee78b2 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -153,6 +153,17 @@ int can_request_irq(unsigned int irq, unsigned long irqflags)
153 return !action; 153 return !action;
154} 154}
155 155
156void compat_irq_chip_set_default_handler(struct irq_desc *desc)
157{
158 /*
159 * If the architecture still has not overriden
160 * the flow handler then zap the default. This
161 * should catch incorrect flow-type setting.
162 */
163 if (desc->handle_irq == &handle_bad_irq)
164 desc->handle_irq = NULL;
165}
166
156/* 167/*
157 * Internal function to register an irqaction - typically used to 168 * Internal function to register an irqaction - typically used to
158 * allocate special interrupts that are part of the architecture. 169 * allocate special interrupts that are part of the architecture.
@@ -217,6 +228,9 @@ int setup_irq(unsigned int irq, struct irqaction *new)
217 desc->status |= IRQ_PER_CPU; 228 desc->status |= IRQ_PER_CPU;
218#endif 229#endif
219 if (!shared) { 230 if (!shared) {
231 irq_chip_set_defaults(desc->chip);
232 compat_irq_chip_set_default_handler(desc);
233
220 desc->status &= ~(IRQ_AUTODETECT | IRQ_WAITING | 234 desc->status &= ~(IRQ_AUTODETECT | IRQ_WAITING |
221 IRQ_INPROGRESS); 235 IRQ_INPROGRESS);
222 236
diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c
index 096b102fb392..872f91ba2ce8 100644
--- a/kernel/irq/resend.c
+++ b/kernel/irq/resend.c
@@ -37,9 +37,9 @@ static void resend_irqs(unsigned long arg)
37 irq = find_first_bit(irqs_resend, NR_IRQS); 37 irq = find_first_bit(irqs_resend, NR_IRQS);
38 clear_bit(irq, irqs_resend); 38 clear_bit(irq, irqs_resend);
39 desc = irq_desc + irq; 39 desc = irq_desc + irq;
40 spin_lock_irqsave(&desc->lock, flags); 40 local_irq_disable();
41 desc->handle_irq(irq, desc, NULL); 41 desc->handle_irq(irq, desc, NULL);
42 spin_unlock_irqrestore(&desc->lock, flags); 42 local_irq_enable();
43 } 43 }
44} 44}
45 45
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index 3a0a62123301..ca187b83f897 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -168,6 +168,7 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc,
168 */ 168 */
169 printk(KERN_EMERG "Disabling IRQ #%d\n", irq); 169 printk(KERN_EMERG "Disabling IRQ #%d\n", irq);
170 desc->status |= IRQ_DISABLED; 170 desc->status |= IRQ_DISABLED;
171 desc->depth = 1;
171 desc->chip->disable(irq); 172 desc->chip->disable(irq);
172 } 173 }
173 desc->irqs_unhandled = 0; 174 desc->irqs_unhandled = 0;