Commit 27f3d18630cd7fbb03b62bd78a74303cb8c88069
1 parent
76cde7e495
PM / genirq: Document rules related to system suspend and interrupts
Add a document describing how IRQs are managed during system suspend and resume, how wakeup interrupts work and what the IRQF_NO_SUSPEND flag is supposed to be used for. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Showing 1 changed file with 123 additions and 0 deletions Side-by-side Diff
Documentation/power/suspend-and-interrupts.txt
1 | +System Suspend and Device Interrupts | |
2 | + | |
3 | +Copyright (C) 2014 Intel Corp. | |
4 | +Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com> | |
5 | + | |
6 | + | |
7 | +Suspending and Resuming Device IRQs | |
8 | +----------------------------------- | |
9 | + | |
10 | +Device interrupt request lines (IRQs) are generally disabled during system | |
11 | +suspend after the "late" phase of suspending devices (that is, after all of the | |
12 | +->prepare, ->suspend and ->suspend_late callbacks have been executed for all | |
13 | +devices). That is done by suspend_device_irqs(). | |
14 | + | |
15 | +The rationale for doing so is that after the "late" phase of device suspend | |
16 | +there is no legitimate reason why any interrupts from suspended devices should | |
17 | +trigger and if any devices have not been suspended properly yet, it is better to | |
18 | +block interrupts from them anyway. Also, in the past we had problems with | |
19 | +interrupt handlers for shared IRQs that device drivers implementing them were | |
20 | +not prepared for interrupts triggering after their devices had been suspended. | |
21 | +In some cases they would attempt to access, for example, memory address spaces | |
22 | +of suspended devices and cause unpredictable behavior to ensue as a result. | |
23 | +Unfortunately, such problems are very difficult to debug and the introduction | |
24 | +of suspend_device_irqs(), along with the "noirq" phase of device suspend and | |
25 | +resume, was the only practical way to mitigate them. | |
26 | + | |
27 | +Device IRQs are re-enabled during system resume, right before the "early" phase | |
28 | +of resuming devices (that is, before starting to execute ->resume_early | |
29 | +callbacks for devices). The function doing that is resume_device_irqs(). | |
30 | + | |
31 | + | |
32 | +The IRQF_NO_SUSPEND Flag | |
33 | +------------------------ | |
34 | + | |
35 | +There are interrupts that can legitimately trigger during the entire system | |
36 | +suspend-resume cycle, including the "noirq" phases of suspending and resuming | |
37 | +devices as well as during the time when nonboot CPUs are taken offline and | |
38 | +brought back online. That applies to timer interrupts in the first place, | |
39 | +but also to IPIs and to some other special-purpose interrupts. | |
40 | + | |
41 | +The IRQF_NO_SUSPEND flag is used to indicate that to the IRQ subsystem when | |
42 | +requesting a special-purpose interrupt. It causes suspend_device_irqs() to | |
43 | +leave the corresponding IRQ enabled so as to allow the interrupt to work all | |
44 | +the time as expected. | |
45 | + | |
46 | +Note that the IRQF_NO_SUSPEND flag affects the entire IRQ and not just one | |
47 | +user of it. Thus, if the IRQ is shared, all of the interrupt handlers installed | |
48 | +for it will be executed as usual after suspend_device_irqs(), even if the | |
49 | +IRQF_NO_SUSPEND flag was not passed to request_irq() (or equivalent) by some of | |
50 | +the IRQ's users. For this reason, using IRQF_NO_SUSPEND and IRQF_SHARED at the | |
51 | +same time should be avoided. | |
52 | + | |
53 | + | |
54 | +System Wakeup Interrupts, enable_irq_wake() and disable_irq_wake() | |
55 | +------------------------------------------------------------------ | |
56 | + | |
57 | +System wakeup interrupts generally need to be configured to wake up the system | |
58 | +from sleep states, especially if they are used for different purposes (e.g. as | |
59 | +I/O interrupts) in the working state. | |
60 | + | |
61 | +That may involve turning on a special signal handling logic within the platform | |
62 | +(such as an SoC) so that signals from a given line are routed in a different way | |
63 | +during system sleep so as to trigger a system wakeup when needed. For example, | |
64 | +the platform may include a dedicated interrupt controller used specifically for | |
65 | +handling system wakeup events. Then, if a given interrupt line is supposed to | |
66 | +wake up the system from sleep sates, the corresponding input of that interrupt | |
67 | +controller needs to be enabled to receive signals from the line in question. | |
68 | +After wakeup, it generally is better to disable that input to prevent the | |
69 | +dedicated controller from triggering interrupts unnecessarily. | |
70 | + | |
71 | +The IRQ subsystem provides two helper functions to be used by device drivers for | |
72 | +those purposes. Namely, enable_irq_wake() turns on the platform's logic for | |
73 | +handling the given IRQ as a system wakeup interrupt line and disable_irq_wake() | |
74 | +turns that logic off. | |
75 | + | |
76 | +Calling enable_irq_wake() causes suspend_device_irqs() to treat the given IRQ | |
77 | +in a special way. Namely, the IRQ remains enabled, by on the first interrupt | |
78 | +it will be disabled, marked as pending and "suspended" so that it will be | |
79 | +re-enabled by resume_device_irqs() during the subsequent system resume. Also | |
80 | +the PM core is notified about the event which casues the system suspend in | |
81 | +progress to be aborted (that doesn't have to happen immediately, but at one | |
82 | +of the points where the suspend thread looks for pending wakeup events). | |
83 | + | |
84 | +This way every interrupt from a wakeup interrupt source will either cause the | |
85 | +system suspend currently in progress to be aborted or wake up the system if | |
86 | +already suspended. However, after suspend_device_irqs() interrupt handlers are | |
87 | +not executed for system wakeup IRQs. They are only executed for IRQF_NO_SUSPEND | |
88 | +IRQs at that time, but those IRQs should not be configured for system wakeup | |
89 | +using enable_irq_wake(). | |
90 | + | |
91 | + | |
92 | +Interrupts and Suspend-to-Idle | |
93 | +------------------------------ | |
94 | + | |
95 | +Suspend-to-idle (also known as the "freeze" sleep state) is a relatively new | |
96 | +system sleep state that works by idling all of the processors and waiting for | |
97 | +interrupts right after the "noirq" phase of suspending devices. | |
98 | + | |
99 | +Of course, this means that all of the interrupts with the IRQF_NO_SUSPEND flag | |
100 | +set will bring CPUs out of idle while in that state, but they will not cause the | |
101 | +IRQ subsystem to trigger a system wakeup. | |
102 | + | |
103 | +System wakeup interrupts, in turn, will trigger wakeup from suspend-to-idle in | |
104 | +analogy with what they do in the full system suspend case. The only difference | |
105 | +is that the wakeup from suspend-to-idle is signaled using the usual working | |
106 | +state interrupt delivery mechanisms and doesn't require the platform to use | |
107 | +any special interrupt handling logic for it to work. | |
108 | + | |
109 | + | |
110 | +IRQF_NO_SUSPEND and enable_irq_wake() | |
111 | +------------------------------------- | |
112 | + | |
113 | +There are no valid reasons to use both enable_irq_wake() and the IRQF_NO_SUSPEND | |
114 | +flag on the same IRQ. | |
115 | + | |
116 | +First of all, if the IRQ is not shared, the rules for handling IRQF_NO_SUSPEND | |
117 | +interrupts (interrupt handlers are invoked after suspend_device_irqs()) are | |
118 | +directly at odds with the rules for handling system wakeup interrupts (interrupt | |
119 | +handlers are not invoked after suspend_device_irqs()). | |
120 | + | |
121 | +Second, both enable_irq_wake() and IRQF_NO_SUSPEND apply to entire IRQs and not | |
122 | +to individual interrupt handlers, so sharing an IRQ between a system wakeup | |
123 | +interrupt source and an IRQF_NO_SUSPEND interrupt source does not make sense. |