Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[safe/jmp/linux-2.6] / kernel / irq / manage.c
index 84f3227..3164ba7 100644 (file)
@@ -138,6 +138,22 @@ int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
        return 0;
 }
 
+int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
+{
+       struct irq_desc *desc = irq_to_desc(irq);
+       unsigned long flags;
+
+       if (!desc)
+               return -EINVAL;
+
+       raw_spin_lock_irqsave(&desc->lock, flags);
+       desc->affinity_hint = m;
+       raw_spin_unlock_irqrestore(&desc->lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(irq_set_affinity_hint);
+
 #ifndef CONFIG_AUTO_IRQ_AFFINITY
 /*
  * Generic version of the affinity autoselector.
@@ -757,16 +773,6 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
                if (new->flags & IRQF_ONESHOT)
                        desc->status |= IRQ_ONESHOT;
 
-               /*
-                * Force MSI interrupts to run with interrupts
-                * disabled. The multi vector cards can cause stack
-                * overflows due to nested interrupts when enough of
-                * them are directed to a core and fire at the same
-                * time.
-                */
-               if (desc->msi_desc)
-                       new->flags |= IRQF_DISABLED;
-
                if (!(desc->status & IRQ_NOAUTOEN)) {
                        desc->depth = 0;
                        desc->status &= ~IRQ_DISABLED;
@@ -916,6 +922,12 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
                        desc->chip->disable(irq);
        }
 
+#ifdef CONFIG_SMP
+       /* make sure affinity_hint is cleaned up */
+       if (WARN_ON_ONCE(desc->affinity_hint))
+               desc->affinity_hint = NULL;
+#endif
+
        raw_spin_unlock_irqrestore(&desc->lock, flags);
 
        unregister_handler_proc(irq, action);
@@ -1027,7 +1039,6 @@ EXPORT_SYMBOL(free_irq);
  *     Flags:
  *
  *     IRQF_SHARED             Interrupt is shared
- *     IRQF_DISABLED   Disable local interrupts while processing
  *     IRQF_SAMPLE_RANDOM      The interrupt can be used for entropy
  *     IRQF_TRIGGER_*          Specify active edge(s) or level
  *
@@ -1041,25 +1052,6 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
        int retval;
 
        /*
-        * handle_IRQ_event() always ignores IRQF_DISABLED except for
-        * the _first_ irqaction (sigh).  That can cause oopsing, but
-        * the behavior is classified as "will not fix" so we need to
-        * start nudging drivers away from using that idiom.
-        */
-       if ((irqflags & (IRQF_SHARED|IRQF_DISABLED)) ==
-                                       (IRQF_SHARED|IRQF_DISABLED)) {
-               pr_warning(
-                 "IRQ %d/%s: IRQF_DISABLED is not guaranteed on shared IRQs\n",
-                       irq, devname);
-       }
-
-#ifdef CONFIG_LOCKDEP
-       /*
-        * Lockdep wants atomic interrupt handlers:
-        */
-       irqflags |= IRQF_DISABLED;
-#endif
-       /*
         * Sanity-check: shared interrupts must pass in a real dev-ID,
         * otherwise we'll have trouble later trying to figure out
         * which interrupt is which (messes up the interrupt freeing