diff options
author | David Brownell <david-b@pacbell.net> | 2006-08-15 02:11:04 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-09-26 00:08:37 -0400 |
commit | 82bb67f2c1f9ef438c56ac24e7dca027fe7289b5 (patch) | |
tree | e0531466b19295129692da81bdff3538ab3621b3 | |
parent | 8b4b8a24e4e49dc9fe36d4d079f6d2c23f942b03 (diff) |
PM: define PM_EVENT_PRETHAW
This adds a new pm_message_t event type to use when preparing to restore a
swsusp snapshot. Devices that have been initialized by Linux after resume
(rather than left in power-up-reset state) may need to be reset; this new
event type give drivers the chance to do that.
The drivers that will care about this are those which understand more hardware
states than just "on" and "reset", relying on hardware state during resume()
methods to be either the state left by the preceding suspend(), or a
power-lost reset. The best current example of this class of drivers are USB
host controller drivers, which currently do not work through swsusp when
they're statically linked.
When the swsusp freeze/thaw mechanism kicks in, a troublesome third state
could exist: one state set up by a different kernel instance, before a
snapshot image is resumed. This mechanism lets drivers prevent that state.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | include/linux/pm.h | 62 |
1 files changed, 47 insertions, 15 deletions
diff --git a/include/linux/pm.h b/include/linux/pm.h index 096fb6f754cf..6b27e07aef19 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h | |||
@@ -142,29 +142,61 @@ typedef struct pm_message { | |||
142 | } pm_message_t; | 142 | } pm_message_t; |
143 | 143 | ||
144 | /* | 144 | /* |
145 | * There are 4 important states driver can be in: | 145 | * Several driver power state transitions are externally visible, affecting |
146 | * ON -- driver is working | 146 | * the state of pending I/O queues and (for drivers that touch hardware) |
147 | * FREEZE -- stop operations and apply whatever policy is applicable to a | 147 | * interrupts, wakeups, DMA, and other hardware state. There may also be |
148 | * suspended driver of that class, freeze queues for block like IDE | 148 | * internal transitions to various low power modes, which are transparent |
149 | * does, drop packets for ethernet, etc... stop DMA engine too etc... | 149 | * to the rest of the driver stack (such as a driver that's ON gating off |
150 | * so a consistent image can be saved; but do not power any hardware | 150 | * clocks which are not in active use). |
151 | * down. | ||
152 | * SUSPEND - like FREEZE, but hardware is doing as much powersaving as | ||
153 | * possible. Roughly pci D3. | ||
154 | * | 151 | * |
155 | * Unfortunately, current drivers only recognize numeric values 0 (ON) and 3 | 152 | * One transition is triggered by resume(), after a suspend() call; the |
156 | * (SUSPEND). We'll need to fix the drivers. So yes, putting 3 to all different | 153 | * message is implicit: |
157 | * defines is intentional, and will go away as soon as drivers are fixed. Also | 154 | * |
158 | * note that typedef is neccessary, we'll probably want to switch to | 155 | * ON Driver starts working again, responding to hardware events |
159 | * typedef struct pm_message_t { int event; int flags; } pm_message_t | 156 | * and software requests. The hardware may have gone through |
160 | * or something similar soon. | 157 | * a power-off reset, or it may have maintained state from the |
158 | * previous suspend() which the driver will rely on while | ||
159 | * resuming. On most platforms, there are no restrictions on | ||
160 | * availability of resources like clocks during resume(). | ||
161 | * | ||
162 | * Other transitions are triggered by messages sent using suspend(). All | ||
163 | * these transitions quiesce the driver, so that I/O queues are inactive. | ||
164 | * That commonly entails turning off IRQs and DMA; there may be rules | ||
165 | * about how to quiesce that are specific to the bus or the device's type. | ||
166 | * (For example, network drivers mark the link state.) Other details may | ||
167 | * differ according to the message: | ||
168 | * | ||
169 | * SUSPEND Quiesce, enter a low power device state appropriate for | ||
170 | * the upcoming system state (such as PCI_D3hot), and enable | ||
171 | * wakeup events as appropriate. | ||
172 | * | ||
173 | * FREEZE Quiesce operations so that a consistent image can be saved; | ||
174 | * but do NOT otherwise enter a low power device state, and do | ||
175 | * NOT emit system wakeup events. | ||
176 | * | ||
177 | * PRETHAW Quiesce as if for FREEZE; additionally, prepare for restoring | ||
178 | * the system from a snapshot taken after an earlier FREEZE. | ||
179 | * Some drivers will need to reset their hardware state instead | ||
180 | * of preserving it, to ensure that it's never mistaken for the | ||
181 | * state which that earlier snapshot had set up. | ||
182 | * | ||
183 | * A minimally power-aware driver treats all messages as SUSPEND, fully | ||
184 | * reinitializes its device during resume() -- whether or not it was reset | ||
185 | * during the suspend/resume cycle -- and can't issue wakeup events. | ||
186 | * | ||
187 | * More power-aware drivers may also use low power states at runtime as | ||
188 | * well as during system sleep states like PM_SUSPEND_STANDBY. They may | ||
189 | * be able to use wakeup events to exit from runtime low-power states, | ||
190 | * or from system low-power states such as standby or suspend-to-RAM. | ||
161 | */ | 191 | */ |
162 | 192 | ||
163 | #define PM_EVENT_ON 0 | 193 | #define PM_EVENT_ON 0 |
164 | #define PM_EVENT_FREEZE 1 | 194 | #define PM_EVENT_FREEZE 1 |
165 | #define PM_EVENT_SUSPEND 2 | 195 | #define PM_EVENT_SUSPEND 2 |
196 | #define PM_EVENT_PRETHAW 3 | ||
166 | 197 | ||
167 | #define PMSG_FREEZE ((struct pm_message){ .event = PM_EVENT_FREEZE, }) | 198 | #define PMSG_FREEZE ((struct pm_message){ .event = PM_EVENT_FREEZE, }) |
199 | #define PMSG_PRETHAW ((struct pm_message){ .event = PM_EVENT_PRETHAW, }) | ||
168 | #define PMSG_SUSPEND ((struct pm_message){ .event = PM_EVENT_SUSPEND, }) | 200 | #define PMSG_SUSPEND ((struct pm_message){ .event = PM_EVENT_SUSPEND, }) |
169 | #define PMSG_ON ((struct pm_message){ .event = PM_EVENT_ON, }) | 201 | #define PMSG_ON ((struct pm_message){ .event = PM_EVENT_ON, }) |
170 | 202 | ||