Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/kernel/irq/pm.c
10818 views
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 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 IRQS_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
raw_spin_lock_irqsave(&desc->lock, flags);
32
__disable_irq(desc, irq, true);
33
raw_spin_unlock_irqrestore(&desc->lock, flags);
34
}
35
36
for_each_irq_desc(irq, desc)
37
if (desc->istate & IRQS_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 IRQS_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
raw_spin_lock_irqsave(&desc->lock, flags);
57
__enable_irq(desc, irq, true);
58
raw_spin_unlock_irqrestore(&desc->lock, flags);
59
}
60
}
61
EXPORT_SYMBOL_GPL(resume_device_irqs);
62
63
/**
64
* check_wakeup_irqs - check if any wake-up interrupts are pending
65
*/
66
int check_wakeup_irqs(void)
67
{
68
struct irq_desc *desc;
69
int irq;
70
71
for_each_irq_desc(irq, desc) {
72
if (irqd_is_wakeup_set(&desc->irq_data)) {
73
if (desc->istate & IRQS_PENDING)
74
return -EBUSY;
75
continue;
76
}
77
/*
78
* Check the non wakeup interrupts whether they need
79
* to be masked before finally going into suspend
80
* state. That's for hardware which has no wakeup
81
* source configuration facility. The chip
82
* implementation indicates that with
83
* IRQCHIP_MASK_ON_SUSPEND.
84
*/
85
if (desc->istate & IRQS_SUSPENDED &&
86
irq_desc_get_chip(desc)->flags & IRQCHIP_MASK_ON_SUSPEND)
87
mask_irq(desc);
88
}
89
90
return 0;
91
}
92
93