]> git.karo-electronics.de Git - linux-beck.git/commitdiff
genirq: Move suspend/resume logic into irq/pm code
authorThomas Gleixner <tglx@linutronix.de>
Thu, 28 Aug 2014 09:49:28 +0000 (11:49 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 1 Sep 2014 11:47:57 +0000 (13:47 +0200)
No functional change. Preparatory patch for cleaning up the suspend
abort functionality. Update the comments while at it.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
kernel/irq/internals.h
kernel/irq/manage.c
kernel/irq/pm.c

index 099ea2e0eb8833676b3d234f2740487873bac093..af2821178900a6313cdab63b7895f2d2f28c813e 100644 (file)
@@ -63,8 +63,8 @@ enum {
 
 extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
                unsigned long flags);
-extern void __disable_irq(struct irq_desc *desc, unsigned int irq, bool susp);
-extern void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume);
+extern void __disable_irq(struct irq_desc *desc, unsigned int irq);
+extern void __enable_irq(struct irq_desc *desc, unsigned int irq);
 
 extern int irq_startup(struct irq_desc *desc, bool resend);
 extern void irq_shutdown(struct irq_desc *desc);
index 3dc6a61bf06a447acb70f67fc3942fc2286e32d2..fa564e8db996b5e32b969ed9f6c3ef9ca95c2394 100644 (file)
@@ -382,14 +382,8 @@ setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask)
 }
 #endif
 
-void __disable_irq(struct irq_desc *desc, unsigned int irq, bool suspend)
+void __disable_irq(struct irq_desc *desc, unsigned int irq)
 {
-       if (suspend) {
-               if (!desc->action || (desc->action->flags & IRQF_NO_SUSPEND))
-                       return;
-               desc->istate |= IRQS_SUSPENDED;
-       }
-
        if (!desc->depth++)
                irq_disable(desc);
 }
@@ -401,7 +395,7 @@ static int __disable_irq_nosync(unsigned int irq)
 
        if (!desc)
                return -EINVAL;
-       __disable_irq(desc, irq, false);
+       __disable_irq(desc, irq);
        irq_put_desc_busunlock(desc, flags);
        return 0;
 }
@@ -442,20 +436,8 @@ void disable_irq(unsigned int irq)
 }
 EXPORT_SYMBOL(disable_irq);
 
-void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume)
+void __enable_irq(struct irq_desc *desc, unsigned int irq)
 {
-       if (resume) {
-               if (!(desc->istate & IRQS_SUSPENDED)) {
-                       if (!desc->action)
-                               return;
-                       if (!(desc->action->flags & IRQF_FORCE_RESUME))
-                               return;
-                       /* Pretend that it got disabled ! */
-                       desc->depth++;
-               }
-               desc->istate &= ~IRQS_SUSPENDED;
-       }
-
        switch (desc->depth) {
        case 0:
  err_out:
@@ -497,7 +479,7 @@ void enable_irq(unsigned int irq)
                 KERN_ERR "enable_irq before setup/request_irq: irq %u\n", irq))
                goto out;
 
-       __enable_irq(desc, irq, false);
+       __enable_irq(desc, irq);
 out:
        irq_put_desc_busunlock(desc, flags);
 }
@@ -1228,7 +1210,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
         */
        if (shared && (desc->istate & IRQS_SPURIOUS_DISABLED)) {
                desc->istate &= ~IRQS_SPURIOUS_DISABLED;
-               __enable_irq(desc, irq, false);
+               __enable_irq(desc, irq);
        }
 
        raw_spin_unlock_irqrestore(&desc->lock, flags);
index abcd6ca86cb76b56e5979613a1964c0db743b5d0..b84141dcee5ed038d9e1939908b532e8d2f6e8b0 100644 (file)
 
 #include "internals.h"
 
+static void suspend_device_irq(struct irq_desc *desc, int irq)
+{
+       if (!desc->action || (desc->action->flags & IRQF_NO_SUSPEND))
+               return;
+
+       desc->istate |= IRQS_SUSPENDED;
+       __disable_irq(desc, irq);
+}
+
 /**
  * suspend_device_irqs - disable all currently enabled interrupt lines
  *
- * During system-wide suspend or hibernation device drivers need to be prevented
- * from receiving interrupts and this function is provided for this purpose.
- * It marks all interrupt lines in use, except for the timer ones, as disabled
- * and sets the IRQS_SUSPENDED flag for each of them.
+ * During system-wide suspend or hibernation device drivers need to be
+ * prevented from receiving interrupts and this function is provided
+ * for this purpose.
+ *
+ * So we disable all interrupts and mark them IRQS_SUSPENDED except
+ * for those which are unused and those which are marked as not
+ * suspendable via an interrupt request with the flag IRQF_NO_SUSPEND
+ * set.
  */
 void suspend_device_irqs(void)
 {
@@ -30,7 +43,7 @@ void suspend_device_irqs(void)
                unsigned long flags;
 
                raw_spin_lock_irqsave(&desc->lock, flags);
-               __disable_irq(desc, irq, true);
+               suspend_device_irq(desc, irq);
                raw_spin_unlock_irqrestore(&desc->lock, flags);
        }
 
@@ -40,6 +53,25 @@ void suspend_device_irqs(void)
 }
 EXPORT_SYMBOL_GPL(suspend_device_irqs);
 
+static void resume_irq(struct irq_desc *desc, int irq)
+{
+       if (desc->istate & IRQS_SUSPENDED)
+               goto resume;
+
+       if (!desc->action)
+               return;
+
+       /* Interrupts marked with that flag are force reenabled */
+       if (!(desc->action->flags & IRQF_FORCE_RESUME))
+               return;
+
+       /* Pretend that it got disabled ! */
+       desc->depth++;
+resume:
+       desc->istate &= ~IRQS_SUSPENDED;
+       __enable_irq(desc, irq);
+}
+
 static void resume_irqs(bool want_early)
 {
        struct irq_desc *desc;
@@ -54,7 +86,7 @@ static void resume_irqs(bool want_early)
                        continue;
 
                raw_spin_lock_irqsave(&desc->lock, flags);
-               __enable_irq(desc, irq, true);
+               resume_irq(desc, irq);
                raw_spin_unlock_irqrestore(&desc->lock, flags);
        }
 }