1 /* 2 * linux/kernel/irq/pm.c 3 * 4 * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, 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 drivers need to be prevented 19 * from receiving interrupts and this function is provided for this purpose. 20 * It marks all interrupt lines in use, except for the timer ones, as disabled 21 * and sets the IRQ_SUSPENDED flag for each of 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 } 80