]>
Commit | Line | Data |
---|---|---|
0a0c5168 RW |
1 | /* |
2 | * linux/kernel/irq/pm.c | |
3 | * | |
4 | * Copyright (C) 2009 Rafael J. Wysocki <[email protected]>, Novell Inc. | |
5 | * | |
6 | * This file contains power management functions related to interrupts. | |
7 | */ | |
8 | ||
9 | #include <linux/irq.h> | |
10 | #include <linux/module.h> | |
11 | #include <linux/interrupt.h> | |
12 | ||
13 | #include "internals.h" | |
14 | ||
15 | /** | |
16 | * suspend_device_irqs - disable all currently enabled interrupt lines | |
17 | * | |
18 | * During system-wide suspend or hibernation device interrupts need to be | |
19 | * disabled at the chip level and this function is provided for this purpose. | |
20 | * It disables all interrupt lines that are enabled at the moment and sets the | |
21 | * IRQ_SUSPENDED flag for them. | |
22 | */ | |
23 | void suspend_device_irqs(void) | |
24 | { | |
25 | struct irq_desc *desc; | |
26 | int irq; | |
27 | ||
28 | for_each_irq_desc(irq, desc) { | |
29 | unsigned long flags; | |
30 | ||
31 | spin_lock_irqsave(&desc->lock, flags); | |
32 | __disable_irq(desc, irq, true); | |
33 | spin_unlock_irqrestore(&desc->lock, flags); | |
34 | } | |
35 | ||
36 | for_each_irq_desc(irq, desc) | |
37 | if (desc->status & IRQ_SUSPENDED) | |
38 | synchronize_irq(irq); | |
39 | } | |
40 | EXPORT_SYMBOL_GPL(suspend_device_irqs); | |
41 | ||
42 | /** | |
43 | * resume_device_irqs - enable interrupt lines disabled by suspend_device_irqs() | |
44 | * | |
45 | * Enable all interrupt lines previously disabled by suspend_device_irqs() that | |
46 | * have the IRQ_SUSPENDED flag set. | |
47 | */ | |
48 | void resume_device_irqs(void) | |
49 | { | |
50 | struct irq_desc *desc; | |
51 | int irq; | |
52 | ||
53 | for_each_irq_desc(irq, desc) { | |
54 | unsigned long flags; | |
55 | ||
56 | if (!(desc->status & IRQ_SUSPENDED)) | |
57 | continue; | |
58 | ||
59 | spin_lock_irqsave(&desc->lock, flags); | |
60 | __enable_irq(desc, irq, true); | |
61 | spin_unlock_irqrestore(&desc->lock, flags); | |
62 | } | |
63 | } | |
64 | EXPORT_SYMBOL_GPL(resume_device_irqs); | |
65 | ||
66 | /** | |
67 | * check_wakeup_irqs - check if any wake-up interrupts are pending | |
68 | */ | |
69 | int check_wakeup_irqs(void) | |
70 | { | |
71 | struct irq_desc *desc; | |
72 | int irq; | |
73 | ||
74 | for_each_irq_desc(irq, desc) | |
75 | if ((desc->status & IRQ_WAKEUP) && (desc->status & IRQ_PENDING)) | |
76 | return -EBUSY; | |
77 | ||
78 | return 0; | |
79 | } |