]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
genirq: Add IRQF_FORCE_RESUME
authorThomas Gleixner <tglx@linutronix.de>
Fri, 4 Feb 2011 12:19:20 +0000 (13:19 +0100)
committerAndi Kleen <ak@linux.intel.com>
Mon, 1 Aug 2011 20:54:56 +0000 (13:54 -0700)
commit dc5f219e88294b93009eef946251251ffffb6d60 upstream.

Xen needs to reenable interrupts which are marked IRQF_NO_SUSPEND in the
resume path. Add a flag to force the reenabling in the resume code.

Tested-and-acked-by: Ian Campbell <Ian.Campbell@eu.citrix.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Andi Kleen <ak@linux.intel.com>
include/linux/interrupt.h
kernel/irq/manage.c
kernel/irq/pm.c

index a0384a4d1e6f4da4d39a02c0f8ba6634842dd236..146712ce7534084631a1e8f067614cf06239ffd7 100644 (file)
@@ -54,7 +54,7 @@
  *                Used by threaded interrupts which need to keep the
  *                irq line disabled until the threaded handler has been run.
  * IRQF_NO_SUSPEND - Do not disable this IRQ during suspend
- *
+ * IRQF_FORCE_RESUME - Force enable it on resume even if IRQF_NO_SUSPEND is set
  */
 #define IRQF_DISABLED          0x00000020
 #define IRQF_SAMPLE_RANDOM     0x00000040
@@ -66,6 +66,7 @@
 #define IRQF_IRQPOLL           0x00001000
 #define IRQF_ONESHOT           0x00002000
 #define IRQF_NO_SUSPEND                0x00004000
+#define IRQF_FORCE_RESUME      0x00008000
 
 #define IRQF_TIMER             (__IRQF_TIMER | IRQF_NO_SUSPEND)
 
index 6a2281f781c10c42f3666161ce3dc6d504c3286c..a6a8b6af1fe7c1b375ace38a235b4a40370d7180 100644 (file)
@@ -281,8 +281,17 @@ EXPORT_SYMBOL(disable_irq);
 
 void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume)
 {
-       if (resume)
+       if (resume) {
+               if (!(desc->status & IRQ_SUSPENDED)) {
+                       if (!desc->action)
+                               return;
+                       if (!(desc->action->flags & IRQF_FORCE_RESUME))
+                               return;
+                       /* Pretend that it got disabled ! */
+                       desc->depth++;
+               }
                desc->status &= ~IRQ_SUSPENDED;
+       }
 
        switch (desc->depth) {
        case 0:
index 0d4005d85b03243746f6c45d54cf1600bc3e5acf..d6bfb89cce910de5262617ff4e42fe353c258a0e 100644 (file)
@@ -53,9 +53,6 @@ void resume_device_irqs(void)
        for_each_irq_desc(irq, desc) {
                unsigned long flags;
 
-               if (!(desc->status & IRQ_SUSPENDED))
-                       continue;
-
                raw_spin_lock_irqsave(&desc->lock, flags);
                __enable_irq(desc, irq, true);
                raw_spin_unlock_irqrestore(&desc->lock, flags);