diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2014-08-28 05:49:28 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-09-01 07:47:57 -0400 |
commit | 8df2e02c5c4de9e65ee60153dd9c442356534ad9 (patch) | |
tree | b4080a4efddd018fac2bd4aa57c8c6ced8b6f0b4 /kernel/irq/pm.c | |
parent | 068765ba7987e73d4381edfe47b70aa121c7155c (diff) |
genirq: Move suspend/resume logic into irq/pm code
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>
Diffstat (limited to 'kernel/irq/pm.c')
-rw-r--r-- | kernel/irq/pm.c | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c index abcd6ca86cb7..b84141dcee5e 100644 --- a/kernel/irq/pm.c +++ b/kernel/irq/pm.c | |||
@@ -13,13 +13,26 @@ | |||
13 | 13 | ||
14 | #include "internals.h" | 14 | #include "internals.h" |
15 | 15 | ||
16 | static void suspend_device_irq(struct irq_desc *desc, int irq) | ||
17 | { | ||
18 | if (!desc->action || (desc->action->flags & IRQF_NO_SUSPEND)) | ||
19 | return; | ||
20 | |||
21 | desc->istate |= IRQS_SUSPENDED; | ||
22 | __disable_irq(desc, irq); | ||
23 | } | ||
24 | |||
16 | /** | 25 | /** |
17 | * suspend_device_irqs - disable all currently enabled interrupt lines | 26 | * suspend_device_irqs - disable all currently enabled interrupt lines |
18 | * | 27 | * |
19 | * During system-wide suspend or hibernation device drivers need to be prevented | 28 | * During system-wide suspend or hibernation device drivers need to be |
20 | * from receiving interrupts and this function is provided for this purpose. | 29 | * prevented from receiving interrupts and this function is provided |
21 | * It marks all interrupt lines in use, except for the timer ones, as disabled | 30 | * for this purpose. |
22 | * and sets the IRQS_SUSPENDED flag for each of them. | 31 | * |
32 | * So we disable all interrupts and mark them IRQS_SUSPENDED except | ||
33 | * for those which are unused and those which are marked as not | ||
34 | * suspendable via an interrupt request with the flag IRQF_NO_SUSPEND | ||
35 | * set. | ||
23 | */ | 36 | */ |
24 | void suspend_device_irqs(void) | 37 | void suspend_device_irqs(void) |
25 | { | 38 | { |
@@ -30,7 +43,7 @@ void suspend_device_irqs(void) | |||
30 | unsigned long flags; | 43 | unsigned long flags; |
31 | 44 | ||
32 | raw_spin_lock_irqsave(&desc->lock, flags); | 45 | raw_spin_lock_irqsave(&desc->lock, flags); |
33 | __disable_irq(desc, irq, true); | 46 | suspend_device_irq(desc, irq); |
34 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 47 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
35 | } | 48 | } |
36 | 49 | ||
@@ -40,6 +53,25 @@ void suspend_device_irqs(void) | |||
40 | } | 53 | } |
41 | EXPORT_SYMBOL_GPL(suspend_device_irqs); | 54 | EXPORT_SYMBOL_GPL(suspend_device_irqs); |
42 | 55 | ||
56 | static void resume_irq(struct irq_desc *desc, int irq) | ||
57 | { | ||
58 | if (desc->istate & IRQS_SUSPENDED) | ||
59 | goto resume; | ||
60 | |||
61 | if (!desc->action) | ||
62 | return; | ||
63 | |||
64 | /* Interrupts marked with that flag are force reenabled */ | ||
65 | if (!(desc->action->flags & IRQF_FORCE_RESUME)) | ||
66 | return; | ||
67 | |||
68 | /* Pretend that it got disabled ! */ | ||
69 | desc->depth++; | ||
70 | resume: | ||
71 | desc->istate &= ~IRQS_SUSPENDED; | ||
72 | __enable_irq(desc, irq); | ||
73 | } | ||
74 | |||
43 | static void resume_irqs(bool want_early) | 75 | static void resume_irqs(bool want_early) |
44 | { | 76 | { |
45 | struct irq_desc *desc; | 77 | struct irq_desc *desc; |
@@ -54,7 +86,7 @@ static void resume_irqs(bool want_early) | |||
54 | continue; | 86 | continue; |
55 | 87 | ||
56 | raw_spin_lock_irqsave(&desc->lock, flags); | 88 | raw_spin_lock_irqsave(&desc->lock, flags); |
57 | __enable_irq(desc, irq, true); | 89 | resume_irq(desc, irq); |
58 | raw_spin_unlock_irqrestore(&desc->lock, flags); | 90 | raw_spin_unlock_irqrestore(&desc->lock, flags); |
59 | } | 91 | } |
60 | } | 92 | } |