This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / kernel / irq / manage.c
index a164fe2..97d5559 100644 (file)
@@ -6,6 +6,7 @@
  * This file contains driver APIs to the irq subsystem.
  */
 
+#include <linux/config.h>
 #include <linux/irq.h>
 #include <linux/module.h>
 #include <linux/random.h>
 
 #ifdef CONFIG_SMP
 
+cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
+
+#if defined (CONFIG_GENERIC_PENDING_IRQ) || defined (CONFIG_IRQBALANCE)
+cpumask_t __cacheline_aligned pending_irq_cpumask[NR_IRQS];
+#endif
+
 /**
  *     synchronize_irq - wait for pending IRQ handlers (on other CPUs)
+ *     @irq: interrupt number to wait for
  *
  *     This function waits for any pending IRQ handlers for this interrupt
  *     to complete before returning. If you use this function while
@@ -28,6 +36,9 @@ void synchronize_irq(unsigned int irq)
 {
        struct irq_desc *desc = irq_desc + irq;
 
+       if (irq >= NR_IRQS)
+               return;
+
        while (desc->status & IRQ_INPROGRESS)
                cpu_relax();
 }
@@ -52,6 +63,9 @@ void disable_irq_nosync(unsigned int irq)
        irq_desc_t *desc = irq_desc + irq;
        unsigned long flags;
 
+       if (irq >= NR_IRQS)
+               return;
+
        spin_lock_irqsave(&desc->lock, flags);
        if (!desc->depth++) {
                desc->status |= IRQ_DISABLED;
@@ -78,6 +92,9 @@ void disable_irq(unsigned int irq)
 {
        irq_desc_t *desc = irq_desc + irq;
 
+       if (irq >= NR_IRQS)
+               return;
+
        disable_irq_nosync(irq);
        if (desc->action)
                synchronize_irq(irq);
@@ -100,6 +117,9 @@ void enable_irq(unsigned int irq)
        irq_desc_t *desc = irq_desc + irq;
        unsigned long flags;
 
+       if (irq >= NR_IRQS)
+               return;
+
        spin_lock_irqsave(&desc->lock, flags);
        switch (desc->depth) {
        case 0:
@@ -155,6 +175,9 @@ int setup_irq(unsigned int irq, struct irqaction * new)
        unsigned long flags;
        int shared = 0;
 
+       if (irq >= NR_IRQS)
+               return -EINVAL;
+
        if (desc->handler == &no_irq_type)
                return -ENOSYS;
        /*
@@ -253,6 +276,13 @@ void free_irq(unsigned int irq, void *dev_id)
 
                        /* Found it - now remove it from the list of entries */
                        *pp = action->next;
+
+                       /* Currently used only by UML, might disappear one day.*/
+#ifdef CONFIG_IRQ_RELEASE_METHOD
+                       if (desc->handler->release)
+                               desc->handler->release(irq, dev_id);
+#endif
+
                        if (!desc->action) {
                                desc->status |= IRQ_DISABLED;
                                if (desc->handler->shutdown)
@@ -336,6 +366,8 @@ int request_irq(unsigned int irq,
        action->next = NULL;
        action->dev_id = dev_id;
 
+       select_smp_affinity(irq);
+
        retval = setup_irq(irq, action);
        if (retval)
                kfree(action);