Merge branches 'irq/genirq', 'irq/sparseirq' and 'irq/urgent' into irq/core
Ingo Molnar [Fri, 13 Feb 2009 10:57:18 +0000 (11:57 +0100)]
33 files changed:
arch/alpha/kernel/irq.c
arch/alpha/kernel/irq_alpha.c
arch/arm/kernel/irq.c
arch/arm/mach-ns9xxx/irq.c
arch/avr32/kernel/irq.c
arch/blackfin/kernel/irqchip.c
arch/cris/kernel/irq.c
arch/frv/kernel/irq.c
arch/h8300/kernel/irq.c
arch/ia64/kernel/irq.c
arch/m32r/kernel/irq.c
arch/mips/kernel/irq.c
arch/mn10300/kernel/irq.c
arch/parisc/kernel/irq.c
arch/powerpc/kernel/irq.c
arch/powerpc/platforms/cell/interrupt.c
arch/sh/kernel/irq.c
arch/sparc/kernel/irq_64.c
arch/sparc/kernel/time_64.c
arch/um/kernel/irq.c
arch/xtensa/kernel/irq.c
drivers/char/random.c
drivers/pci/intr_remapping.c
include/linux/interrupt.h
include/linux/irq.h
include/linux/irqnr.h
include/linux/kernel_stat.h
kernel/irq/chip.c
kernel/irq/handle.c
kernel/irq/internals.h
kernel/irq/manage.c
kernel/irq/numa_migrate.c
kernel/irq/spurious.c

index 703731a..d3812eb 100644 (file)
@@ -90,7 +90,7 @@ show_interrupts(struct seq_file *p, void *v)
                seq_printf(p, "%10u ", kstat_irqs(irq));
 #else
                for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", kstat_cpu(j).irqs[irq]);
+                       seq_printf(p, "%10u ", kstat_irqs_cpu(irq, j));
 #endif
                seq_printf(p, " %14s", irq_desc[irq].chip->typename);
                seq_printf(p, "  %c%s",
index e16aeb6..67c19f8 100644 (file)
@@ -64,7 +64,7 @@ do_entInt(unsigned long type, unsigned long vector,
                smp_percpu_timer_interrupt(regs);
                cpu = smp_processor_id();
                if (cpu != boot_cpuid) {
-                       kstat_cpu(cpu).irqs[RTC_IRQ]++;
+                       kstat_incr_irqs_this_cpu(RTC_IRQ, irq_to_desc(RTC_IRQ));
                } else {
                        handle_irq(RTC_IRQ);
                }
index 363db18..7296f04 100644 (file)
@@ -76,7 +76,7 @@ int show_interrupts(struct seq_file *p, void *v)
 
                seq_printf(p, "%3d: ", i);
                for_each_present_cpu(cpu)
-                       seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
+                       seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
                seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
                seq_printf(p, "  %s", action->name);
                for (action = action->next; action; action = action->next)
index 22e0eb6..feb0e54 100644 (file)
@@ -63,7 +63,6 @@ static struct irq_chip ns9xxx_chip = {
 #else
 static void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
 {
-       unsigned int cpu = smp_processor_id();
        struct irqaction *action;
        irqreturn_t action_ret;
 
@@ -72,7 +71,7 @@ static void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
        BUG_ON(desc->status & IRQ_INPROGRESS);
 
        desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
-       kstat_cpu(cpu).irqs[irq]++;
+       kstat_incr_irqs_this_cpu(irq, desc);
 
        action = desc->action;
        if (unlikely(!action || (desc->status & IRQ_DISABLED)))
index a8e767d..9f57222 100644 (file)
@@ -58,7 +58,7 @@ int show_interrupts(struct seq_file *p, void *v)
 
                seq_printf(p, "%3d: ", i);
                for_each_online_cpu(cpu)
-                       seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
+                       seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
                seq_printf(p, " %8s", irq_desc[i].chip->name ? : "-");
                seq_printf(p, "  %s", action->name);
                for (action = action->next; action; action = action->next)
index 75724ee..2d395c9 100644 (file)
@@ -83,7 +83,7 @@ int show_interrupts(struct seq_file *p, void *v)
                        goto skip;
                seq_printf(p, "%3d: ", i);
                for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+                       seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
                seq_printf(p, " %8s", irq_desc[i].chip->name);
                seq_printf(p, "  %s", action->name);
                for (action = action->next; action; action = action->next)
index 2dfac8c..7f642fc 100644 (file)
@@ -66,7 +66,7 @@ int show_interrupts(struct seq_file *p, void *v)
                seq_printf(p, "%10u ", kstat_irqs(i));
 #else
                for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+                       seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #endif
                seq_printf(p, " %14s", irq_desc[i].chip->typename);
                seq_printf(p, "  %s", action->name);
index 73abae7..af3e824 100644 (file)
@@ -74,7 +74,7 @@ int show_interrupts(struct seq_file *p, void *v)
                if (action) {
                        seq_printf(p, "%3d: ", i);
                        for_each_present_cpu(cpu)
-                               seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
+                               seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
                        seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
                        seq_printf(p, "  %s", action->name);
                        for (action = action->next;
index ef4f004..74f8dd7 100644 (file)
@@ -183,7 +183,7 @@ asmlinkage void do_IRQ(int irq)
 #if defined(CONFIG_PROC_FS)
 int show_interrupts(struct seq_file *p, void *v)
 {
-       int i = *(loff_t *) v, j;
+       int i = *(loff_t *) v;
        struct irqaction * action;
        unsigned long flags;
 
@@ -196,7 +196,7 @@ int show_interrupts(struct seq_file *p, void *v)
                if (!action)
                        goto unlock;
                seq_printf(p, "%3d: ",i);
-               seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+               seq_printf(p, "%10u ", kstat_irqs(i));
                seq_printf(p, " %14s", irq_desc[i].chip->name);
                seq_printf(p, "-%-8s", irq_desc[i].name);
                seq_printf(p, "  %s", action->name);
index a58f64c..4f59661 100644 (file)
@@ -80,7 +80,7 @@ int show_interrupts(struct seq_file *p, void *v)
                seq_printf(p, "%10u ", kstat_irqs(i));
 #else
                for_each_online_cpu(j) {
-                       seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+                       seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
                }
 #endif
                seq_printf(p, " %14s", irq_desc[i].chip->name);
index 2aeae46..8dfd31e 100644 (file)
@@ -49,7 +49,7 @@ int show_interrupts(struct seq_file *p, void *v)
                seq_printf(p, "%10u ", kstat_irqs(i));
 #else
                for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+                       seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #endif
                seq_printf(p, " %14s", irq_desc[i].chip->typename);
                seq_printf(p, "  %s", action->name);
index a0ff2b6..7c2dafa 100644 (file)
@@ -108,7 +108,7 @@ int show_interrupts(struct seq_file *p, void *v)
                seq_printf(p, "%10u ", kstat_irqs(i));
 #else
                for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+                       seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #endif
                seq_printf(p, " %14s", irq_desc[i].chip->name);
                seq_printf(p, "-%-8s", irq_desc[i].name);
index 56c64cc..50fdb5c 100644 (file)
@@ -221,7 +221,7 @@ int show_interrupts(struct seq_file *p, void *v)
                if (action) {
                        seq_printf(p, "%3d: ", i);
                        for_each_present_cpu(cpu)
-                               seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
+                               seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
                        seq_printf(p, " %14s.%u", irq_desc[i].chip->name,
                                   (GxICR(i) & GxICR_LEVEL) >>
                                   GxICR_LEVEL_SHIFT);
index ac2c822..704341b 100644 (file)
@@ -183,7 +183,7 @@ int show_interrupts(struct seq_file *p, void *v)
                seq_printf(p, "%3d: ", i);
 #ifdef CONFIG_SMP
                for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+                       seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #else
                seq_printf(p, "%10u ", kstat_irqs(i));
 #endif
index 23b8b5e..17efb71 100644 (file)
@@ -190,7 +190,7 @@ int show_interrupts(struct seq_file *p, void *v)
                seq_printf(p, "%3d: ", i);
 #ifdef CONFIG_SMP
                for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+                       seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #else
                seq_printf(p, "%10u ", kstat_irqs(i));
 #endif /* CONFIG_SMP */
index 28c04da..1f0d774 100644 (file)
@@ -254,7 +254,7 @@ static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
                goto out_eoi;
        }
 
-       kstat_cpu(cpu).irqs[irq]++;
+       kstat_incr_irqs_this_cpu(irq, desc);
 
        /* Mark the IRQ currently in progress.*/
        desc->status |= IRQ_INPROGRESS;
index 64b7690..0080a16 100644 (file)
@@ -51,7 +51,7 @@ int show_interrupts(struct seq_file *p, void *v)
                        goto unlock;
                seq_printf(p, "%3d: ",i);
                for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+                       seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
                seq_printf(p, " %14s", irq_desc[i].chip->name);
                seq_printf(p, "-%-8s", irq_desc[i].name);
                seq_printf(p, "  %s", action->name);
index e289376..e531383 100644 (file)
@@ -185,7 +185,7 @@ int show_interrupts(struct seq_file *p, void *v)
                seq_printf(p, "%10u ", kstat_irqs(i));
 #else
                for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+                       seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #endif
                seq_printf(p, " %9s", irq_desc[i].chip->typename);
                seq_printf(p, "  %s", action->name);
index 2db3c22..642562d 100644 (file)
 #include <linux/clocksource.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/irq.h>
 
 #include <asm/oplib.h>
 #include <asm/timer.h>
-#include <asm/irq.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/starfire.h>
index 3d7aad0..336b615 100644 (file)
@@ -42,7 +42,7 @@ int show_interrupts(struct seq_file *p, void *v)
                seq_printf(p, "%10u ", kstat_irqs(i));
 #else
                for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+                       seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #endif
                seq_printf(p, " %14s", irq_desc[i].chip->typename);
                seq_printf(p, "  %s", action->name);
index 5fbcde5..f3b66fb 100644 (file)
@@ -99,7 +99,7 @@ int show_interrupts(struct seq_file *p, void *v)
                seq_printf(p, "%10u ", kstat_irqs(i));
 #else
                for_each_online_cpu(j)
-                       seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+                       seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
 #endif
                seq_printf(p, " %14s", irq_desc[i].chip->typename);
                seq_printf(p, "  %s", action->name);
index 7c13581..7c43ae7 100644 (file)
 #include <linux/percpu.h>
 #include <linux/cryptohash.h>
 
+#ifdef CONFIG_GENERIC_HARDIRQS
+# include <linux/irq.h>
+#endif
+
 #include <asm/processor.h>
 #include <asm/uaccess.h>
 #include <asm/irq.h>
@@ -558,7 +562,7 @@ struct timer_rand_state {
        unsigned dont_count_entropy:1;
 };
 
-#ifndef CONFIG_SPARSE_IRQ
+#ifndef CONFIG_GENERIC_HARDIRQS
 
 static struct timer_rand_state *irq_timer_state[NR_IRQS];
 
index f78371b..3d60413 100644 (file)
@@ -20,7 +20,7 @@ struct irq_2_iommu {
        u8  irte_mask;
 };
 
-#ifdef CONFIG_SPARSE_IRQ
+#ifdef CONFIG_GENERIC_HARDIRQS
 static struct irq_2_iommu *get_one_free_irq_2_iommu(int cpu)
 {
        struct irq_2_iommu *iommu;
index 9127f6b..468e3a2 100644 (file)
@@ -462,6 +462,12 @@ static inline void init_irq_proc(void)
 }
 #endif
 
+#if defined(CONFIG_GENERIC_HARDIRQS) && defined(CONFIG_DEBUG_SHIRQ)
+extern void debug_poll_all_shared_irqs(void);
+#else
+static inline void debug_poll_all_shared_irqs(void) { }
+#endif
+
 int show_interrupts(struct seq_file *p, void *v);
 
 struct irq_desc;
index f899b50..48901e9 100644 (file)
@@ -160,12 +160,10 @@ struct irq_2_iommu;
  */
 struct irq_desc {
        unsigned int            irq;
-#ifdef CONFIG_SPARSE_IRQ
        struct timer_rand_state *timer_rand_state;
        unsigned int            *kstat_irqs;
-# ifdef CONFIG_INTR_REMAP
+#ifdef CONFIG_INTR_REMAP
        struct irq_2_iommu      *irq_2_iommu;
-# endif
 #endif
        irq_flow_handler_t      handle_irq;
        struct irq_chip         *chip;
@@ -202,12 +200,6 @@ extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc
 extern struct irq_desc irq_desc[NR_IRQS];
 #else /* CONFIG_SPARSE_IRQ */
 extern struct irq_desc *move_irq_desc(struct irq_desc *old_desc, int cpu);
-
-#define kstat_irqs_this_cpu(DESC) \
-       ((DESC)->kstat_irqs[smp_processor_id()])
-#define kstat_incr_irqs_this_cpu(irqno, DESC) \
-       ((DESC)->kstat_irqs[smp_processor_id()]++)
-
 #endif /* CONFIG_SPARSE_IRQ */
 
 extern struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu);
index 86af92e..52ebbb4 100644 (file)
@@ -28,13 +28,17 @@ extern struct irq_desc *irq_to_desc(unsigned int irq);
 # define for_each_irq_desc(irq, desc)                                  \
        for (irq = 0, desc = irq_to_desc(irq); irq < nr_irqs;           \
             irq++, desc = irq_to_desc(irq))                            \
-               if (desc)
+               if (!desc)                                              \
+                       ;                                               \
+               else
 
 
 # define for_each_irq_desc_reverse(irq, desc)                          \
        for (irq = nr_irqs - 1, desc = irq_to_desc(irq); irq >= 0;      \
             irq--, desc = irq_to_desc(irq))                            \
-               if (desc)
+               if (!desc)                                              \
+                       ;                                               \
+               else
 
 #endif /* CONFIG_GENERIC_HARDIRQS */
 
index 570d204..0c8b89f 100644 (file)
@@ -28,7 +28,7 @@ struct cpu_usage_stat {
 
 struct kernel_stat {
        struct cpu_usage_stat   cpustat;
-#ifndef CONFIG_SPARSE_IRQ
+#ifndef CONFIG_GENERIC_HARDIRQS
        unsigned int irqs[NR_IRQS];
 #endif
 };
@@ -41,7 +41,7 @@ DECLARE_PER_CPU(struct kernel_stat, kstat);
 
 extern unsigned long long nr_context_switches(void);
 
-#ifndef CONFIG_SPARSE_IRQ
+#ifndef CONFIG_GENERIC_HARDIRQS
 #define kstat_irqs_this_cpu(irq) \
        (kstat_this_cpu.irqs[irq])
 
@@ -52,16 +52,19 @@ static inline void kstat_incr_irqs_this_cpu(unsigned int irq,
 {
        kstat_this_cpu.irqs[irq]++;
 }
-#endif
-
 
-#ifndef CONFIG_SPARSE_IRQ
 static inline unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
 {
        return kstat_cpu(cpu).irqs[irq];
 }
 #else
+#include <linux/irq.h>
 extern unsigned int kstat_irqs_cpu(unsigned int irq, int cpu);
+#define kstat_irqs_this_cpu(DESC) \
+       ((DESC)->kstat_irqs[smp_processor_id()])
+#define kstat_incr_irqs_this_cpu(irqno, DESC) \
+       ((DESC)->kstat_irqs[smp_processor_id()]++)
+
 #endif
 
 /*
index 7de11bd..03d0bed 100644 (file)
@@ -78,6 +78,7 @@ void dynamic_irq_cleanup(unsigned int irq)
        desc->handle_irq = handle_bad_irq;
        desc->chip = &no_irq_chip;
        desc->name = NULL;
+       clear_kstat_irqs(desc);
        spin_unlock_irqrestore(&desc->lock, flags);
 }
 
@@ -290,7 +291,8 @@ static inline void mask_ack_irq(struct irq_desc *desc, int irq)
                desc->chip->mask_ack(irq);
        else {
                desc->chip->mask(irq);
-               desc->chip->ack(irq);
+               if (desc->chip->ack)
+                       desc->chip->ack(irq);
        }
 }
 
@@ -476,7 +478,8 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
        kstat_incr_irqs_this_cpu(irq, desc);
 
        /* Start handling the irq */
-       desc->chip->ack(irq);
+       if (desc->chip->ack)
+               desc->chip->ack(irq);
        desc = irq_remap_to_desc(irq, desc);
 
        /* Mark the IRQ currently in progress.*/
index 3aba8d1..759b8b0 100644 (file)
@@ -83,19 +83,21 @@ static struct irq_desc irq_desc_init = {
 
 void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr)
 {
-       unsigned long bytes;
-       char *ptr;
        int node;
-
-       /* Compute how many bytes we need per irq and allocate them */
-       bytes = nr * sizeof(unsigned int);
+       void *ptr;
 
        node = cpu_to_node(cpu);
-       ptr = kzalloc_node(bytes, GFP_ATOMIC, node);
-       printk(KERN_DEBUG "  alloc kstat_irqs on cpu %d node %d\n", cpu, node);
+       ptr = kzalloc_node(nr * sizeof(*desc->kstat_irqs), GFP_ATOMIC, node);
 
-       if (ptr)
-               desc->kstat_irqs = (unsigned int *)ptr;
+       /*
+        * don't overwite if can not get new one
+        * init_copy_kstat_irqs() could still use old one
+        */
+       if (ptr) {
+               printk(KERN_DEBUG "  alloc kstat_irqs on cpu %d node %d\n",
+                        cpu, node);
+               desc->kstat_irqs = ptr;
+       }
 }
 
 static 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 = {
        }
 };
 
+static unsigned int kstat_irqs_all[NR_IRQS][NR_CPUS];
 int __init early_irq_init(void)
 {
        struct irq_desc *desc;
@@ -238,8 +241,10 @@ int __init early_irq_init(void)
        desc = irq_desc;
        count = ARRAY_SIZE(irq_desc);
 
-       for (i = 0; i < count; i++)
+       for (i = 0; i < count; i++) {
                desc[i].irq = i;
+               desc[i].kstat_irqs = kstat_irqs_all[i];
+       }
 
        return arch_early_irq_init();
 }
@@ -255,6 +260,11 @@ struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu)
 }
 #endif /* !CONFIG_SPARSE_IRQ */
 
+void clear_kstat_irqs(struct irq_desc *desc)
+{
+       memset(desc->kstat_irqs, 0, nr_cpu_ids * sizeof(*(desc->kstat_irqs)));
+}
+
 /*
  * What should we do if we get a hw irq event on an illegal vector?
  * Each architecture has to answer this themself.
@@ -467,12 +477,10 @@ void early_init_irq_lock_class(void)
        }
 }
 
-#ifdef CONFIG_SPARSE_IRQ
 unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
 {
        struct irq_desc *desc = irq_to_desc(irq);
        return desc ? desc->kstat_irqs[cpu] : 0;
 }
-#endif
 EXPORT_SYMBOL(kstat_irqs_cpu);
 
index e6d0a43..b60950b 100644 (file)
@@ -15,6 +15,7 @@ extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
 
 extern struct lock_class_key irq_desc_lock_class;
 extern void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr);
+extern void clear_kstat_irqs(struct irq_desc *desc);
 extern spinlock_t sparse_irq_lock;
 extern struct irq_desc *irq_desc_ptrs[NR_IRQS];
 
index 291f036..cbc3828 100644 (file)
@@ -109,7 +109,7 @@ int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
 /*
  * Generic version of the affinity autoselector.
  */
-int do_irq_select_affinity(unsigned int irq, struct irq_desc *desc)
+static int setup_affinity(unsigned int irq, struct irq_desc *desc)
 {
        if (!irq_can_set_affinity(irq))
                return 0;
@@ -133,7 +133,7 @@ set_affinity:
        return 0;
 }
 #else
-static inline int do_irq_select_affinity(unsigned int irq, struct irq_desc *d)
+static inline int setup_affinity(unsigned int irq, struct irq_desc *d)
 {
        return irq_select_affinity(irq);
 }
@@ -149,14 +149,14 @@ int irq_select_affinity_usr(unsigned int irq)
        int ret;
 
        spin_lock_irqsave(&desc->lock, flags);
-       ret = do_irq_select_affinity(irq, desc);
+       ret = setup_affinity(irq, desc);
        spin_unlock_irqrestore(&desc->lock, flags);
 
        return ret;
 }
 
 #else
-static inline int do_irq_select_affinity(int irq, struct irq_desc *desc)
+static inline int setup_affinity(unsigned int irq, struct irq_desc *desc)
 {
        return 0;
 }
@@ -488,7 +488,7 @@ __setup_irq(unsigned int irq, struct irq_desc * desc, struct irqaction *new)
                        desc->status |= IRQ_NO_BALANCING;
 
                /* Set default affinity mask once everything is setup */
-               do_irq_select_affinity(irq, desc);
+               setup_affinity(irq, desc);
 
        } else if ((new->flags & IRQF_TRIGGER_MASK)
                        && (new->flags & IRQF_TRIGGER_MASK)
@@ -709,7 +709,7 @@ int request_irq(unsigned int irq, irq_handler_t handler,
        if (!handler)
                return -EINVAL;
 
-       action = kmalloc(sizeof(struct irqaction), GFP_ATOMIC);
+       action = kmalloc(sizeof(struct irqaction), GFP_KERNEL);
        if (!action)
                return -ENOMEM;
 
index acd8835..aef18ab 100644 (file)
@@ -17,16 +17,11 @@ static void init_copy_kstat_irqs(struct irq_desc *old_desc,
                                 struct irq_desc *desc,
                                 int cpu, int nr)
 {
-       unsigned long bytes;
-
        init_kstat_irqs(desc, cpu, nr);
 
-       if (desc->kstat_irqs != old_desc->kstat_irqs) {
-               /* Compute how many bytes we need per irq and allocate them */
-               bytes = nr * sizeof(unsigned int);
-
-               memcpy(desc->kstat_irqs, old_desc->kstat_irqs, bytes);
-       }
+       if (desc->kstat_irqs != old_desc->kstat_irqs)
+               memcpy(desc->kstat_irqs, old_desc->kstat_irqs,
+                        nr * sizeof(*desc->kstat_irqs));
 }
 
 static void free_kstat_irqs(struct irq_desc *old_desc, struct irq_desc *desc)
index dd364c1..4d56829 100644 (file)
@@ -104,7 +104,7 @@ static int misrouted_irq(int irq)
        return ok;
 }
 
-static void poll_spurious_irqs(unsigned long dummy)
+static void poll_all_shared_irqs(void)
 {
        struct irq_desc *desc;
        int i;
@@ -123,11 +123,23 @@ static void poll_spurious_irqs(unsigned long dummy)
 
                try_one_irq(i, desc);
        }
+}
+
+static void poll_spurious_irqs(unsigned long dummy)
+{
+       poll_all_shared_irqs();
 
        mod_timer(&poll_spurious_irq_timer,
                  jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
 }
 
+#ifdef CONFIG_DEBUG_SHIRQ
+void debug_poll_all_shared_irqs(void)
+{
+       poll_all_shared_irqs();
+}
+#endif
+
 /*
  * If 99,900 of the previous 100,000 interrupts have not been handled
  * then assume that the IRQ is stuck in some manner. Drop a diagnostic