aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2007-10-18 06:04:42 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-18 17:37:18 -0400
commit74f270af0c1ed5b9d4413784256959dcfe3593ce (patch)
tree5b74248167be086b0050a84f9ebe072bbb43fdb3
parentf242d9196fd1ef4e6bf0e50d2e7f32866fb145c2 (diff)
PM: Rework struct hibernation_ops
During hibernation we also need to tell the ACPI core that we're going to put the system into the S4 sleep state. For this reason, an additional method in 'struct hibernation_ops' is needed, playing the role of set_target() in 'struct platform_suspend_operations'. Moreover, the role of the .prepare() method is now different, so it's better to introduce another method, that in general may be different from .prepare(), that will be used to prepare the platform for creating the hibernation image (.prepare() is used anyway to notify the platform that we're going to enter the low power state after the image has been saved). Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/acpi/sleep/main.c12
-rw-r--r--include/linux/suspend.h38
-rw-r--r--kernel/power/disk.c27
3 files changed, 64 insertions, 13 deletions
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index c58dd0bb5506..f20b0ab9ef54 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -230,6 +230,12 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
230#endif /* CONFIG_SUSPEND */ 230#endif /* CONFIG_SUSPEND */
231 231
232#ifdef CONFIG_HIBERNATION 232#ifdef CONFIG_HIBERNATION
233static int acpi_hibernation_start(void)
234{
235 acpi_target_sleep_state = ACPI_STATE_S4;
236 return 0;
237}
238
233static int acpi_hibernation_prepare(void) 239static int acpi_hibernation_prepare(void)
234{ 240{
235 return acpi_sleep_prepare(ACPI_STATE_S4); 241 return acpi_sleep_prepare(ACPI_STATE_S4);
@@ -258,6 +264,8 @@ static void acpi_hibernation_finish(void)
258 264
259 /* reset firmware waking vector */ 265 /* reset firmware waking vector */
260 acpi_set_firmware_waking_vector((acpi_physical_address) 0); 266 acpi_set_firmware_waking_vector((acpi_physical_address) 0);
267
268 acpi_target_sleep_state = ACPI_STATE_S0;
261} 269}
262 270
263static int acpi_hibernation_pre_restore(void) 271static int acpi_hibernation_pre_restore(void)
@@ -275,9 +283,11 @@ static void acpi_hibernation_restore_cleanup(void)
275} 283}
276 284
277static struct hibernation_ops acpi_hibernation_ops = { 285static struct hibernation_ops acpi_hibernation_ops = {
286 .start = acpi_hibernation_start,
287 .pre_snapshot = acpi_hibernation_prepare,
288 .finish = acpi_hibernation_finish,
278 .prepare = acpi_hibernation_prepare, 289 .prepare = acpi_hibernation_prepare,
279 .enter = acpi_hibernation_enter, 290 .enter = acpi_hibernation_enter,
280 .finish = acpi_hibernation_finish,
281 .pre_restore = acpi_hibernation_pre_restore, 291 .pre_restore = acpi_hibernation_pre_restore,
282 .restore_cleanup = acpi_hibernation_restore_cleanup, 292 .restore_cleanup = acpi_hibernation_restore_cleanup,
283}; 293};
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index dee416c5477f..0044483dd477 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -134,16 +134,42 @@ extern void mark_free_pages(struct zone *zone);
134 * 134 *
135 * All three methods must be assigned. 135 * All three methods must be assigned.
136 * 136 *
137 * @prepare: prepare system for hibernation 137 * @start: Tell the platform driver that we're starting hibernation.
138 * @enter: shut down system after state has been saved to disk 138 * Called right after shrinking memory and before freezing devices.
139 * @finish: finish/clean up after state has been reloaded 139 *
140 * @pre_restore: prepare system for the restoration from a hibernation image 140 * @pre_snapshot: Prepare the platform for creating the hibernation image.
141 * @restore_cleanup: clean up after a failing image restoration 141 * Called right after devices have been frozen and before the nonboot
142 * CPUs are disabled (runs with IRQs on).
143 *
144 * @finish: Restore the previous state of the platform after the hibernation
145 * image has been created *or* put the platform into the normal operation
146 * mode after the hibernation (the same method is executed in both cases).
147 * Called right after the nonboot CPUs have been enabled and before
148 * thawing devices (runs with IRQs on).
149 *
150 * @prepare: Prepare the platform for entering the low power state.
151 * Called right after the hibernation image has been saved and before
152 * devices are prepared for entering the low power state.
153 *
154 * @enter: Put the system into the low power state after the hibernation image
155 * has been saved to disk.
156 * Called after the nonboot CPUs have been disabled and all of the low
157 * level devices have been shut down (runs with IRQs off).
158 *
159 * @pre_restore: Prepare system for the restoration from a hibernation image.
160 * Called right after devices have been frozen and before the nonboot
161 * CPUs are disabled (runs with IRQs on).
162 *
163 * @restore_cleanup: Clean up after a failing image restoration.
164 * Called right after the nonboot CPUs have been enabled and before
165 * thawing devices (runs with IRQs on).
142 */ 166 */
143struct hibernation_ops { 167struct hibernation_ops {
168 int (*start)(void);
169 int (*pre_snapshot)(void);
170 void (*finish)(void);
144 int (*prepare)(void); 171 int (*prepare)(void);
145 int (*enter)(void); 172 int (*enter)(void);
146 void (*finish)(void);
147 int (*pre_restore)(void); 173 int (*pre_restore)(void);
148 void (*restore_cleanup)(void); 174 void (*restore_cleanup)(void);
149}; 175};
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index eb72255b5c86..d17bb14bce7b 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -54,8 +54,9 @@ static struct hibernation_ops *hibernation_ops;
54 54
55void hibernation_set_ops(struct hibernation_ops *ops) 55void hibernation_set_ops(struct hibernation_ops *ops)
56{ 56{
57 if (ops && !(ops->prepare && ops->enter && ops->finish 57 if (ops && !(ops->start && ops->pre_snapshot && ops->finish
58 && ops->pre_restore && ops->restore_cleanup)) { 58 && ops->prepare && ops->enter && ops->pre_restore
59 && ops->restore_cleanup)) {
59 WARN_ON(1); 60 WARN_ON(1);
60 return; 61 return;
61 } 62 }
@@ -69,16 +70,26 @@ void hibernation_set_ops(struct hibernation_ops *ops)
69 mutex_unlock(&pm_mutex); 70 mutex_unlock(&pm_mutex);
70} 71}
71 72
73/**
74 * platform_start - tell the platform driver that we're starting
75 * hibernation
76 */
77
78static int platform_start(int platform_mode)
79{
80 return (platform_mode && hibernation_ops) ?
81 hibernation_ops->start() : 0;
82}
72 83
73/** 84/**
74 * platform_prepare - prepare the machine for hibernation using the 85 * platform_pre_snapshot - prepare the machine for hibernation using the
75 * platform driver if so configured and return an error code if it fails 86 * platform driver if so configured and return an error code if it fails
76 */ 87 */
77 88
78static int platform_prepare(int platform_mode) 89static int platform_pre_snapshot(int platform_mode)
79{ 90{
80 return (platform_mode && hibernation_ops) ? 91 return (platform_mode && hibernation_ops) ?
81 hibernation_ops->prepare() : 0; 92 hibernation_ops->pre_snapshot() : 0;
82} 93}
83 94
84/** 95/**
@@ -135,12 +146,16 @@ int hibernation_snapshot(int platform_mode)
135 if (error) 146 if (error)
136 return error; 147 return error;
137 148
149 error = platform_start(platform_mode);
150 if (error)
151 return error;
152
138 suspend_console(); 153 suspend_console();
139 error = device_suspend(PMSG_FREEZE); 154 error = device_suspend(PMSG_FREEZE);
140 if (error) 155 if (error)
141 goto Resume_console; 156 goto Resume_console;
142 157
143 error = platform_prepare(platform_mode); 158 error = platform_pre_snapshot(platform_mode);
144 if (error) 159 if (error)
145 goto Resume_devices; 160 goto Resume_devices;
146 161