Merge branches 'irq/genirq', 'irq/sparseirq' and 'irq/urgent' into irq/core
authorIngo Molnar <mingo@elte.hu>
Fri, 13 Feb 2009 10:57:18 +0000 (11:57 +0100)
committerIngo Molnar <mingo@elte.hu>
Fri, 13 Feb 2009 10:57:18 +0000 (11:57 +0100)
1  2  3  4 
arch/arm/kernel/irq.c
arch/blackfin/kernel/irqchip.c
arch/mips/kernel/irq.c
arch/sparc/kernel/irq_64.c
arch/sparc/kernel/time_64.c
kernel/irq/chip.c
kernel/irq/handle.c
kernel/irq/manage.c
kernel/irq/numa_migrate.c

diff --combined arch/arm/kernel/irq.c
index 363db186cb93334791588db5b2158e6f295c5c54,7141cee1fab71e8b131d03e0d8e6dbfc043dbb85,a285e4a636a64ff5d1ab23da361c6e786339672b,363db186cb93334791588db5b2158e6f295c5c54..7296f041628663f2c88258b90f2e411d99d3a4aa
@@@@@ -76,7 -76,7 -76,7 -76,7 +76,7 @@@@@ int show_interrupts(struct seq_file *p
    
                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)
@@@@@ -101,7 -101,7 -101,7 -101,7 +101,7 @@@@@ unlock
    /* Handle bad interrupts */
    static struct irq_desc bad_irq_desc = {
        .handle_irq = handle_bad_irq,
 --     .lock = SPIN_LOCK_UNLOCKED
 ++     .lock = __SPIN_LOCK_UNLOCKED(bad_irq_desc.lock),
    };
    
    /*
index 75724eee6494c65c87545e14682f8cfe213877dd,ab8209cbbad0368f1ebc2bc252c7532478ec6b5a,a4e12d1b3798092aa7fd450d68d373763e9af47b,75724eee6494c65c87545e14682f8cfe213877dd..2d395c9005c50e6147d1755a7cc7619a92316e85
    #include <linux/interrupt.h>
    #include <linux/irq.h>
    #include <asm/trace.h>
 ++ #include <asm/pda.h>
    
    static atomic_t irq_err_count;
    static spinlock_t irq_controller_lock;
@@@@@ -83,7 -82,7 -82,7 -83,7 +83,7 @@@@@ int show_interrupts(struct seq_file *p
                        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)
                seq_putc(p, '\n');
     skip:
                spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 --     } else if (i == NR_IRQS)
 ++     } else if (i == NR_IRQS) {
 ++             seq_printf(p, "NMI: ");
 ++             for_each_online_cpu(j)
 ++                     seq_printf(p, "%10u ", cpu_pda[j].__nmi_count);
 ++             seq_printf(p, "     CORE  Non Maskable Interrupt\n");
                seq_printf(p, "Err: %10u\n",  atomic_read(&irq_err_count));
 ++     }
        return 0;
    }
    
diff --combined arch/mips/kernel/irq.c
index a0ff2b66e22b453f23d909959d3c37694cd5fd80,a0ff2b66e22b453f23d909959d3c37694cd5fd80,7b845ba9dff4cf565394393dbb1e24f497e5aed4,a0ff2b66e22b453f23d909959d3c37694cd5fd80..7c2dafa0f584c4e7a6a82069355c3779ba09e2a1
@@@@@ -108,10 -108,10 -108,9 -108,10 +108,10 @@@@@ int show_interrupts(struct seq_file *p
                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);
                seq_printf(p, "  %s", action->name);
    
                for (action=action->next; action; action = action->next)
index e289376198eb2be4e722b5cbf1a31d440c580631,cab8e02868716d691a38b9bad239ec754dd39134,2e98bef507817e9ac6239d294c4015a7577ce22a,e289376198eb2be4e722b5cbf1a31d440c580631..e531383654906b884853d0af4e9cdc1eb7469347
@@@@@ -185,7 -185,7 -185,7 -185,7 +185,7 @@@@@ int show_interrupts(struct seq_file *p
                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);
                seq_putc(p, '\n');
    skip:
                spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 ++     } else if (i == NR_IRQS) {
 ++             seq_printf(p, "NMI: ");
 ++             for_each_online_cpu(j)
 ++                     seq_printf(p, "%10u ", cpu_data(j).__nmi_count);
 ++             seq_printf(p, "     Non-maskable interrupts\n");
        }
        return 0;
    }
@@@@@ -783,6 -778,69 -778,69 -783,6 +783,6 @@@@@ void do_softirq(void
        local_irq_restore(flags);
    }
    
 -- static void unhandled_perf_irq(struct pt_regs *regs)
 -- {
 --     unsigned long pcr, pic;
 -- 
 --     read_pcr(pcr);
 --     read_pic(pic);
 -- 
 --     write_pcr(0);
 -- 
 --     printk(KERN_EMERG "CPU %d: Got unexpected perf counter IRQ.\n",
 --            smp_processor_id());
 --     printk(KERN_EMERG "CPU %d: PCR[%016lx] PIC[%016lx]\n",
 --            smp_processor_id(), pcr, pic);
 -- }
 -- 
 -- /* Almost a direct copy of the powerpc PMC code.  */
 -- static DEFINE_SPINLOCK(perf_irq_lock);
 -- static void *perf_irq_owner_caller; /* mostly for debugging */
 -- static void (*perf_irq)(struct pt_regs *regs) = unhandled_perf_irq;
 -- 
 -- /* Invoked from level 15 PIL handler in trap table.  */
 -- void perfctr_irq(int irq, struct pt_regs *regs)
 -- {
 --     clear_softint(1 << irq);
 --     perf_irq(regs);
 -- }
 -- 
 -- int register_perfctr_intr(void (*handler)(struct pt_regs *))
 -- {
 --     int ret;
 -- 
 --     if (!handler)
 --             return -EINVAL;
 -- 
 --     spin_lock(&perf_irq_lock);
 --     if (perf_irq != unhandled_perf_irq) {
 --             printk(KERN_WARNING "register_perfctr_intr: "
 --                    "perf IRQ busy (reserved by caller %p)\n",
 --                    perf_irq_owner_caller);
 --             ret = -EBUSY;
 --             goto out;
 --     }
 -- 
 --     perf_irq_owner_caller = __builtin_return_address(0);
 --     perf_irq = handler;
 -- 
 --     ret = 0;
 -- out:
 --     spin_unlock(&perf_irq_lock);
 -- 
 --     return ret;
 -- }
 -- EXPORT_SYMBOL_GPL(register_perfctr_intr);
 -- 
 -- void release_perfctr_intr(void (*handler)(struct pt_regs *))
 -- {
 --     spin_lock(&perf_irq_lock);
 --     perf_irq_owner_caller = NULL;
 --     perf_irq = unhandled_perf_irq;
 --     spin_unlock(&perf_irq_lock);
 -- }
 -- EXPORT_SYMBOL_GPL(release_perfctr_intr);
 -- 
    #ifdef CONFIG_HOTPLUG_CPU
    void fixup_irqs(void)
    {
index 2db3c2229b95ca39870fef29c01677ff39dc7c2d,2db3c2229b95ca39870fef29c01677ff39dc7c2d,a55279939b65b9c046bed904b3a2312a5f4f7ccb,2db3c2229b95ca39870fef29c01677ff39dc7c2d..642562d83ec44603dddfbc6276fcb7a2e52a211d
    #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>
@@@@@ -176,7 -176,7 -176,6 -176,7 +176,7 @@@@@ static struct sparc64_tick_ops tick_ope
    };
    
    struct sparc64_tick_ops *tick_ops __read_mostly = &tick_operations;
  + EXPORT_SYMBOL(tick_ops);
    
    static void stick_disable_irq(void)
    {
@@@@@ -640,7 -640,7 -639,6 -640,7 +640,7 @@@@@ unsigned long sparc64_get_clock_tick(un
                return ft->clock_tick_ref;
        return cpu_data(cpu).clock_tick;
    }
  + EXPORT_SYMBOL(sparc64_get_clock_tick);
    
    #ifdef CONFIG_CPU_FREQ
    
diff --combined kernel/irq/chip.c
index 7de11bd64dfe33a2fa8c1091a308ed58b685d0c7,9a7fbb84f5651894891e8c9c591cc2da55593e91,1310856cb22b147558ad5fa1e9944e6b80296285,7de11bd64dfe33a2fa8c1091a308ed58b685d0c7..03d0bed2b8d925492a16e84951772330fccdcbd8
@@@@@ -78,6 -78,6 -78,7 -78,6 +78,7 @@@@@ void dynamic_irq_cleanup(unsigned int i
        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 -290,8 -291,7 -290,7 +291,8 @@@@@ static inline void mask_ack_irq(struct 
                desc->chip->mask_ack(irq);
        else {
                desc->chip->mask(irq);
- --            desc->chip->ack(irq);
+ ++            if (desc->chip->ack)
+ ++                    desc->chip->ack(irq);
        }
    }
    
@@@@@ -383,7 -384,6 -384,6 -383,7 +385,7 @@@@@ handle_level_irq(unsigned int irq, stru
    out_unlock:
        spin_unlock(&desc->lock);
    }
 ++ EXPORT_SYMBOL_GPL(handle_level_irq);
    
    /**
     *  handle_fasteoi_irq - irq handler for transparent controllers
@@@@@ -476,7 -476,8 -476,7 -476,7 +478,8 @@@@@ handle_edge_irq(unsigned int irq, struc
        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.*/
@@@@@ -594,7 -595,6 -594,6 -594,7 +597,7 @@@@@ __set_irq_handler(unsigned int irq, irq
        }
        spin_unlock_irqrestore(&desc->lock, flags);
    }
 ++ EXPORT_SYMBOL_GPL(__set_irq_handler);
    
    void
    set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip,
diff --combined kernel/irq/handle.c
index 3aba8d12f328ec91e59f5c72217ceb0c0d2fd0a1,c20db0be9173969a52c7ab75341cc8171db63d46,49d642b62c64fa51e7cc2958fc988901abaf396b,3aba8d12f328ec91e59f5c72217ceb0c0d2fd0a1..759b8b04d294147e1dd6740dabdb7589f3e765a3
@@@@@ -39,18 -39,6 -39,6 -39,18 +39,18 @@@@@ void handle_bad_irq(unsigned int irq, s
        ack_bad_irq(irq);
    }
    
 ++ #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS)
 ++ static void __init init_irq_default_affinity(void)
 ++ {
 ++     alloc_bootmem_cpumask_var(&irq_default_affinity);
 ++     cpumask_setall(irq_default_affinity);
 ++ }
 ++ #else
 ++ static void __init init_irq_default_affinity(void)
 ++ {
 ++ }
 ++ #endif
 ++ 
    /*
     * Linux has a controller-independent interrupt architecture.
     * Every controller has a 'controller-template', that is used
@@@@@ -83,19 -71,19 -71,21 -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)
@@@@@ -146,8 -134,6 -136,6 -146,8 +148,8 @@@@@ int __init early_irq_init(void
        int legacy_count;
        int i;
    
 ++     init_irq_default_affinity();
 ++ 
        desc = irq_desc_legacy;
        legacy_count = ARRAY_SIZE(irq_desc_legacy);
    
@@@@@ -227,19 -213,17 -215,20 -227,19 +229,22 @@@@@ struct irq_desc irq_desc[NR_IRQS] __cac
        }
    };
    
++ +static unsigned int kstat_irqs_all[NR_IRQS][NR_CPUS];
    int __init early_irq_init(void)
    {
        struct irq_desc *desc;
        int count;
        int i;
    
 ++     init_irq_default_affinity();
 ++ 
        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 -239,6 -244,11 -255,6 +260,11 @@@@@ struct irq_desc *irq_to_desc_alloc_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 -451,12 -461,10 -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);
    
diff --combined kernel/irq/manage.c
index 291f03664552387658690f947b1d3a4d9562dcc6,1c5055069170ef44b7b545413cf96880a89acfb8,cd0cd8dcb3453aee98a20cd6652144cf10e42281,38008b80bd59a0e955a0b61102ed08e01e3c9a8c..cbc3828faf5f4b4cd50f10913dc796dba8c0dfa0
    
    #include "internals.h"
    
 -- #ifdef CONFIG_SMP
 ++ #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS)
    cpumask_var_t irq_default_affinity;
    
 -- static int init_irq_default_affinity(void)
 -- {
 --     alloc_cpumask_var(&irq_default_affinity, GFP_KERNEL);
 --     cpumask_setall(irq_default_affinity);
 --     return 0;
 -- }
 -- core_initcall(init_irq_default_affinity);
 -- 
    /**
     *  synchronize_irq - wait for pending IRQ handlers (on other CPUs)
     *  @irq: interrupt number to wait for
@@@@@ -109,7 -117,7 -117,7 -109,7 +109,7 @@@@@ int irq_set_affinity(unsigned int irq, 
    /*
     * 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 -141,7 -141,7 -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 -157,14 -157,14 -149,14 +149,14 @@@@@ int irq_select_affinity_usr(unsigned in
        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 -496,7 -496,7 -488,7 +488,7 @@@@@ __setup_irq(unsigned int irq, struct ir
                        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 -717,7 -717,7 -709,7 +709,7 @@@@@ int request_irq(unsigned int irq, irq_h
        if (!handler)
                return -EINVAL;
    
- --    action = kmalloc(sizeof(struct irqaction), GFP_ATOMIC);
+ ++    action = kmalloc(sizeof(struct irqaction), GFP_KERNEL);
        if (!action)
                return -ENOMEM;
    
index acd88356ac76abfcbd186209f16d8e92d2ff31fb,ecf765c6a77ac8276b73cc551af07de1c4302f23,c500cfe422b66ffb45445266702341d0b358d1c3,acd88356ac76abfcbd186209f16d8e92d2ff31fb..aef18ab6b75bf1954f23ccff4a52a948d62b74d2
@@@@@ -17,16 -17,16 -17,11 -17,16 +17,11 @@@@@ static void init_copy_kstat_irqs(struc
                                 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)
@@@@@ -71,7 -71,7 -66,7 -71,7 +66,7 @@@@@ static struct irq_desc *__real_move_irq
        desc = irq_desc_ptrs[irq];
    
        if (desc && old_desc != desc)
 --                     goto out_unlock;
 ++             goto out_unlock;
    
        node = cpu_to_node(cpu);
        desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
        init_copy_one_irq_desc(irq, old_desc, desc, cpu);
    
        irq_desc_ptrs[irq] = desc;
 ++     spin_unlock_irqrestore(&sparse_irq_lock, flags);
    
        /* free the old one */
        free_one_irq_desc(old_desc, desc);
 ++     spin_unlock(&old_desc->lock);
        kfree(old_desc);
 ++     spin_lock(&desc->lock);
 ++ 
 ++     return desc;
    
    out_unlock:
        spin_unlock_irqrestore(&sparse_irq_lock, flags);