aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/DocBook/genericirq.tmpl1
-rw-r--r--Documentation/feature-removal-schedule.txt17
-rw-r--r--arch/alpha/kernel/irq.c2
-rw-r--r--arch/alpha/kernel/irq_alpha.c2
-rw-r--r--arch/arm/kernel/irq.c2
-rw-r--r--arch/arm/mach-ns9xxx/irq.c3
-rw-r--r--arch/avr32/kernel/irq.c2
-rw-r--r--arch/blackfin/kernel/irqchip.c2
-rw-r--r--arch/cris/kernel/irq.c2
-rw-r--r--arch/frv/kernel/irq.c2
-rw-r--r--arch/h8300/kernel/irq.c4
-rw-r--r--arch/ia64/kernel/irq.c2
-rw-r--r--arch/m32r/kernel/irq.c2
-rw-r--r--arch/mips/kernel/irq.c2
-rw-r--r--arch/mn10300/kernel/irq.c2
-rw-r--r--arch/parisc/kernel/irq.c2
-rw-r--r--arch/powerpc/kernel/irq.c2
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c4
-rw-r--r--arch/sh/kernel/irq.c2
-rw-r--r--arch/sparc/kernel/irq_64.c2
-rw-r--r--arch/sparc/kernel/time_64.c2
-rw-r--r--arch/um/kernel/irq.c2
-rw-r--r--arch/x86/Kconfig3
-rw-r--r--arch/xtensa/kernel/irq.c2
-rw-r--r--drivers/char/random.c6
-rw-r--r--drivers/pci/intr_remapping.c2
-rw-r--r--include/linux/interrupt.h17
-rw-r--r--include/linux/irq.h16
-rw-r--r--include/linux/irqnr.h8
-rw-r--r--include/linux/irqreturn.h28
-rw-r--r--include/linux/kernel_stat.h13
-rw-r--r--kernel/irq/chip.c7
-rw-r--r--kernel/irq/handle.c39
-rw-r--r--kernel/irq/internals.h1
-rw-r--r--kernel/irq/manage.c192
-rw-r--r--kernel/irq/numa_migrate.c11
-rw-r--r--kernel/irq/spurious.c14
37 files changed, 252 insertions, 170 deletions
diff --git a/Documentation/DocBook/genericirq.tmpl b/Documentation/DocBook/genericirq.tmpl
index 3a882d9a90a9..c671a0168096 100644
--- a/Documentation/DocBook/genericirq.tmpl
+++ b/Documentation/DocBook/genericirq.tmpl
@@ -440,6 +440,7 @@ desc->chip->end();
440 used in the generic IRQ layer. 440 used in the generic IRQ layer.
441 </para> 441 </para>
442!Iinclude/linux/irq.h 442!Iinclude/linux/irq.h
443!Iinclude/linux/interrupt.h
443 </chapter> 444 </chapter>
444 445
445 <chapter id="pubfunctions"> 446 <chapter id="pubfunctions">
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 802c6fd20c63..e47c0ff8ba7a 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -346,3 +346,20 @@ Why: See commits 129f8ae9b1b5be94517da76009ea956e89104ce8 and
346 Removal is subject to fixing any remaining bugs in ACPI which may 346 Removal is subject to fixing any remaining bugs in ACPI which may
347 cause the thermal throttling not to happen at the right time. 347 cause the thermal throttling not to happen at the right time.
348Who: Dave Jones <davej@redhat.com>, Matthew Garrett <mjg@redhat.com> 348Who: Dave Jones <davej@redhat.com>, Matthew Garrett <mjg@redhat.com>
349
350-----------------------------
351
352What: __do_IRQ all in one fits nothing interrupt handler
353When: 2.6.32
354Why: __do_IRQ was kept for easy migration to the type flow handlers.
355 More than two years of migration time is enough.
356Who: Thomas Gleixner <tglx@linutronix.de>
357
358-----------------------------
359
360What: obsolete generic irq defines and typedefs
361When: 2.6.30
362Why: The defines and typedefs (hw_interrupt_type, no_irq_type, irq_desc_t)
363 have been kept around for migration reasons. After more than two years
364 it's time to remove them finally
365Who: Thomas Gleixner <tglx@linutronix.de>
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index 703731accda6..d3812eb84015 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -90,7 +90,7 @@ show_interrupts(struct seq_file *p, void *v)
90 seq_printf(p, "%10u ", kstat_irqs(irq)); 90 seq_printf(p, "%10u ", kstat_irqs(irq));
91#else 91#else
92 for_each_online_cpu(j) 92 for_each_online_cpu(j)
93 seq_printf(p, "%10u ", kstat_cpu(j).irqs[irq]); 93 seq_printf(p, "%10u ", kstat_irqs_cpu(irq, j));
94#endif 94#endif
95 seq_printf(p, " %14s", irq_desc[irq].chip->typename); 95 seq_printf(p, " %14s", irq_desc[irq].chip->typename);
96 seq_printf(p, " %c%s", 96 seq_printf(p, " %c%s",
diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c
index e16aeb6e79ef..67c19f8a9944 100644
--- a/arch/alpha/kernel/irq_alpha.c
+++ b/arch/alpha/kernel/irq_alpha.c
@@ -64,7 +64,7 @@ do_entInt(unsigned long type, unsigned long vector,
64 smp_percpu_timer_interrupt(regs); 64 smp_percpu_timer_interrupt(regs);
65 cpu = smp_processor_id(); 65 cpu = smp_processor_id();
66 if (cpu != boot_cpuid) { 66 if (cpu != boot_cpuid) {
67 kstat_cpu(cpu).irqs[RTC_IRQ]++; 67 kstat_incr_irqs_this_cpu(RTC_IRQ, irq_to_desc(RTC_IRQ));
68 } else { 68 } else {
69 handle_irq(RTC_IRQ); 69 handle_irq(RTC_IRQ);
70 } 70 }
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 363db186cb93..7296f0416286 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -76,7 +76,7 @@ int show_interrupts(struct seq_file *p, void *v)
76 76
77 seq_printf(p, "%3d: ", i); 77 seq_printf(p, "%3d: ", i);
78 for_each_present_cpu(cpu) 78 for_each_present_cpu(cpu)
79 seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]); 79 seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
80 seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-"); 80 seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
81 seq_printf(p, " %s", action->name); 81 seq_printf(p, " %s", action->name);
82 for (action = action->next; action; action = action->next) 82 for (action = action->next; action; action = action->next)
diff --git a/arch/arm/mach-ns9xxx/irq.c b/arch/arm/mach-ns9xxx/irq.c
index 22e0eb6e9ec4..feb0e54a91de 100644
--- a/arch/arm/mach-ns9xxx/irq.c
+++ b/arch/arm/mach-ns9xxx/irq.c
@@ -63,7 +63,6 @@ static struct irq_chip ns9xxx_chip = {
63#else 63#else
64static void handle_prio_irq(unsigned int irq, struct irq_desc *desc) 64static void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
65{ 65{
66 unsigned int cpu = smp_processor_id();
67 struct irqaction *action; 66 struct irqaction *action;
68 irqreturn_t action_ret; 67 irqreturn_t action_ret;
69 68
@@ -72,7 +71,7 @@ static void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
72 BUG_ON(desc->status & IRQ_INPROGRESS); 71 BUG_ON(desc->status & IRQ_INPROGRESS);
73 72
74 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); 73 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
75 kstat_cpu(cpu).irqs[irq]++; 74 kstat_incr_irqs_this_cpu(irq, desc);
76 75
77 action = desc->action; 76 action = desc->action;
78 if (unlikely(!action || (desc->status & IRQ_DISABLED))) 77 if (unlikely(!action || (desc->status & IRQ_DISABLED)))
diff --git a/arch/avr32/kernel/irq.c b/arch/avr32/kernel/irq.c
index a8e767d836aa..9f572229d318 100644
--- a/arch/avr32/kernel/irq.c
+++ b/arch/avr32/kernel/irq.c
@@ -58,7 +58,7 @@ int show_interrupts(struct seq_file *p, void *v)
58 58
59 seq_printf(p, "%3d: ", i); 59 seq_printf(p, "%3d: ", i);
60 for_each_online_cpu(cpu) 60 for_each_online_cpu(cpu)
61 seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]); 61 seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
62 seq_printf(p, " %8s", irq_desc[i].chip->name ? : "-"); 62 seq_printf(p, " %8s", irq_desc[i].chip->name ? : "-");
63 seq_printf(p, " %s", action->name); 63 seq_printf(p, " %s", action->name);
64 for (action = action->next; action; action = action->next) 64 for (action = action->next; action; action = action->next)
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
index 7fd126564846..bd052a67032e 100644
--- a/arch/blackfin/kernel/irqchip.c
+++ b/arch/blackfin/kernel/irqchip.c
@@ -83,7 +83,7 @@ int show_interrupts(struct seq_file *p, void *v)
83 goto skip; 83 goto skip;
84 seq_printf(p, "%3d: ", i); 84 seq_printf(p, "%3d: ", i);
85 for_each_online_cpu(j) 85 for_each_online_cpu(j)
86 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); 86 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
87 seq_printf(p, " %8s", irq_desc[i].chip->name); 87 seq_printf(p, " %8s", irq_desc[i].chip->name);
88 seq_printf(p, " %s", action->name); 88 seq_printf(p, " %s", action->name);
89 for (action = action->next; action; action = action->next) 89 for (action = action->next; action; action = action->next)
diff --git a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c
index 2dfac8c79090..7f642fcffbfc 100644
--- a/arch/cris/kernel/irq.c
+++ b/arch/cris/kernel/irq.c
@@ -66,7 +66,7 @@ int show_interrupts(struct seq_file *p, void *v)
66 seq_printf(p, "%10u ", kstat_irqs(i)); 66 seq_printf(p, "%10u ", kstat_irqs(i));
67#else 67#else
68 for_each_online_cpu(j) 68 for_each_online_cpu(j)
69 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); 69 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
70#endif 70#endif
71 seq_printf(p, " %14s", irq_desc[i].chip->typename); 71 seq_printf(p, " %14s", irq_desc[i].chip->typename);
72 seq_printf(p, " %s", action->name); 72 seq_printf(p, " %s", action->name);
diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c
index 73abae767fdc..af3e824b91b3 100644
--- a/arch/frv/kernel/irq.c
+++ b/arch/frv/kernel/irq.c
@@ -74,7 +74,7 @@ int show_interrupts(struct seq_file *p, void *v)
74 if (action) { 74 if (action) {
75 seq_printf(p, "%3d: ", i); 75 seq_printf(p, "%3d: ", i);
76 for_each_present_cpu(cpu) 76 for_each_present_cpu(cpu)
77 seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]); 77 seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
78 seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-"); 78 seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
79 seq_printf(p, " %s", action->name); 79 seq_printf(p, " %s", action->name);
80 for (action = action->next; 80 for (action = action->next;
diff --git a/arch/h8300/kernel/irq.c b/arch/h8300/kernel/irq.c
index ef4f0047067d..74f8dd7b34d2 100644
--- a/arch/h8300/kernel/irq.c
+++ b/arch/h8300/kernel/irq.c
@@ -183,7 +183,7 @@ asmlinkage void do_IRQ(int irq)
183#if defined(CONFIG_PROC_FS) 183#if defined(CONFIG_PROC_FS)
184int show_interrupts(struct seq_file *p, void *v) 184int show_interrupts(struct seq_file *p, void *v)
185{ 185{
186 int i = *(loff_t *) v, j; 186 int i = *(loff_t *) v;
187 struct irqaction * action; 187 struct irqaction * action;
188 unsigned long flags; 188 unsigned long flags;
189 189
@@ -196,7 +196,7 @@ int show_interrupts(struct seq_file *p, void *v)
196 if (!action) 196 if (!action)
197 goto unlock; 197 goto unlock;
198 seq_printf(p, "%3d: ",i); 198 seq_printf(p, "%3d: ",i);
199 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); 199 seq_printf(p, "%10u ", kstat_irqs(i));
200 seq_printf(p, " %14s", irq_desc[i].chip->name); 200 seq_printf(p, " %14s", irq_desc[i].chip->name);
201 seq_printf(p, "-%-8s", irq_desc[i].name); 201 seq_printf(p, "-%-8s", irq_desc[i].name);
202 seq_printf(p, " %s", action->name); 202 seq_printf(p, " %s", action->name);
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
index a58f64ca9f0e..4f596613bffd 100644
--- a/arch/ia64/kernel/irq.c
+++ b/arch/ia64/kernel/irq.c
@@ -80,7 +80,7 @@ int show_interrupts(struct seq_file *p, void *v)
80 seq_printf(p, "%10u ", kstat_irqs(i)); 80 seq_printf(p, "%10u ", kstat_irqs(i));
81#else 81#else
82 for_each_online_cpu(j) { 82 for_each_online_cpu(j) {
83 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); 83 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
84 } 84 }
85#endif 85#endif
86 seq_printf(p, " %14s", irq_desc[i].chip->name); 86 seq_printf(p, " %14s", irq_desc[i].chip->name);
diff --git a/arch/m32r/kernel/irq.c b/arch/m32r/kernel/irq.c
index 2aeae4670098..8dfd31e87c4c 100644
--- a/arch/m32r/kernel/irq.c
+++ b/arch/m32r/kernel/irq.c
@@ -49,7 +49,7 @@ int show_interrupts(struct seq_file *p, void *v)
49 seq_printf(p, "%10u ", kstat_irqs(i)); 49 seq_printf(p, "%10u ", kstat_irqs(i));
50#else 50#else
51 for_each_online_cpu(j) 51 for_each_online_cpu(j)
52 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); 52 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
53#endif 53#endif
54 seq_printf(p, " %14s", irq_desc[i].chip->typename); 54 seq_printf(p, " %14s", irq_desc[i].chip->typename);
55 seq_printf(p, " %s", action->name); 55 seq_printf(p, " %s", action->name);
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index 4b4007b3083a..7b845ba9dff4 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -108,7 +108,7 @@ int show_interrupts(struct seq_file *p, void *v)
108 seq_printf(p, "%10u ", kstat_irqs(i)); 108 seq_printf(p, "%10u ", kstat_irqs(i));
109#else 109#else
110 for_each_online_cpu(j) 110 for_each_online_cpu(j)
111 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); 111 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
112#endif 112#endif
113 seq_printf(p, " %14s", irq_desc[i].chip->name); 113 seq_printf(p, " %14s", irq_desc[i].chip->name);
114 seq_printf(p, " %s", action->name); 114 seq_printf(p, " %s", action->name);
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c
index 56c64ccc9c21..50fdb5c16e0c 100644
--- a/arch/mn10300/kernel/irq.c
+++ b/arch/mn10300/kernel/irq.c
@@ -221,7 +221,7 @@ int show_interrupts(struct seq_file *p, void *v)
221 if (action) { 221 if (action) {
222 seq_printf(p, "%3d: ", i); 222 seq_printf(p, "%3d: ", i);
223 for_each_present_cpu(cpu) 223 for_each_present_cpu(cpu)
224 seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]); 224 seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
225 seq_printf(p, " %14s.%u", irq_desc[i].chip->name, 225 seq_printf(p, " %14s.%u", irq_desc[i].chip->name,
226 (GxICR(i) & GxICR_LEVEL) >> 226 (GxICR(i) & GxICR_LEVEL) >>
227 GxICR_LEVEL_SHIFT); 227 GxICR_LEVEL_SHIFT);
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index 29e70e16ede8..adfd617b4c18 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -185,7 +185,7 @@ int show_interrupts(struct seq_file *p, void *v)
185 seq_printf(p, "%3d: ", i); 185 seq_printf(p, "%3d: ", i);
186#ifdef CONFIG_SMP 186#ifdef CONFIG_SMP
187 for_each_online_cpu(j) 187 for_each_online_cpu(j)
188 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); 188 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
189#else 189#else
190 seq_printf(p, "%10u ", kstat_irqs(i)); 190 seq_printf(p, "%10u ", kstat_irqs(i));
191#endif 191#endif
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 23b8b5e36f98..17efb7118db1 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -190,7 +190,7 @@ int show_interrupts(struct seq_file *p, void *v)
190 seq_printf(p, "%3d: ", i); 190 seq_printf(p, "%3d: ", i);
191#ifdef CONFIG_SMP 191#ifdef CONFIG_SMP
192 for_each_online_cpu(j) 192 for_each_online_cpu(j)
193 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); 193 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
194#else 194#else
195 seq_printf(p, "%10u ", kstat_irqs(i)); 195 seq_printf(p, "%10u ", kstat_irqs(i));
196#endif /* CONFIG_SMP */ 196#endif /* CONFIG_SMP */
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 28c04dab2633..882e47080e74 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -237,8 +237,6 @@ extern int noirqdebug;
237 237
238static void handle_iic_irq(unsigned int irq, struct irq_desc *desc) 238static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
239{ 239{
240 const unsigned int cpu = smp_processor_id();
241
242 spin_lock(&desc->lock); 240 spin_lock(&desc->lock);
243 241
244 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); 242 desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
@@ -254,7 +252,7 @@ static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
254 goto out_eoi; 252 goto out_eoi;
255 } 253 }
256 254
257 kstat_cpu(cpu).irqs[irq]++; 255 kstat_incr_irqs_this_cpu(irq, desc);
258 256
259 /* Mark the IRQ currently in progress.*/ 257 /* Mark the IRQ currently in progress.*/
260 desc->status |= IRQ_INPROGRESS; 258 desc->status |= IRQ_INPROGRESS;
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index 90d63aefd275..3f1372eb0091 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -51,7 +51,7 @@ int show_interrupts(struct seq_file *p, void *v)
51 goto unlock; 51 goto unlock;
52 seq_printf(p, "%3d: ",i); 52 seq_printf(p, "%3d: ",i);
53 for_each_online_cpu(j) 53 for_each_online_cpu(j)
54 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); 54 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
55 seq_printf(p, " %14s", irq_desc[i].chip->name); 55 seq_printf(p, " %14s", irq_desc[i].chip->name);
56 seq_printf(p, "-%-8s", irq_desc[i].name); 56 seq_printf(p, "-%-8s", irq_desc[i].name);
57 seq_printf(p, " %s", action->name); 57 seq_printf(p, " %s", action->name);
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index 1c378d8e90c5..8ba064f08a6f 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -185,7 +185,7 @@ int show_interrupts(struct seq_file *p, void *v)
185 seq_printf(p, "%10u ", kstat_irqs(i)); 185 seq_printf(p, "%10u ", kstat_irqs(i));
186#else 186#else
187 for_each_online_cpu(j) 187 for_each_online_cpu(j)
188 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); 188 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
189#endif 189#endif
190 seq_printf(p, " %9s", irq_desc[i].chip->typename); 190 seq_printf(p, " %9s", irq_desc[i].chip->typename);
191 seq_printf(p, " %s", action->name); 191 seq_printf(p, " %s", action->name);
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c
index 2db3c2229b95..642562d83ec4 100644
--- a/arch/sparc/kernel/time_64.c
+++ b/arch/sparc/kernel/time_64.c
@@ -36,10 +36,10 @@
36#include <linux/clocksource.h> 36#include <linux/clocksource.h>
37#include <linux/of_device.h> 37#include <linux/of_device.h>
38#include <linux/platform_device.h> 38#include <linux/platform_device.h>
39#include <linux/irq.h>
39 40
40#include <asm/oplib.h> 41#include <asm/oplib.h>
41#include <asm/timer.h> 42#include <asm/timer.h>
42#include <asm/irq.h>
43#include <asm/io.h> 43#include <asm/io.h>
44#include <asm/prom.h> 44#include <asm/prom.h>
45#include <asm/starfire.h> 45#include <asm/starfire.h>
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 3d7aad09b171..336b61569072 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -42,7 +42,7 @@ int show_interrupts(struct seq_file *p, void *v)
42 seq_printf(p, "%10u ", kstat_irqs(i)); 42 seq_printf(p, "%10u ", kstat_irqs(i));
43#else 43#else
44 for_each_online_cpu(j) 44 for_each_online_cpu(j)
45 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); 45 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
46#endif 46#endif
47 seq_printf(p, " %14s", irq_desc[i].chip->typename); 47 seq_printf(p, " %14s", irq_desc[i].chip->typename);
48 seq_printf(p, " %s", action->name); 48 seq_printf(p, " %s", action->name);
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index bc2fbadff9f9..3a330a437c6f 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -165,6 +165,9 @@ config GENERIC_HARDIRQS
165 bool 165 bool
166 default y 166 default y
167 167
168config GENERIC_HARDIRQS_NO__DO_IRQ
169 def_bool y
170
168config GENERIC_IRQ_PROBE 171config GENERIC_IRQ_PROBE
169 bool 172 bool
170 default y 173 default y
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c
index 5fbcde59a92d..f3b66fba5b8f 100644
--- a/arch/xtensa/kernel/irq.c
+++ b/arch/xtensa/kernel/irq.c
@@ -99,7 +99,7 @@ int show_interrupts(struct seq_file *p, void *v)
99 seq_printf(p, "%10u ", kstat_irqs(i)); 99 seq_printf(p, "%10u ", kstat_irqs(i));
100#else 100#else
101 for_each_online_cpu(j) 101 for_each_online_cpu(j)
102 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); 102 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
103#endif 103#endif
104 seq_printf(p, " %14s", irq_desc[i].chip->typename); 104 seq_printf(p, " %14s", irq_desc[i].chip->typename);
105 seq_printf(p, " %s", action->name); 105 seq_printf(p, " %s", action->name);
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 7c13581ca9cd..7c43ae782b26 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -241,6 +241,10 @@
241#include <linux/percpu.h> 241#include <linux/percpu.h>
242#include <linux/cryptohash.h> 242#include <linux/cryptohash.h>
243 243
244#ifdef CONFIG_GENERIC_HARDIRQS
245# include <linux/irq.h>
246#endif
247
244#include <asm/processor.h> 248#include <asm/processor.h>
245#include <asm/uaccess.h> 249#include <asm/uaccess.h>
246#include <asm/irq.h> 250#include <asm/irq.h>
@@ -558,7 +562,7 @@ struct timer_rand_state {
558 unsigned dont_count_entropy:1; 562 unsigned dont_count_entropy:1;
559}; 563};
560 564
561#ifndef CONFIG_SPARSE_IRQ 565#ifndef CONFIG_GENERIC_HARDIRQS
562 566
563static struct timer_rand_state *irq_timer_state[NR_IRQS]; 567static struct timer_rand_state *irq_timer_state[NR_IRQS];
564 568
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index 45effc5726c0..b721c2fbe8f5 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -20,7 +20,7 @@ struct irq_2_iommu {
20 u8 irte_mask; 20 u8 irte_mask;
21}; 21};
22 22
23#ifdef CONFIG_SPARSE_IRQ 23#ifdef CONFIG_GENERIC_HARDIRQS
24static struct irq_2_iommu *get_one_free_irq_2_iommu(int cpu) 24static struct irq_2_iommu *get_one_free_irq_2_iommu(int cpu)
25{ 25{
26 struct irq_2_iommu *iommu; 26 struct irq_2_iommu *iommu;
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 9127f6b51a39..91658d076598 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -61,6 +61,17 @@
61 61
62typedef irqreturn_t (*irq_handler_t)(int, void *); 62typedef irqreturn_t (*irq_handler_t)(int, void *);
63 63
64/**
65 * struct irqaction - per interrupt action descriptor
66 * @handler: interrupt handler function
67 * @flags: flags (see IRQF_* above)
68 * @mask: no comment as it is useless and about to be removed
69 * @name: name of the device
70 * @dev_id: cookie to identify the device
71 * @next: pointer to the next irqaction for shared interrupts
72 * @irq: interrupt number
73 * @dir: pointer to the proc/irq/NN/name entry
74 */
64struct irqaction { 75struct irqaction {
65 irq_handler_t handler; 76 irq_handler_t handler;
66 unsigned long flags; 77 unsigned long flags;
@@ -462,6 +473,12 @@ static inline void init_irq_proc(void)
462} 473}
463#endif 474#endif
464 475
476#if defined(CONFIG_GENERIC_HARDIRQS) && defined(CONFIG_DEBUG_SHIRQ)
477extern void debug_poll_all_shared_irqs(void);
478#else
479static inline void debug_poll_all_shared_irqs(void) { }
480#endif
481
465int show_interrupts(struct seq_file *p, void *v); 482int show_interrupts(struct seq_file *p, void *v);
466 483
467struct irq_desc; 484struct irq_desc;
diff --git a/include/linux/irq.h b/include/linux/irq.h
index f899b502f186..6db939a575bd 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -160,12 +160,10 @@ struct irq_2_iommu;
160 */ 160 */
161struct irq_desc { 161struct irq_desc {
162 unsigned int irq; 162 unsigned int irq;
163#ifdef CONFIG_SPARSE_IRQ
164 struct timer_rand_state *timer_rand_state; 163 struct timer_rand_state *timer_rand_state;
165 unsigned int *kstat_irqs; 164 unsigned int *kstat_irqs;
166# ifdef CONFIG_INTR_REMAP 165#ifdef CONFIG_INTR_REMAP
167 struct irq_2_iommu *irq_2_iommu; 166 struct irq_2_iommu *irq_2_iommu;
168# endif
169#endif 167#endif
170 irq_flow_handler_t handle_irq; 168 irq_flow_handler_t handle_irq;
171 struct irq_chip *chip; 169 struct irq_chip *chip;
@@ -202,12 +200,6 @@ extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc
202extern struct irq_desc irq_desc[NR_IRQS]; 200extern struct irq_desc irq_desc[NR_IRQS];
203#else /* CONFIG_SPARSE_IRQ */ 201#else /* CONFIG_SPARSE_IRQ */
204extern struct irq_desc *move_irq_desc(struct irq_desc *old_desc, int cpu); 202extern struct irq_desc *move_irq_desc(struct irq_desc *old_desc, int cpu);
205
206#define kstat_irqs_this_cpu(DESC) \
207 ((DESC)->kstat_irqs[smp_processor_id()])
208#define kstat_incr_irqs_this_cpu(irqno, DESC) \
209 ((DESC)->kstat_irqs[smp_processor_id()]++)
210
211#endif /* CONFIG_SPARSE_IRQ */ 203#endif /* CONFIG_SPARSE_IRQ */
212 204
213extern struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu); 205extern struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu);
@@ -226,7 +218,6 @@ irq_remap_to_desc(unsigned int irq, struct irq_desc *desc)
226 * Migration helpers for obsolete names, they will go away: 218 * Migration helpers for obsolete names, they will go away:
227 */ 219 */
228#define hw_interrupt_type irq_chip 220#define hw_interrupt_type irq_chip
229typedef struct irq_chip hw_irq_controller;
230#define no_irq_type no_irq_chip 221#define no_irq_type no_irq_chip
231typedef struct irq_desc irq_desc_t; 222typedef struct irq_desc irq_desc_t;
232 223
@@ -236,6 +227,7 @@ typedef struct irq_desc irq_desc_t;
236#include <asm/hw_irq.h> 227#include <asm/hw_irq.h>
237 228
238extern int setup_irq(unsigned int irq, struct irqaction *new); 229extern int setup_irq(unsigned int irq, struct irqaction *new);
230extern void remove_irq(unsigned int irq, struct irqaction *act);
239 231
240#ifdef CONFIG_GENERIC_HARDIRQS 232#ifdef CONFIG_GENERIC_HARDIRQS
241 233
@@ -280,7 +272,7 @@ static inline int irq_balancing_disabled(unsigned int irq)
280} 272}
281 273
282/* Handle irq action chains: */ 274/* Handle irq action chains: */
283extern int handle_IRQ_event(unsigned int irq, struct irqaction *action); 275extern irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action);
284 276
285/* 277/*
286 * Built-in IRQ handlers for various IRQ types, 278 * Built-in IRQ handlers for various IRQ types,
@@ -325,7 +317,7 @@ static inline void generic_handle_irq(unsigned int irq)
325 317
326/* Handling of unhandled and spurious interrupts: */ 318/* Handling of unhandled and spurious interrupts: */
327extern void note_interrupt(unsigned int irq, struct irq_desc *desc, 319extern void note_interrupt(unsigned int irq, struct irq_desc *desc,
328 int action_ret); 320 irqreturn_t action_ret);
329 321
330/* Resending of interrupts :*/ 322/* Resending of interrupts :*/
331void check_irq_resend(struct irq_desc *desc, unsigned int irq); 323void check_irq_resend(struct irq_desc *desc, unsigned int irq);
diff --git a/include/linux/irqnr.h b/include/linux/irqnr.h
index 86af92e9e84c..52ebbb4b161d 100644
--- a/include/linux/irqnr.h
+++ b/include/linux/irqnr.h
@@ -28,13 +28,17 @@ extern struct irq_desc *irq_to_desc(unsigned int irq);
28# define for_each_irq_desc(irq, desc) \ 28# define for_each_irq_desc(irq, desc) \
29 for (irq = 0, desc = irq_to_desc(irq); irq < nr_irqs; \ 29 for (irq = 0, desc = irq_to_desc(irq); irq < nr_irqs; \
30 irq++, desc = irq_to_desc(irq)) \ 30 irq++, desc = irq_to_desc(irq)) \
31 if (desc) 31 if (!desc) \
32 ; \
33 else
32 34
33 35
34# define for_each_irq_desc_reverse(irq, desc) \ 36# define for_each_irq_desc_reverse(irq, desc) \
35 for (irq = nr_irqs - 1, desc = irq_to_desc(irq); irq >= 0; \ 37 for (irq = nr_irqs - 1, desc = irq_to_desc(irq); irq >= 0; \
36 irq--, desc = irq_to_desc(irq)) \ 38 irq--, desc = irq_to_desc(irq)) \
37 if (desc) 39 if (!desc) \
40 ; \
41 else
38 42
39#endif /* CONFIG_GENERIC_HARDIRQS */ 43#endif /* CONFIG_GENERIC_HARDIRQS */
40 44
diff --git a/include/linux/irqreturn.h b/include/linux/irqreturn.h
index 881883c2009d..c5584ca5b8c9 100644
--- a/include/linux/irqreturn.h
+++ b/include/linux/irqreturn.h
@@ -1,25 +1,17 @@
1/* irqreturn.h */
2#ifndef _LINUX_IRQRETURN_H 1#ifndef _LINUX_IRQRETURN_H
3#define _LINUX_IRQRETURN_H 2#define _LINUX_IRQRETURN_H
4 3
5/* 4/**
6 * For 2.4.x compatibility, 2.4.x can use 5 * enum irqreturn
7 * 6 * @IRQ_NONE interrupt was not from this device
8 * typedef void irqreturn_t; 7 * @IRQ_HANDLED interrupt was handled by this device
9 * #define IRQ_NONE
10 * #define IRQ_HANDLED
11 * #define IRQ_RETVAL(x)
12 *
13 * To mix old-style and new-style irq handler returns.
14 *
15 * IRQ_NONE means we didn't handle it.
16 * IRQ_HANDLED means that we did have a valid interrupt and handled it.
17 * IRQ_RETVAL(x) selects on the two depending on x being non-zero (for handled)
18 */ 8 */
19typedef int irqreturn_t; 9enum irqreturn {
10 IRQ_NONE,
11 IRQ_HANDLED,
12};
20 13
21#define IRQ_NONE (0) 14typedef enum irqreturn irqreturn_t;
22#define IRQ_HANDLED (1) 15#define IRQ_RETVAL(x) ((x) != IRQ_NONE)
23#define IRQ_RETVAL(x) ((x) != 0)
24 16
25#endif 17#endif
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
index 570d20413119..0c8b89f28a95 100644
--- a/include/linux/kernel_stat.h
+++ b/include/linux/kernel_stat.h
@@ -28,7 +28,7 @@ struct cpu_usage_stat {
28 28
29struct kernel_stat { 29struct kernel_stat {
30 struct cpu_usage_stat cpustat; 30 struct cpu_usage_stat cpustat;
31#ifndef CONFIG_SPARSE_IRQ 31#ifndef CONFIG_GENERIC_HARDIRQS
32 unsigned int irqs[NR_IRQS]; 32 unsigned int irqs[NR_IRQS];
33#endif 33#endif
34}; 34};
@@ -41,7 +41,7 @@ DECLARE_PER_CPU(struct kernel_stat, kstat);
41 41
42extern unsigned long long nr_context_switches(void); 42extern unsigned long long nr_context_switches(void);
43 43
44#ifndef CONFIG_SPARSE_IRQ 44#ifndef CONFIG_GENERIC_HARDIRQS
45#define kstat_irqs_this_cpu(irq) \ 45#define kstat_irqs_this_cpu(irq) \
46 (kstat_this_cpu.irqs[irq]) 46 (kstat_this_cpu.irqs[irq])
47 47
@@ -52,16 +52,19 @@ static inline void kstat_incr_irqs_this_cpu(unsigned int irq,
52{ 52{
53 kstat_this_cpu.irqs[irq]++; 53 kstat_this_cpu.irqs[irq]++;
54} 54}
55#endif
56
57 55
58#ifndef CONFIG_SPARSE_IRQ
59static inline unsigned int kstat_irqs_cpu(unsigned int irq, int cpu) 56static inline unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
60{ 57{
61 return kstat_cpu(cpu).irqs[irq]; 58 return kstat_cpu(cpu).irqs[irq];
62} 59}
63#else 60#else
61#include <linux/irq.h>
64extern unsigned int kstat_irqs_cpu(unsigned int irq, int cpu); 62extern unsigned int kstat_irqs_cpu(unsigned int irq, int cpu);
63#define kstat_irqs_this_cpu(DESC) \
64 ((DESC)->kstat_irqs[smp_processor_id()])
65#define kstat_incr_irqs_this_cpu(irqno, DESC) \
66 ((DESC)->kstat_irqs[smp_processor_id()]++)
67
65#endif 68#endif
66 69
67/* 70/*
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 7de11bd64dfe..03d0bed2b8d9 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -78,6 +78,7 @@ void dynamic_irq_cleanup(unsigned int irq)
78 desc->handle_irq = handle_bad_irq; 78 desc->handle_irq = handle_bad_irq;
79 desc->chip = &no_irq_chip; 79 desc->chip = &no_irq_chip;
80 desc->name = NULL; 80 desc->name = NULL;
81 clear_kstat_irqs(desc);
81 spin_unlock_irqrestore(&desc->lock, flags); 82 spin_unlock_irqrestore(&desc->lock, flags);
82} 83}
83 84
@@ -290,7 +291,8 @@ static inline void mask_ack_irq(struct irq_desc *desc, int irq)
290 desc->chip->mask_ack(irq); 291 desc->chip->mask_ack(irq);
291 else { 292 else {
292 desc->chip->mask(irq); 293 desc->chip->mask(irq);
293 desc->chip->ack(irq); 294 if (desc->chip->ack)
295 desc->chip->ack(irq);
294 } 296 }
295} 297}
296 298
@@ -476,7 +478,8 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
476 kstat_incr_irqs_this_cpu(irq, desc); 478 kstat_incr_irqs_this_cpu(irq, desc);
477 479
478 /* Start handling the irq */ 480 /* Start handling the irq */
479 desc->chip->ack(irq); 481 if (desc->chip->ack)
482 desc->chip->ack(irq);
480 desc = irq_remap_to_desc(irq, desc); 483 desc = irq_remap_to_desc(irq, desc);
481 484
482 /* Mark the IRQ currently in progress.*/ 485 /* Mark the IRQ currently in progress.*/
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 3aba8d12f328..f6cdda68e5c6 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -83,19 +83,21 @@ static struct irq_desc irq_desc_init = {
83 83
84void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr) 84void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr)
85{ 85{
86 unsigned long bytes;
87 char *ptr;
88 int node; 86 int node;
89 87 void *ptr;
90 /* Compute how many bytes we need per irq and allocate them */
91 bytes = nr * sizeof(unsigned int);
92 88
93 node = cpu_to_node(cpu); 89 node = cpu_to_node(cpu);
94 ptr = kzalloc_node(bytes, GFP_ATOMIC, node); 90 ptr = kzalloc_node(nr * sizeof(*desc->kstat_irqs), GFP_ATOMIC, node);
95 printk(KERN_DEBUG " alloc kstat_irqs on cpu %d node %d\n", cpu, node);
96 91
97 if (ptr) 92 /*
98 desc->kstat_irqs = (unsigned int *)ptr; 93 * don't overwite if can not get new one
94 * init_copy_kstat_irqs() could still use old one
95 */
96 if (ptr) {
97 printk(KERN_DEBUG " alloc kstat_irqs on cpu %d node %d\n",
98 cpu, node);
99 desc->kstat_irqs = ptr;
100 }
99} 101}
100 102
101static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu) 103static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu)
@@ -227,6 +229,7 @@ struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
227 } 229 }
228}; 230};
229 231
232static unsigned int kstat_irqs_all[NR_IRQS][NR_CPUS];
230int __init early_irq_init(void) 233int __init early_irq_init(void)
231{ 234{
232 struct irq_desc *desc; 235 struct irq_desc *desc;
@@ -238,8 +241,10 @@ int __init early_irq_init(void)
238 desc = irq_desc; 241 desc = irq_desc;
239 count = ARRAY_SIZE(irq_desc); 242 count = ARRAY_SIZE(irq_desc);
240 243
241 for (i = 0; i < count; i++) 244 for (i = 0; i < count; i++) {
242 desc[i].irq = i; 245 desc[i].irq = i;
246 desc[i].kstat_irqs = kstat_irqs_all[i];
247 }
243 248
244 return arch_early_irq_init(); 249 return arch_early_irq_init();
245} 250}
@@ -255,6 +260,11 @@ struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu)
255} 260}
256#endif /* !CONFIG_SPARSE_IRQ */ 261#endif /* !CONFIG_SPARSE_IRQ */
257 262
263void clear_kstat_irqs(struct irq_desc *desc)
264{
265 memset(desc->kstat_irqs, 0, nr_cpu_ids * sizeof(*(desc->kstat_irqs)));
266}
267
258/* 268/*
259 * What should we do if we get a hw irq event on an illegal vector? 269 * What should we do if we get a hw irq event on an illegal vector?
260 * Each architecture has to answer this themself. 270 * Each architecture has to answer this themself.
@@ -328,6 +338,8 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
328 irqreturn_t ret, retval = IRQ_NONE; 338 irqreturn_t ret, retval = IRQ_NONE;
329 unsigned int status = 0; 339 unsigned int status = 0;
330 340
341 WARN_ONCE(!in_irq(), "BUG: IRQ handler called from non-hardirq context!");
342
331 if (!(action->flags & IRQF_DISABLED)) 343 if (!(action->flags & IRQF_DISABLED))
332 local_irq_enable_in_hardirq(); 344 local_irq_enable_in_hardirq();
333 345
@@ -347,6 +359,11 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
347} 359}
348 360
349#ifndef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ 361#ifndef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ
362
363#ifdef CONFIG_ENABLE_WARN_DEPRECATED
364# warning __do_IRQ is deprecated. Please convert to proper flow handlers
365#endif
366
350/** 367/**
351 * __do_IRQ - original all in one highlevel IRQ handler 368 * __do_IRQ - original all in one highlevel IRQ handler
352 * @irq: the interrupt number 369 * @irq: the interrupt number
@@ -467,12 +484,10 @@ void early_init_irq_lock_class(void)
467 } 484 }
468} 485}
469 486
470#ifdef CONFIG_SPARSE_IRQ
471unsigned int kstat_irqs_cpu(unsigned int irq, int cpu) 487unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
472{ 488{
473 struct irq_desc *desc = irq_to_desc(irq); 489 struct irq_desc *desc = irq_to_desc(irq);
474 return desc ? desc->kstat_irqs[cpu] : 0; 490 return desc ? desc->kstat_irqs[cpu] : 0;
475} 491}
476#endif
477EXPORT_SYMBOL(kstat_irqs_cpu); 492EXPORT_SYMBOL(kstat_irqs_cpu);
478 493
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index e6d0a43cc125..b60950bf5a16 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -15,6 +15,7 @@ extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
15 15
16extern struct lock_class_key irq_desc_lock_class; 16extern struct lock_class_key irq_desc_lock_class;
17extern void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr); 17extern void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr);
18extern void clear_kstat_irqs(struct irq_desc *desc);
18extern spinlock_t sparse_irq_lock; 19extern spinlock_t sparse_irq_lock;
19extern struct irq_desc *irq_desc_ptrs[NR_IRQS]; 20extern struct irq_desc *irq_desc_ptrs[NR_IRQS];
20 21
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 291f03664552..ea119effe096 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -109,7 +109,7 @@ int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
109/* 109/*
110 * Generic version of the affinity autoselector. 110 * Generic version of the affinity autoselector.
111 */ 111 */
112int do_irq_select_affinity(unsigned int irq, struct irq_desc *desc) 112static int setup_affinity(unsigned int irq, struct irq_desc *desc)
113{ 113{
114 if (!irq_can_set_affinity(irq)) 114 if (!irq_can_set_affinity(irq))
115 return 0; 115 return 0;
@@ -133,7 +133,7 @@ set_affinity:
133 return 0; 133 return 0;
134} 134}
135#else 135#else
136static inline int do_irq_select_affinity(unsigned int irq, struct irq_desc *d) 136static inline int setup_affinity(unsigned int irq, struct irq_desc *d)
137{ 137{
138 return irq_select_affinity(irq); 138 return irq_select_affinity(irq);
139} 139}
@@ -149,14 +149,14 @@ int irq_select_affinity_usr(unsigned int irq)
149 int ret; 149 int ret;
150 150
151 spin_lock_irqsave(&desc->lock, flags); 151 spin_lock_irqsave(&desc->lock, flags);
152 ret = do_irq_select_affinity(irq, desc); 152 ret = setup_affinity(irq, desc);
153 spin_unlock_irqrestore(&desc->lock, flags); 153 spin_unlock_irqrestore(&desc->lock, flags);
154 154
155 return ret; 155 return ret;
156} 156}
157 157
158#else 158#else
159static inline int do_irq_select_affinity(int irq, struct irq_desc *desc) 159static inline int setup_affinity(unsigned int irq, struct irq_desc *desc)
160{ 160{
161 return 0; 161 return 0;
162} 162}
@@ -389,9 +389,9 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
389 * allocate special interrupts that are part of the architecture. 389 * allocate special interrupts that are part of the architecture.
390 */ 390 */
391static int 391static int
392__setup_irq(unsigned int irq, struct irq_desc * desc, struct irqaction *new) 392__setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
393{ 393{
394 struct irqaction *old, **p; 394 struct irqaction *old, **old_ptr;
395 const char *old_name = NULL; 395 const char *old_name = NULL;
396 unsigned long flags; 396 unsigned long flags;
397 int shared = 0; 397 int shared = 0;
@@ -423,8 +423,8 @@ __setup_irq(unsigned int irq, struct irq_desc * desc, struct irqaction *new)
423 * The following block of code has to be executed atomically 423 * The following block of code has to be executed atomically
424 */ 424 */
425 spin_lock_irqsave(&desc->lock, flags); 425 spin_lock_irqsave(&desc->lock, flags);
426 p = &desc->action; 426 old_ptr = &desc->action;
427 old = *p; 427 old = *old_ptr;
428 if (old) { 428 if (old) {
429 /* 429 /*
430 * Can't share interrupts unless both agree to and are 430 * Can't share interrupts unless both agree to and are
@@ -447,8 +447,8 @@ __setup_irq(unsigned int irq, struct irq_desc * desc, struct irqaction *new)
447 447
448 /* add new interrupt at end of irq queue */ 448 /* add new interrupt at end of irq queue */
449 do { 449 do {
450 p = &old->next; 450 old_ptr = &old->next;
451 old = *p; 451 old = *old_ptr;
452 } while (old); 452 } while (old);
453 shared = 1; 453 shared = 1;
454 } 454 }
@@ -488,7 +488,7 @@ __setup_irq(unsigned int irq, struct irq_desc * desc, struct irqaction *new)
488 desc->status |= IRQ_NO_BALANCING; 488 desc->status |= IRQ_NO_BALANCING;
489 489
490 /* Set default affinity mask once everything is setup */ 490 /* Set default affinity mask once everything is setup */
491 do_irq_select_affinity(irq, desc); 491 setup_affinity(irq, desc);
492 492
493 } else if ((new->flags & IRQF_TRIGGER_MASK) 493 } else if ((new->flags & IRQF_TRIGGER_MASK)
494 && (new->flags & IRQF_TRIGGER_MASK) 494 && (new->flags & IRQF_TRIGGER_MASK)
@@ -499,7 +499,7 @@ __setup_irq(unsigned int irq, struct irq_desc * desc, struct irqaction *new)
499 (int)(new->flags & IRQF_TRIGGER_MASK)); 499 (int)(new->flags & IRQF_TRIGGER_MASK));
500 } 500 }
501 501
502 *p = new; 502 *old_ptr = new;
503 503
504 /* Reset broken irq detection when installing new handler */ 504 /* Reset broken irq detection when installing new handler */
505 desc->irq_count = 0; 505 desc->irq_count = 0;
@@ -549,90 +549,117 @@ int setup_irq(unsigned int irq, struct irqaction *act)
549 549
550 return __setup_irq(irq, desc, act); 550 return __setup_irq(irq, desc, act);
551} 551}
552EXPORT_SYMBOL_GPL(setup_irq);
552 553
553/** 554 /*
554 * free_irq - free an interrupt 555 * Internal function to unregister an irqaction - used to free
555 * @irq: Interrupt line to free 556 * regular and special interrupts that are part of the architecture.
556 * @dev_id: Device identity to free
557 *
558 * Remove an interrupt handler. The handler is removed and if the
559 * interrupt line is no longer in use by any driver it is disabled.
560 * On a shared IRQ the caller must ensure the interrupt is disabled
561 * on the card it drives before calling this function. The function
562 * does not return until any executing interrupts for this IRQ
563 * have completed.
564 *
565 * This function must not be called from interrupt context.
566 */ 557 */
567void free_irq(unsigned int irq, void *dev_id) 558static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
568{ 559{
569 struct irq_desc *desc = irq_to_desc(irq); 560 struct irq_desc *desc = irq_to_desc(irq);
570 struct irqaction **p; 561 struct irqaction *action, **action_ptr;
571 unsigned long flags; 562 unsigned long flags;
572 563
573 WARN_ON(in_interrupt()); 564 WARN(in_interrupt(), "Trying to free IRQ %d from IRQ context!\n", irq);
574 565
575 if (!desc) 566 if (!desc)
576 return; 567 return NULL;
577 568
578 spin_lock_irqsave(&desc->lock, flags); 569 spin_lock_irqsave(&desc->lock, flags);
579 p = &desc->action; 570
571 /*
572 * There can be multiple actions per IRQ descriptor, find the right
573 * one based on the dev_id:
574 */
575 action_ptr = &desc->action;
580 for (;;) { 576 for (;;) {
581 struct irqaction *action = *p; 577 action = *action_ptr;
582 578
583 if (action) { 579 if (!action) {
584 struct irqaction **pp = p; 580 WARN(1, "Trying to free already-free IRQ %d\n", irq);
581 spin_unlock_irqrestore(&desc->lock, flags);
585 582
586 p = &action->next; 583 return NULL;
587 if (action->dev_id != dev_id) 584 }
588 continue;
589 585
590 /* Found it - now remove it from the list of entries */ 586 if (action->dev_id == dev_id)
591 *pp = action->next; 587 break;
588 action_ptr = &action->next;
589 }
592 590
593 /* Currently used only by UML, might disappear one day.*/ 591 /* Found it - now remove it from the list of entries: */
592 *action_ptr = action->next;
593
594 /* Currently used only by UML, might disappear one day: */
594#ifdef CONFIG_IRQ_RELEASE_METHOD 595#ifdef CONFIG_IRQ_RELEASE_METHOD
595 if (desc->chip->release) 596 if (desc->chip->release)
596 desc->chip->release(irq, dev_id); 597 desc->chip->release(irq, dev_id);
597#endif 598#endif
598 599
599 if (!desc->action) { 600 /* If this was the last handler, shut down the IRQ line: */
600 desc->status |= IRQ_DISABLED; 601 if (!desc->action) {
601 if (desc->chip->shutdown) 602 desc->status |= IRQ_DISABLED;
602 desc->chip->shutdown(irq); 603 if (desc->chip->shutdown)
603 else 604 desc->chip->shutdown(irq);
604 desc->chip->disable(irq); 605 else
605 } 606 desc->chip->disable(irq);
606 spin_unlock_irqrestore(&desc->lock, flags); 607 }
607 unregister_handler_proc(irq, action); 608 spin_unlock_irqrestore(&desc->lock, flags);
609
610 unregister_handler_proc(irq, action);
611
612 /* Make sure it's not being used on another CPU: */
613 synchronize_irq(irq);
608 614
609 /* Make sure it's not being used on another CPU */
610 synchronize_irq(irq);
611#ifdef CONFIG_DEBUG_SHIRQ
612 /*
613 * It's a shared IRQ -- the driver ought to be
614 * prepared for it to happen even now it's
615 * being freed, so let's make sure.... We do
616 * this after actually deregistering it, to
617 * make sure that a 'real' IRQ doesn't run in
618 * parallel with our fake
619 */
620 if (action->flags & IRQF_SHARED) {
621 local_irq_save(flags);
622 action->handler(irq, dev_id);
623 local_irq_restore(flags);
624 }
625#endif
626 kfree(action);
627 return;
628 }
629 printk(KERN_ERR "Trying to free already-free IRQ %d\n", irq);
630#ifdef CONFIG_DEBUG_SHIRQ 615#ifdef CONFIG_DEBUG_SHIRQ
631 dump_stack(); 616 /*
632#endif 617 * It's a shared IRQ -- the driver ought to be prepared for an IRQ
633 spin_unlock_irqrestore(&desc->lock, flags); 618 * event to happen even now it's being freed, so let's make sure that
634 return; 619 * is so by doing an extra call to the handler ....
620 *
621 * ( We do this after actually deregistering it, to make sure that a
622 * 'real' IRQ doesn't run in * parallel with our fake. )
623 */
624 if (action->flags & IRQF_SHARED) {
625 local_irq_save(flags);
626 action->handler(irq, dev_id);
627 local_irq_restore(flags);
635 } 628 }
629#endif
630 return action;
631}
632
633/**
634 * remove_irq - free an interrupt
635 * @irq: Interrupt line to free
636 * @act: irqaction for the interrupt
637 *
638 * Used to remove interrupts statically setup by the early boot process.
639 */
640void remove_irq(unsigned int irq, struct irqaction *act)
641{
642 __free_irq(irq, act->dev_id);
643}
644EXPORT_SYMBOL_GPL(remove_irq);
645
646/**
647 * free_irq - free an interrupt allocated with request_irq
648 * @irq: Interrupt line to free
649 * @dev_id: Device identity to free
650 *
651 * Remove an interrupt handler. The handler is removed and if the
652 * interrupt line is no longer in use by any driver it is disabled.
653 * On a shared IRQ the caller must ensure the interrupt is disabled
654 * on the card it drives before calling this function. The function
655 * does not return until any executing interrupts for this IRQ
656 * have completed.
657 *
658 * This function must not be called from interrupt context.
659 */
660void free_irq(unsigned int irq, void *dev_id)
661{
662 kfree(__free_irq(irq, dev_id));
636} 663}
637EXPORT_SYMBOL(free_irq); 664EXPORT_SYMBOL(free_irq);
638 665
@@ -679,11 +706,12 @@ int request_irq(unsigned int irq, irq_handler_t handler,
679 * the behavior is classified as "will not fix" so we need to 706 * the behavior is classified as "will not fix" so we need to
680 * start nudging drivers away from using that idiom. 707 * start nudging drivers away from using that idiom.
681 */ 708 */
682 if ((irqflags & (IRQF_SHARED|IRQF_DISABLED)) 709 if ((irqflags & (IRQF_SHARED|IRQF_DISABLED)) ==
683 == (IRQF_SHARED|IRQF_DISABLED)) 710 (IRQF_SHARED|IRQF_DISABLED)) {
684 pr_warning("IRQ %d/%s: IRQF_DISABLED is not " 711 pr_warning(
685 "guaranteed on shared IRQs\n", 712 "IRQ %d/%s: IRQF_DISABLED is not guaranteed on shared IRQs\n",
686 irq, devname); 713 irq, devname);
714 }
687 715
688#ifdef CONFIG_LOCKDEP 716#ifdef CONFIG_LOCKDEP
689 /* 717 /*
@@ -709,15 +737,13 @@ int request_irq(unsigned int irq, irq_handler_t handler,
709 if (!handler) 737 if (!handler)
710 return -EINVAL; 738 return -EINVAL;
711 739
712 action = kmalloc(sizeof(struct irqaction), GFP_ATOMIC); 740 action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);
713 if (!action) 741 if (!action)
714 return -ENOMEM; 742 return -ENOMEM;
715 743
716 action->handler = handler; 744 action->handler = handler;
717 action->flags = irqflags; 745 action->flags = irqflags;
718 cpus_clear(action->mask);
719 action->name = devname; 746 action->name = devname;
720 action->next = NULL;
721 action->dev_id = dev_id; 747 action->dev_id = dev_id;
722 748
723 retval = __setup_irq(irq, desc, action); 749 retval = __setup_irq(irq, desc, action);
diff --git a/kernel/irq/numa_migrate.c b/kernel/irq/numa_migrate.c
index acd88356ac76..aef18ab6b75b 100644
--- a/kernel/irq/numa_migrate.c
+++ b/kernel/irq/numa_migrate.c
@@ -17,16 +17,11 @@ static void init_copy_kstat_irqs(struct irq_desc *old_desc,
17 struct irq_desc *desc, 17 struct irq_desc *desc,
18 int cpu, int nr) 18 int cpu, int nr)
19{ 19{
20 unsigned long bytes;
21
22 init_kstat_irqs(desc, cpu, nr); 20 init_kstat_irqs(desc, cpu, nr);
23 21
24 if (desc->kstat_irqs != old_desc->kstat_irqs) { 22 if (desc->kstat_irqs != old_desc->kstat_irqs)
25 /* Compute how many bytes we need per irq and allocate them */ 23 memcpy(desc->kstat_irqs, old_desc->kstat_irqs,
26 bytes = nr * sizeof(unsigned int); 24 nr * sizeof(*desc->kstat_irqs));
27
28 memcpy(desc->kstat_irqs, old_desc->kstat_irqs, bytes);
29 }
30} 25}
31 26
32static void free_kstat_irqs(struct irq_desc *old_desc, struct irq_desc *desc) 27static void free_kstat_irqs(struct irq_desc *old_desc, struct irq_desc *desc)
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index dd364c11e56e..4d568294de3e 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -104,7 +104,7 @@ static int misrouted_irq(int irq)
104 return ok; 104 return ok;
105} 105}
106 106
107static void poll_spurious_irqs(unsigned long dummy) 107static void poll_all_shared_irqs(void)
108{ 108{
109 struct irq_desc *desc; 109 struct irq_desc *desc;
110 int i; 110 int i;
@@ -123,11 +123,23 @@ static void poll_spurious_irqs(unsigned long dummy)
123 123
124 try_one_irq(i, desc); 124 try_one_irq(i, desc);
125 } 125 }
126}
127
128static void poll_spurious_irqs(unsigned long dummy)
129{
130 poll_all_shared_irqs();
126 131
127 mod_timer(&poll_spurious_irq_timer, 132 mod_timer(&poll_spurious_irq_timer,
128 jiffies + POLL_SPURIOUS_IRQ_INTERVAL); 133 jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
129} 134}
130 135
136#ifdef CONFIG_DEBUG_SHIRQ
137void debug_poll_all_shared_irqs(void)
138{
139 poll_all_shared_irqs();
140}
141#endif
142
131/* 143/*
132 * If 99,900 of the previous 100,000 interrupts have not been handled 144 * If 99,900 of the previous 100,000 interrupts have not been handled
133 * then assume that the IRQ is stuck in some manner. Drop a diagnostic 145 * then assume that the IRQ is stuck in some manner. Drop a diagnostic