diff options
Diffstat (limited to 'kernel/irq')
-rw-r--r-- | kernel/irq/autoprobe.c | 9 | ||||
-rw-r--r-- | kernel/irq/handle.c | 10 | ||||
-rw-r--r-- | kernel/irq/internals.h | 6 | ||||
-rw-r--r-- | kernel/irq/manage.c | 14 | ||||
-rw-r--r-- | kernel/irq/resend.c | 4 | ||||
-rw-r--r-- | kernel/irq/spurious.c | 1 |
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 | */ | ||
24 | void fastcall | ||
25 | handle_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 | ||
5 | extern int noirqdebug; | 5 | extern int noirqdebug; |
6 | 6 | ||
7 | /* Set default functions for irq_chip structures: */ | ||
8 | extern void irq_chip_set_defaults(struct irq_chip *chip); | ||
9 | |||
10 | /* Set default handler: */ | ||
11 | extern void compat_irq_chip_set_default_handler(struct irq_desc *desc); | ||
12 | |||
7 | #ifdef CONFIG_PROC_FS | 13 | #ifdef CONFIG_PROC_FS |
8 | extern void register_irq_proc(unsigned int irq); | 14 | extern void register_irq_proc(unsigned int irq); |
9 | extern void register_handler_proc(unsigned int irq, struct irqaction *action); | 15 | extern 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 | ||
156 | void 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; |