]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - kernel/irq/manage.c
Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[karo-tx-linux.git] / kernel / irq / manage.c
index 0a8e8f059627dec4ee56bab79849e0f86372d3b5..4c69326aa773f6469b7170d66814d7480ea12ea7 100644 (file)
@@ -943,6 +943,18 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
                goto out_thread;
        }
 
+       /*
+        * Drivers are often written to work w/o knowledge about the
+        * underlying irq chip implementation, so a request for a
+        * threaded irq without a primary hard irq context handler
+        * requires the ONESHOT flag to be set. Some irq chips like
+        * MSI based interrupts are per se one shot safe. Check the
+        * chip flags, so we can avoid the unmask dance at the end of
+        * the threaded handler for those.
+        */
+       if (desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE)
+               new->flags &= ~IRQF_ONESHOT;
+
        /*
         * The following block of code has to be executed atomically
         */
@@ -1017,7 +1029,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
                 */
                new->thread_mask = 1 << ffz(thread_mask);
 
-       } else if (new->handler == irq_default_primary_handler) {
+       } else if (new->handler == irq_default_primary_handler &&
+                  !(desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE)) {
                /*
                 * The interrupt was requested with handler = NULL, so
                 * we use the default primary handler for it. But it