Blame view
kernel/irq/pm.c
1.83 KB
0a0c5168d
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/* * linux/kernel/irq/pm.c * * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. * * This file contains power management functions related to interrupts. */ #include <linux/irq.h> #include <linux/module.h> #include <linux/interrupt.h> #include "internals.h" /** * suspend_device_irqs - disable all currently enabled interrupt lines * |
c71320d0c
|
18 19 20 21 |
* 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 IRQ_SUSPENDED flag for each of them. |
0a0c5168d
|
22 23 24 25 26 27 28 29 |
*/ void suspend_device_irqs(void) { struct irq_desc *desc; int irq; for_each_irq_desc(irq, desc) { unsigned long flags; |
239007b84
|
30 |
raw_spin_lock_irqsave(&desc->lock, flags); |
0a0c5168d
|
31 |
__disable_irq(desc, irq, true); |
239007b84
|
32 |
raw_spin_unlock_irqrestore(&desc->lock, flags); |
0a0c5168d
|
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
} for_each_irq_desc(irq, desc) if (desc->status & IRQ_SUSPENDED) synchronize_irq(irq); } EXPORT_SYMBOL_GPL(suspend_device_irqs); /** * resume_device_irqs - enable interrupt lines disabled by suspend_device_irqs() * * Enable all interrupt lines previously disabled by suspend_device_irqs() that * have the IRQ_SUSPENDED flag set. */ void resume_device_irqs(void) { struct irq_desc *desc; int irq; for_each_irq_desc(irq, desc) { unsigned long flags; if (!(desc->status & IRQ_SUSPENDED)) continue; |
239007b84
|
57 |
raw_spin_lock_irqsave(&desc->lock, flags); |
0a0c5168d
|
58 |
__enable_irq(desc, irq, true); |
239007b84
|
59 |
raw_spin_unlock_irqrestore(&desc->lock, flags); |
0a0c5168d
|
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
} } EXPORT_SYMBOL_GPL(resume_device_irqs); /** * check_wakeup_irqs - check if any wake-up interrupts are pending */ int check_wakeup_irqs(void) { struct irq_desc *desc; int irq; for_each_irq_desc(irq, desc) if ((desc->status & IRQ_WAKEUP) && (desc->status & IRQ_PENDING)) return -EBUSY; return 0; } |