/*1* linux/kernel/irq/pm.c2*3* Copyright (C) 2009 Rafael J. Wysocki <[email protected]>, Novell Inc.4*5* This file contains power management functions related to interrupts.6*/78#include <linux/irq.h>9#include <linux/module.h>10#include <linux/interrupt.h>1112#include "internals.h"1314/**15* suspend_device_irqs - disable all currently enabled interrupt lines16*17* During system-wide suspend or hibernation device drivers need to be prevented18* from receiving interrupts and this function is provided for this purpose.19* It marks all interrupt lines in use, except for the timer ones, as disabled20* and sets the IRQS_SUSPENDED flag for each of them.21*/22void suspend_device_irqs(void)23{24struct irq_desc *desc;25int irq;2627for_each_irq_desc(irq, desc) {28unsigned long flags;2930raw_spin_lock_irqsave(&desc->lock, flags);31__disable_irq(desc, irq, true);32raw_spin_unlock_irqrestore(&desc->lock, flags);33}3435for_each_irq_desc(irq, desc)36if (desc->istate & IRQS_SUSPENDED)37synchronize_irq(irq);38}39EXPORT_SYMBOL_GPL(suspend_device_irqs);4041/**42* resume_device_irqs - enable interrupt lines disabled by suspend_device_irqs()43*44* Enable all interrupt lines previously disabled by suspend_device_irqs() that45* have the IRQS_SUSPENDED flag set.46*/47void resume_device_irqs(void)48{49struct irq_desc *desc;50int irq;5152for_each_irq_desc(irq, desc) {53unsigned long flags;5455raw_spin_lock_irqsave(&desc->lock, flags);56__enable_irq(desc, irq, true);57raw_spin_unlock_irqrestore(&desc->lock, flags);58}59}60EXPORT_SYMBOL_GPL(resume_device_irqs);6162/**63* check_wakeup_irqs - check if any wake-up interrupts are pending64*/65int check_wakeup_irqs(void)66{67struct irq_desc *desc;68int irq;6970for_each_irq_desc(irq, desc) {71if (irqd_is_wakeup_set(&desc->irq_data)) {72if (desc->istate & IRQS_PENDING)73return -EBUSY;74continue;75}76/*77* Check the non wakeup interrupts whether they need78* to be masked before finally going into suspend79* state. That's for hardware which has no wakeup80* source configuration facility. The chip81* implementation indicates that with82* IRQCHIP_MASK_ON_SUSPEND.83*/84if (desc->istate & IRQS_SUSPENDED &&85irq_desc_get_chip(desc)->flags & IRQCHIP_MASK_ON_SUSPEND)86mask_irq(desc);87}8889return 0;90}919293