aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-02-01 22:29:57 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-02-01 22:29:57 -0500
commit687fcdf741e4a268c2c7bac8b3734de761bb9719 (patch)
tree82603cd0f892b13d4252cc525ecaec99bb86c0cd
parent215e871aaa3d94540121a3809d80d0c5e5686e4f (diff)
parenta6eb84bc1e069e1d285167e09035ed6c27978feb (diff)
Merge branch 'suspend' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'suspend' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (38 commits) suspend: cleanup reference to swsusp_pg_dir[] PM: Remove obsolete /sys/devices/.../power/state docs Hibernation: Invoke suspend notifications after console switch Suspend: Invoke suspend notifications after console switch Suspend: Clean up suspend_64.c Suspend: Add config option to disable the freezer if architecture wants that ACPI: Print message before calling _PTS ACPI hibernation: Call _PTS before suspending devices Hibernation: Introduce begin() and end() callbacks ACPI suspend: Call _PTS before suspending devices ACPI: Separate disabling of GPEs from _PTS ACPI: Separate invocations of _GTS and _BFS from _PTS and _WAK Suspend: Introduce begin() and end() callbacks suspend: fix ia64 allmodconfig build ACPI: clear GPE earily in resume to avoid warning Suspend: Clean up Kconfig (V2) Hibernation: Clean up Kconfig (V2) Hibernation: Update messages Suspend: Use common prefix in messages Hibernation: Remove unnecessary variable declaration ...
-rw-r--r--Documentation/kernel-parameters.txt5
-rw-r--r--Documentation/power/basic-pm-debugging.txt216
-rw-r--r--Documentation/power/devices.txt49
-rw-r--r--Documentation/power/drivers-testing.txt30
-rw-r--r--Documentation/power/notifiers.txt8
-rw-r--r--Documentation/power/userland-swsusp.txt82
-rw-r--r--arch/arm/Kconfig3
-rw-r--r--arch/arm/mach-at91/pm.c17
-rw-r--r--arch/blackfin/Kconfig4
-rw-r--r--arch/frv/Kconfig5
-rw-r--r--arch/mips/Kconfig4
-rw-r--r--arch/powerpc/Kconfig22
-rw-r--r--arch/powerpc/platforms/52xx/lite5200_pm.c10
-rw-r--r--arch/sh/Kconfig4
-rw-r--r--arch/x86/Kconfig8
-rw-r--r--arch/x86/kernel/suspend_64.c8
-rw-r--r--arch/x86/mm/init_32.c10
-rw-r--r--drivers/acpi/hardware/hwsleep.c79
-rw-r--r--drivers/acpi/sleep/main.c129
-rw-r--r--drivers/acpi/sleep/sleep.h2
-rw-r--r--drivers/base/power/Makefile2
-rw-r--r--include/acpi/acpixf.h2
-rw-r--r--include/linux/Kbuild1
-rw-r--r--include/linux/notifier.h2
-rw-r--r--include/linux/suspend.h56
-rw-r--r--include/linux/suspend_ioctls.h32
-rw-r--r--kernel/power/Kconfig65
-rw-r--r--kernel/power/disk.c204
-rw-r--r--kernel/power/main.c171
-rw-r--r--kernel/power/power.h90
-rw-r--r--kernel/power/snapshot.c31
-rw-r--r--kernel/power/swap.c33
-rw-r--r--kernel/power/swsusp.c48
-rw-r--r--kernel/power/user.c109
34 files changed, 1034 insertions, 507 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 92c40d174355..cf3868956f1e 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -168,6 +168,11 @@ and is between 256 and 4096 characters. It is defined in the file
168 acpi_irq_isa= [HW,ACPI] If irq_balance, mark listed IRQs used by ISA 168 acpi_irq_isa= [HW,ACPI] If irq_balance, mark listed IRQs used by ISA
169 Format: <irq>,<irq>... 169 Format: <irq>,<irq>...
170 170
171 acpi_new_pts_ordering [HW,ACPI]
172 Enforce the ACPI 2.0 ordering of the _PTS control
173 method wrt putting devices into low power states
174 default: pre ACPI 2.0 ordering of _PTS
175
171 acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT 176 acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT
172 177
173 acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS 178 acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS
diff --git a/Documentation/power/basic-pm-debugging.txt b/Documentation/power/basic-pm-debugging.txt
index 57aef2f6e0de..1555001bc733 100644
--- a/Documentation/power/basic-pm-debugging.txt
+++ b/Documentation/power/basic-pm-debugging.txt
@@ -1,45 +1,111 @@
1Debugging suspend and resume 1Debugging hibernation and suspend
2 (C) 2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL 2 (C) 2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL
3 3
41. Testing suspend to disk (STD) 41. Testing hibernation (aka suspend to disk or STD)
5 5
6To verify that the STD works, you can try to suspend in the "reboot" mode: 6To check if hibernation works, you can try to hibernate in the "reboot" mode:
7 7
8# echo reboot > /sys/power/disk 8# echo reboot > /sys/power/disk
9# echo disk > /sys/power/state 9# echo disk > /sys/power/state
10 10
11and the system should suspend, reboot, resume and get back to the command prompt 11and the system should create a hibernation image, reboot, resume and get back to
12where you have started the transition. If that happens, the STD is most likely 12the command prompt where you have started the transition. If that happens,
13to work correctly, but you need to repeat the test at least a couple of times in 13hibernation is most likely to work correctly. Still, you need to repeat the
14a row for confidence. This is necessary, because some problems only show up on 14test at least a couple of times in a row for confidence. [This is necessary,
15a second attempt at suspending and resuming the system. You should also test 15because some problems only show up on a second attempt at suspending and
16the "platform" and "shutdown" modes of suspend: 16resuming the system.] Moreover, hibernating in the "reboot" and "shutdown"
17modes causes the PM core to skip some platform-related callbacks which on ACPI
18systems might be necessary to make hibernation work. Thus, if you machine fails
19to hibernate or resume in the "reboot" mode, you should try the "platform" mode:
17 20
18# echo platform > /sys/power/disk 21# echo platform > /sys/power/disk
19# echo disk > /sys/power/state 22# echo disk > /sys/power/state
20 23
21or 24which is the default and recommended mode of hibernation.
25
26Unfortunately, the "platform" mode of hibernation does not work on some systems
27with broken BIOSes. In such cases the "shutdown" mode of hibernation might
28work:
22 29
23# echo shutdown > /sys/power/disk 30# echo shutdown > /sys/power/disk
24# echo disk > /sys/power/state 31# echo disk > /sys/power/state
25 32
26in which cases you will have to press the power button to make the system 33(it is similar to the "reboot" mode, but it requires you to press the power
27resume. If that does not work, you will need to identify what goes wrong. 34button to make the system resume).
35
36If neither "platform" nor "shutdown" hibernation mode works, you will need to
37identify what goes wrong.
38
39a) Test modes of hibernation
40
41To find out why hibernation fails on your system, you can use a special testing
42facility available if the kernel is compiled with CONFIG_PM_DEBUG set. Then,
43there is the file /sys/power/pm_test that can be used to make the hibernation
44core run in a test mode. There are 5 test modes available:
45
46freezer
47- test the freezing of processes
48
49devices
50- test the freezing of processes and suspending of devices
28 51
29a) Test mode of STD 52platform
53- test the freezing of processes, suspending of devices and platform
54 global control methods(*)
30 55
31To verify if there are any drivers that cause problems you can run the STD 56processors
32in the test mode: 57- test the freezing of processes, suspending of devices, platform
58 global control methods(*) and the disabling of nonboot CPUs
33 59
34# echo test > /sys/power/disk 60core
61- test the freezing of processes, suspending of devices, platform global
62 control methods(*), the disabling of nonboot CPUs and suspending of
63 platform/system devices
64
65(*) the platform global control methods are only available on ACPI systems
66 and are only tested if the hibernation mode is set to "platform"
67
68To use one of them it is necessary to write the corresponding string to
69/sys/power/pm_test (eg. "devices" to test the freezing of processes and
70suspending devices) and issue the standard hibernation commands. For example,
71to use the "devices" test mode along with the "platform" mode of hibernation,
72you should do the following:
73
74# echo devices > /sys/power/pm_test
75# echo platform > /sys/power/disk
35# echo disk > /sys/power/state 76# echo disk > /sys/power/state
36 77
37in which case the system should freeze tasks, suspend devices, disable nonboot 78Then, the kernel will try to freeze processes, suspend devices, wait 5 seconds,
38CPUs (if any), wait for 5 seconds, enable nonboot CPUs, resume devices, thaw 79resume devices and thaw processes. If "platform" is written to
39tasks and return to your command prompt. If that fails, most likely there is 80/sys/power/pm_test , then after suspending devices the kernel will additionally
40a driver that fails to either suspend or resume (in the latter case the system 81invoke the global control methods (eg. ACPI global control methods) used to
41may hang or be unstable after the test, so please take that into consideration). 82prepare the platform firmware for hibernation. Next, it will wait 5 seconds and
42To find this driver, you can carry out a binary search according to the rules: 83invoke the platform (eg. ACPI) global methods used to cancel hibernation etc.
84
85Writing "none" to /sys/power/pm_test causes the kernel to switch to the normal
86hibernation/suspend operations. Also, when open for reading, /sys/power/pm_test
87contains a space-separated list of all available tests (including "none" that
88represents the normal functionality) in which the current test level is
89indicated by square brackets.
90
91Generally, as you can see, each test level is more "invasive" than the previous
92one and the "core" level tests the hardware and drivers as deeply as possible
93without creating a hibernation image. Obviously, if the "devices" test fails,
94the "platform" test will fail as well and so on. Thus, as a rule of thumb, you
95should try the test modes starting from "freezer", through "devices", "platform"
96and "processors" up to "core" (repeat the test on each level a couple of times
97to make sure that any random factors are avoided).
98
99If the "freezer" test fails, there is a task that cannot be frozen (in that case
100it usually is possible to identify the offending task by analysing the output of
101dmesg obtained after the failing test). Failure at this level usually means
102that there is a problem with the tasks freezer subsystem that should be
103reported.
104
105If the "devices" test fails, most likely there is a driver that cannot suspend
106or resume its device (in the latter case the system may hang or become unstable
107after the test, so please take that into consideration). To find this driver,
108you can carry out a binary search according to the rules:
43- if the test fails, unload a half of the drivers currently loaded and repeat 109- if the test fails, unload a half of the drivers currently loaded and repeat
44(that would probably involve rebooting the system, so always note what drivers 110(that would probably involve rebooting the system, so always note what drivers
45have been loaded before the test), 111have been loaded before the test),
@@ -47,23 +113,46 @@ have been loaded before the test),
47recently and repeat. 113recently and repeat.
48 114
49Once you have found the failing driver (there can be more than just one of 115Once you have found the failing driver (there can be more than just one of
50them), you have to unload it every time before the STD transition. In that case 116them), you have to unload it every time before hibernation. In that case please
51please make sure to report the problem with the driver. 117make sure to report the problem with the driver.
52 118
53It is also possible that a cycle can still fail after you have unloaded 119It is also possible that the "devices" test will still fail after you have
54all modules. In that case, you would want to look in your kernel configuration 120unloaded all modules. In that case, you may want to look in your kernel
55for the drivers that can be compiled as modules (testing again with them as 121configuration for the drivers that can be compiled as modules (and test again
56modules), and possibly also try boot time options such as "noapic" or "noacpi". 122with these drivers compiled as modules). You may also try to use some special
123kernel command line options such as "noapic", "noacpi" or even "acpi=off".
124
125If the "platform" test fails, there is a problem with the handling of the
126platform (eg. ACPI) firmware on your system. In that case the "platform" mode
127of hibernation is not likely to work. You can try the "shutdown" mode, but that
128is rather a poor man's workaround.
129
130If the "processors" test fails, the disabling/enabling of nonboot CPUs does not
131work (of course, this only may be an issue on SMP systems) and the problem
132should be reported. In that case you can also try to switch the nonboot CPUs
133off and on using the /sys/devices/system/cpu/cpu*/online sysfs attributes and
134see if that works.
135
136If the "core" test fails, which means that suspending of the system/platform
137devices has failed (these devices are suspended on one CPU with interrupts off),
138the problem is most probably hardware-related and serious, so it should be
139reported.
140
141A failure of any of the "platform", "processors" or "core" tests may cause your
142system to hang or become unstable, so please beware. Such a failure usually
143indicates a serious problem that very well may be related to the hardware, but
144please report it anyway.
57 145
58b) Testing minimal configuration 146b) Testing minimal configuration
59 147
60If the test mode of STD works, you can boot the system with "init=/bin/bash" 148If all of the hibernation test modes work, you can boot the system with the
61and attempt to suspend in the "reboot", "shutdown" and "platform" modes. If 149"init=/bin/bash" command line parameter and attempt to hibernate in the
62that does not work, there probably is a problem with a driver statically 150"reboot", "shutdown" and "platform" modes. If that does not work, there
63compiled into the kernel and you can try to compile more drivers as modules, 151probably is a problem with a driver statically compiled into the kernel and you
64so that they can be tested individually. Otherwise, there is a problem with a 152can try to compile more drivers as modules, so that they can be tested
65modular driver and you can find it by loading a half of the modules you normally 153individually. Otherwise, there is a problem with a modular driver and you can
66use and binary searching in accordance with the algorithm: 154find it by loading a half of the modules you normally use and binary searching
155in accordance with the algorithm:
67- if there are n modules loaded and the attempt to suspend and resume fails, 156- if there are n modules loaded and the attempt to suspend and resume fails,
68unload n/2 of the modules and try again (that would probably involve rebooting 157unload n/2 of the modules and try again (that would probably involve rebooting
69the system), 158the system),
@@ -71,19 +160,19 @@ the system),
71load n/2 modules more and try again. 160load n/2 modules more and try again.
72 161
73Again, if you find the offending module(s), it(they) must be unloaded every time 162Again, if you find the offending module(s), it(they) must be unloaded every time
74before the STD transition, and please report the problem with it(them). 163before hibernation, and please report the problem with it(them).
75 164
76c) Advanced debugging 165c) Advanced debugging
77 166
78In case the STD does not work on your system even in the minimal configuration 167In case that hibernation does not work on your system even in the minimal
79and compiling more drivers as modules is not practical or some modules cannot 168configuration and compiling more drivers as modules is not practical or some
80be unloaded, you can use one of the more advanced debugging techniques to find 169modules cannot be unloaded, you can use one of the more advanced debugging
81the problem. First, if there is a serial port in your box, you can boot the 170techniques to find the problem. First, if there is a serial port in your box,
82kernel with the 'no_console_suspend' parameter and try to log kernel 171you can boot the kernel with the 'no_console_suspend' parameter and try to log
83messages using the serial console. This may provide you with some information 172kernel messages using the serial console. This may provide you with some
84about the reasons of the suspend (resume) failure. Alternatively, it may be 173information about the reasons of the suspend (resume) failure. Alternatively,
85possible to use a FireWire port for debugging with firescope 174it may be possible to use a FireWire port for debugging with firescope
86(ftp://ftp.firstfloor.org/pub/ak/firescope/). On i386 it is also possible to 175(ftp://ftp.firstfloor.org/pub/ak/firescope/). On x86 it is also possible to
87use the PM_TRACE mechanism documented in Documentation/s2ram.txt . 176use the PM_TRACE mechanism documented in Documentation/s2ram.txt .
88 177
892. Testing suspend to RAM (STR) 1782. Testing suspend to RAM (STR)
@@ -91,16 +180,25 @@ use the PM_TRACE mechanism documented in Documentation/s2ram.txt .
91To verify that the STR works, it is generally more convenient to use the s2ram 180To verify that the STR works, it is generally more convenient to use the s2ram
92tool available from http://suspend.sf.net and documented at 181tool available from http://suspend.sf.net and documented at
93http://en.opensuse.org/s2ram . However, before doing that it is recommended to 182http://en.opensuse.org/s2ram . However, before doing that it is recommended to
94carry out the procedure described in section 1. 183carry out STR testing using the facility described in section 1.
95 184
96Assume you have resolved the problems with the STD and you have found some 185Namely, after writing "freezer", "devices", "platform", "processors", or "core"
97failing drivers. These drivers are also likely to fail during the STR or 186into /sys/power/pm_test (available if the kernel is compiled with
98during the resume, so it is better to unload them every time before the STR 187CONFIG_PM_DEBUG set) the suspend code will work in the test mode corresponding
99transition. Now, you can follow the instructions at 188to given string. The STR test modes are defined in the same way as for
100http://en.opensuse.org/s2ram to test the system, but if it does not work 189hibernation, so please refer to Section 1 for more information about them. In
101"out of the box", you may need to boot it with "init=/bin/bash" and test 190particular, the "core" test allows you to test everything except for the actual
102s2ram in the minimal configuration. In that case, you may be able to search 191invocation of the platform firmware in order to put the system into the sleep
103for failing drivers by following the procedure analogous to the one described in 192state.
1041b). If you find some failing drivers, you will have to unload them every time 193
105before the STR transition (ie. before you run s2ram), and please report the 194Among other things, the testing with the help of /sys/power/pm_test may allow
106problems with them. 195you to identify drivers that fail to suspend or resume their devices. They
196should be unloaded every time before an STR transition.
197
198Next, you can follow the instructions at http://en.opensuse.org/s2ram to test
199the system, but if it does not work "out of the box", you may need to boot it
200with "init=/bin/bash" and test s2ram in the minimal configuration. In that
201case, you may be able to search for failing drivers by following the procedure
202analogous to the one described in section 1. If you find some failing drivers,
203you will have to unload them every time before an STR transition (ie. before
204you run s2ram), and please report the problems with them.
diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt
index d0e79d5820a5..c53d26361919 100644
--- a/Documentation/power/devices.txt
+++ b/Documentation/power/devices.txt
@@ -502,52 +502,3 @@ If the CPU can have a "cpufreq" driver, there also may be opportunities
502to shift to lower voltage settings and reduce the power cost of executing 502to shift to lower voltage settings and reduce the power cost of executing
503a given number of instructions. (Without voltage adjustment, it's rare 503a given number of instructions. (Without voltage adjustment, it's rare
504for cpufreq to save much power; the cost-per-instruction must go down.) 504for cpufreq to save much power; the cost-per-instruction must go down.)
505
506
507/sys/devices/.../power/state files
508==================================
509For now you can also test some of this functionality using sysfs.
510
511 DEPRECATED: USE "power/state" ONLY FOR DRIVER TESTING, AND
512 AVOID USING dev->power.power_state IN DRIVERS.
513
514 THESE WILL BE REMOVED. IF THE "power/state" FILE GETS REPLACED,
515 IT WILL BECOME SOMETHING COUPLED TO THE BUS OR DRIVER.
516
517In each device's directory, there is a 'power' directory, which contains
518at least a 'state' file. The value of this field is effectively boolean,
519PM_EVENT_ON or PM_EVENT_SUSPEND.
520
521 * Reading from this file displays a value corresponding to
522 the power.power_state.event field. All nonzero values are
523 displayed as "2", corresponding to a low power state; zero
524 is displayed as "0", corresponding to normal operation.
525
526 * Writing to this file initiates a transition using the
527 specified event code number; only '0', '2', and '3' are
528 accepted (without a newline); '2' and '3' are both
529 mapped to PM_EVENT_SUSPEND.
530
531On writes, the PM core relies on that recorded event code and the device/bus
532capabilities to determine whether it uses a partial suspend() or resume()
533sequence to change things so that the recorded event corresponds to the
534numeric parameter.
535
536 - If the bus requires the irqs-disabled suspend_late()/resume_early()
537 phases, writes fail because those operations are not supported here.
538
539 - If the recorded value is the expected value, nothing is done.
540
541 - If the recorded value is nonzero, the device is partially resumed,
542 using the bus.resume() and/or class.resume() methods.
543
544 - If the target value is nonzero, the device is partially suspended,
545 using the class.suspend() and/or bus.suspend() methods and the
546 PM_EVENT_SUSPEND message.
547
548Drivers have no way to tell whether their suspend() and resume() calls
549have come through the sysfs power/state file or as part of entering a
550system sleep state, except that when accessed through sysfs the normal
551parent/child sequencing rules are ignored. Drivers (such as bus, bridge,
552or hub drivers) which expose child devices may need to enforce those rules
553on their own.
diff --git a/Documentation/power/drivers-testing.txt b/Documentation/power/drivers-testing.txt
index e4bdcaee24e4..7f7a737f7f9f 100644
--- a/Documentation/power/drivers-testing.txt
+++ b/Documentation/power/drivers-testing.txt
@@ -6,9 +6,9 @@ Testing suspend and resume support in device drivers
6Unfortunately, to effectively test the support for the system-wide suspend and 6Unfortunately, to effectively test the support for the system-wide suspend and
7resume transitions in a driver, it is necessary to suspend and resume a fully 7resume transitions in a driver, it is necessary to suspend and resume a fully
8functional system with this driver loaded. Moreover, that should be done 8functional system with this driver loaded. Moreover, that should be done
9several times, preferably several times in a row, and separately for the suspend 9several times, preferably several times in a row, and separately for hibernation
10to disk (STD) and the suspend to RAM (STR) transitions, because each of these 10(aka suspend to disk or STD) and suspend to RAM (STR), because each of these
11cases involves different ordering of operations and different interactions with 11cases involves slightly different operations and different interactions with
12the machine's BIOS. 12the machine's BIOS.
13 13
14Of course, for this purpose the test system has to be known to suspend and 14Of course, for this purpose the test system has to be known to suspend and
@@ -22,20 +22,24 @@ for more information about the debugging of suspend/resume functionality.
22Once you have resolved the suspend/resume-related problems with your test system 22Once you have resolved the suspend/resume-related problems with your test system
23without the new driver, you are ready to test it: 23without the new driver, you are ready to test it:
24 24
25a) Build the driver as a module, load it and try the STD in the test mode (see: 25a) Build the driver as a module, load it and try the test modes of hibernation
26Documents/power/basic-pm-debugging.txt, 1a)). 26 (see: Documents/power/basic-pm-debugging.txt, 1).
27 27
28b) Load the driver and attempt to suspend to disk in the "reboot", "shutdown" 28b) Load the driver and attempt to hibernate in the "reboot", "shutdown" and
29and "platform" modes (see: Documents/power/basic-pm-debugging.txt, 1). 29 "platform" modes (see: Documents/power/basic-pm-debugging.txt, 1).
30 30
31c) Compile the driver directly into the kernel and try the STD in the test mode. 31c) Compile the driver directly into the kernel and try the test modes of
32 hibernation.
32 33
33d) Attempt to suspend to disk with the driver compiled directly into the kernel 34d) Attempt to hibernate with the driver compiled directly into the kernel
34in the "reboot", "shutdown" and "platform" modes. 35 in the "reboot", "shutdown" and "platform" modes.
35 36
36e) Attempt to suspend to RAM using the s2ram tool with the driver loaded (see: 37e) Try the test modes of suspend (see: Documents/power/basic-pm-debugging.txt,
37Documents/power/basic-pm-debugging.txt, 2). As far as the STR tests are 38 2). [As far as the STR tests are concerned, it should not matter whether or
38concerned, it should not matter whether or not the driver is built as a module. 39 not the driver is built as a module.]
40
41f) Attempt to suspend to RAM using the s2ram tool with the driver loaded
42 (see: Documents/power/basic-pm-debugging.txt, 2).
39 43
40Each of the above tests should be repeated several times and the STD tests 44Each of the above tests should be repeated several times and the STD tests
41should be mixed with the STR tests. If any of them fails, the driver cannot be 45should be mixed with the STR tests. If any of them fails, the driver cannot be
diff --git a/Documentation/power/notifiers.txt b/Documentation/power/notifiers.txt
index 9293e4bc857c..ae1b7ec07684 100644
--- a/Documentation/power/notifiers.txt
+++ b/Documentation/power/notifiers.txt
@@ -28,6 +28,14 @@ PM_POST_HIBERNATION The system memory state has been restored from a
28 hibernation. Device drivers' .resume() callbacks have 28 hibernation. Device drivers' .resume() callbacks have
29 been executed and tasks have been thawed. 29 been executed and tasks have been thawed.
30 30
31PM_RESTORE_PREPARE The system is going to restore a hibernation image.
32 If all goes well the restored kernel will issue a
33 PM_POST_HIBERNATION notification.
34
35PM_POST_RESTORE An error occurred during the hibernation restore.
36 Device drivers' .resume() callbacks have been executed
37 and tasks have been thawed.
38
31PM_SUSPEND_PREPARE The system is preparing for a suspend. 39PM_SUSPEND_PREPARE The system is preparing for a suspend.
32 40
33PM_POST_SUSPEND The system has just resumed or an error occured during 41PM_POST_SUSPEND The system has just resumed or an error occured during
diff --git a/Documentation/power/userland-swsusp.txt b/Documentation/power/userland-swsusp.txt
index e00c6cf09e85..7b99636564c8 100644
--- a/Documentation/power/userland-swsusp.txt
+++ b/Documentation/power/userland-swsusp.txt
@@ -14,7 +14,7 @@ are going to develop your own suspend/resume utilities.
14 14
15The interface consists of a character device providing the open(), 15The interface consists of a character device providing the open(),
16release(), read(), and write() operations as well as several ioctl() 16release(), read(), and write() operations as well as several ioctl()
17commands defined in kernel/power/power.h. The major and minor 17commands defined in include/linux/suspend_ioctls.h . The major and minor
18numbers of the device are, respectively, 10 and 231, and they can 18numbers of the device are, respectively, 10 and 231, and they can
19be read from /sys/class/misc/snapshot/dev. 19be read from /sys/class/misc/snapshot/dev.
20 20
@@ -27,17 +27,17 @@ once at a time.
27The ioctl() commands recognized by the device are: 27The ioctl() commands recognized by the device are:
28 28
29SNAPSHOT_FREEZE - freeze user space processes (the current process is 29SNAPSHOT_FREEZE - freeze user space processes (the current process is
30 not frozen); this is required for SNAPSHOT_ATOMIC_SNAPSHOT 30 not frozen); this is required for SNAPSHOT_CREATE_IMAGE
31 and SNAPSHOT_ATOMIC_RESTORE to succeed 31 and SNAPSHOT_ATOMIC_RESTORE to succeed
32 32
33SNAPSHOT_UNFREEZE - thaw user space processes frozen by SNAPSHOT_FREEZE 33SNAPSHOT_UNFREEZE - thaw user space processes frozen by SNAPSHOT_FREEZE
34 34
35SNAPSHOT_ATOMIC_SNAPSHOT - create a snapshot of the system memory; the 35SNAPSHOT_CREATE_IMAGE - create a snapshot of the system memory; the
36 last argument of ioctl() should be a pointer to an int variable, 36 last argument of ioctl() should be a pointer to an int variable,
37 the value of which will indicate whether the call returned after 37 the value of which will indicate whether the call returned after
38 creating the snapshot (1) or after restoring the system memory state 38 creating the snapshot (1) or after restoring the system memory state
39 from it (0) (after resume the system finds itself finishing the 39 from it (0) (after resume the system finds itself finishing the
40 SNAPSHOT_ATOMIC_SNAPSHOT ioctl() again); after the snapshot 40 SNAPSHOT_CREATE_IMAGE ioctl() again); after the snapshot
41 has been created the read() operation can be used to transfer 41 has been created the read() operation can be used to transfer
42 it out of the kernel 42 it out of the kernel
43 43
@@ -49,39 +49,37 @@ SNAPSHOT_ATOMIC_RESTORE - restore the system memory state from the
49 49
50SNAPSHOT_FREE - free memory allocated for the snapshot image 50SNAPSHOT_FREE - free memory allocated for the snapshot image
51 51
52SNAPSHOT_SET_IMAGE_SIZE - set the preferred maximum size of the image 52SNAPSHOT_PREF_IMAGE_SIZE - set the preferred maximum size of the image
53 (the kernel will do its best to ensure the image size will not exceed 53 (the kernel will do its best to ensure the image size will not exceed
54 this number, but if it turns out to be impossible, the kernel will 54 this number, but if it turns out to be impossible, the kernel will
55 create the smallest image possible) 55 create the smallest image possible)
56 56
57SNAPSHOT_AVAIL_SWAP - return the amount of available swap in bytes (the last 57SNAPSHOT_GET_IMAGE_SIZE - return the actual size of the hibernation image
58 argument should be a pointer to an unsigned int variable that will 58
59SNAPSHOT_AVAIL_SWAP_SIZE - return the amount of available swap in bytes (the
60 last argument should be a pointer to an unsigned int variable that will
59 contain the result if the call is successful). 61 contain the result if the call is successful).
60 62
61SNAPSHOT_GET_SWAP_PAGE - allocate a swap page from the resume partition 63SNAPSHOT_ALLOC_SWAP_PAGE - allocate a swap page from the resume partition
62 (the last argument should be a pointer to a loff_t variable that 64 (the last argument should be a pointer to a loff_t variable that
63 will contain the swap page offset if the call is successful) 65 will contain the swap page offset if the call is successful)
64 66
65SNAPSHOT_FREE_SWAP_PAGES - free all swap pages allocated with 67SNAPSHOT_FREE_SWAP_PAGES - free all swap pages allocated by
66 SNAPSHOT_GET_SWAP_PAGE 68 SNAPSHOT_ALLOC_SWAP_PAGE
67
68SNAPSHOT_SET_SWAP_FILE - set the resume partition (the last ioctl() argument
69 should specify the device's major and minor numbers in the old
70 two-byte format, as returned by the stat() function in the .st_rdev
71 member of the stat structure)
72 69
73SNAPSHOT_SET_SWAP_AREA - set the resume partition and the offset (in <PAGE_SIZE> 70SNAPSHOT_SET_SWAP_AREA - set the resume partition and the offset (in <PAGE_SIZE>
74 units) from the beginning of the partition at which the swap header is 71 units) from the beginning of the partition at which the swap header is
75 located (the last ioctl() argument should point to a struct 72 located (the last ioctl() argument should point to a struct
76 resume_swap_area, as defined in kernel/power/power.h, containing the 73 resume_swap_area, as defined in kernel/power/suspend_ioctls.h,
77 resume device specification, as for the SNAPSHOT_SET_SWAP_FILE ioctl(), 74 containing the resume device specification and the offset); for swap
78 and the offset); for swap partitions the offset is always 0, but it is 75 partitions the offset is always 0, but it is different from zero for
79 different to zero for swap files (please see 76 swap files (see Documentation/swsusp-and-swap-files.txt for details).
80 Documentation/swsusp-and-swap-files.txt for details). 77
81 The SNAPSHOT_SET_SWAP_AREA ioctl() is considered as a replacement for 78SNAPSHOT_PLATFORM_SUPPORT - enable/disable the hibernation platform support,
82 SNAPSHOT_SET_SWAP_FILE which is regarded as obsolete. It is 79 depending on the argument value (enable, if the argument is nonzero)
83 recommended to always use this call, because the code to set the resume 80
84 partition may be removed from future kernels 81SNAPSHOT_POWER_OFF - make the kernel transition the system to the hibernation
82 state (eg. ACPI S4) using the platform (eg. ACPI) driver
85 83
86SNAPSHOT_S2RAM - suspend to RAM; using this call causes the kernel to 84SNAPSHOT_S2RAM - suspend to RAM; using this call causes the kernel to
87 immediately enter the suspend-to-RAM state, so this call must always 85 immediately enter the suspend-to-RAM state, so this call must always
@@ -93,24 +91,6 @@ SNAPSHOT_S2RAM - suspend to RAM; using this call causes the kernel to
93 to resume the system from RAM if there's enough battery power or restore 91 to resume the system from RAM if there's enough battery power or restore
94 its state on the basis of the saved suspend image otherwise) 92 its state on the basis of the saved suspend image otherwise)
95 93
96SNAPSHOT_PMOPS - enable the usage of the hibernation_ops->prepare,
97 hibernate_ops->enter and hibernation_ops->finish methods (the in-kernel
98 swsusp knows these as the "platform method") which are needed on many
99 machines to (among others) speed up the resume by letting the BIOS skip
100 some steps or to let the system recognise the correct state of the
101 hardware after the resume (in particular on many machines this ensures
102 that unplugged AC adapters get correctly detected and that kacpid does
103 not run wild after the resume). The last ioctl() argument can take one
104 of the three values, defined in kernel/power/power.h:
105 PMOPS_PREPARE - make the kernel carry out the
106 hibernation_ops->prepare() operation
107 PMOPS_ENTER - make the kernel power off the system by calling
108 hibernation_ops->enter()
109 PMOPS_FINISH - make the kernel carry out the
110 hibernation_ops->finish() operation
111 Note that the actual constants are misnamed because they surface
112 internal kernel implementation details that have changed.
113
114The device's read() operation can be used to transfer the snapshot image from 94The device's read() operation can be used to transfer the snapshot image from
115the kernel. It has the following limitations: 95the kernel. It has the following limitations:
116- you cannot read() more than one virtual memory page at a time 96- you cannot read() more than one virtual memory page at a time
@@ -122,7 +102,7 @@ The device's write() operation is used for uploading the system memory snapshot
122into the kernel. It has the same limitations as the read() operation. 102into the kernel. It has the same limitations as the read() operation.
123 103
124The release() operation frees all memory allocated for the snapshot image 104The release() operation frees all memory allocated for the snapshot image
125and all swap pages allocated with SNAPSHOT_GET_SWAP_PAGE (if any). 105and all swap pages allocated with SNAPSHOT_ALLOC_SWAP_PAGE (if any).
126Thus it is not necessary to use either SNAPSHOT_FREE or 106Thus it is not necessary to use either SNAPSHOT_FREE or
127SNAPSHOT_FREE_SWAP_PAGES before closing the device (in fact it will also 107SNAPSHOT_FREE_SWAP_PAGES before closing the device (in fact it will also
128unfreeze user space processes frozen by SNAPSHOT_UNFREEZE if they are 108unfreeze user space processes frozen by SNAPSHOT_UNFREEZE if they are
@@ -133,16 +113,12 @@ snapshot image from/to the kernel will use a swap parition, called the resume
133partition, or a swap file as storage space (if a swap file is used, the resume 113partition, or a swap file as storage space (if a swap file is used, the resume
134partition is the partition that holds this file). However, this is not really 114partition is the partition that holds this file). However, this is not really
135required, as they can use, for example, a special (blank) suspend partition or 115required, as they can use, for example, a special (blank) suspend partition or
136a file on a partition that is unmounted before SNAPSHOT_ATOMIC_SNAPSHOT and 116a file on a partition that is unmounted before SNAPSHOT_CREATE_IMAGE and
137mounted afterwards. 117mounted afterwards.
138 118
139These utilities SHOULD NOT make any assumptions regarding the ordering of 119These utilities MUST NOT make any assumptions regarding the ordering of
140data within the snapshot image, except for the image header that MAY be 120data within the snapshot image. The contents of the image are entirely owned
141assumed to start with an swsusp_info structure, as specified in 121by the kernel and its structure may be changed in future kernel releases.
142kernel/power/power.h. This structure MAY be used by the userland utilities
143to obtain some information about the snapshot image, such as the size
144of the snapshot image, including the metadata and the header itself,
145contained in the .size member of swsusp_info.
146 122
147The snapshot image MUST be written to the kernel unaltered (ie. all of the image 123The snapshot image MUST be written to the kernel unaltered (ie. all of the image
148data, metadata and header MUST be written in _exactly_ the same amount, form 124data, metadata and header MUST be written in _exactly_ the same amount, form
@@ -159,7 +135,7 @@ means, such as checksums, to ensure the integrity of the snapshot image.
159The suspending and resuming utilities MUST lock themselves in memory, 135The suspending and resuming utilities MUST lock themselves in memory,
160preferrably using mlockall(), before calling SNAPSHOT_FREEZE. 136preferrably using mlockall(), before calling SNAPSHOT_FREEZE.
161 137
162The suspending utility MUST check the value stored by SNAPSHOT_ATOMIC_SNAPSHOT 138The suspending utility MUST check the value stored by SNAPSHOT_CREATE_IMAGE
163in the memory location pointed to by the last argument of ioctl() and proceed 139in the memory location pointed to by the last argument of ioctl() and proceed
164in accordance with it: 140in accordance with it:
1651. If the value is 1 (ie. the system memory snapshot has just been 1411. If the value is 1 (ie. the system memory snapshot has just been
@@ -173,7 +149,7 @@ in accordance with it:
173 image has been saved. 149 image has been saved.
174 (b) The suspending utility SHOULD NOT attempt to perform any 150 (b) The suspending utility SHOULD NOT attempt to perform any
175 file system operations (including reads) on the file systems 151 file system operations (including reads) on the file systems
176 that were mounted before SNAPSHOT_ATOMIC_SNAPSHOT has been 152 that were mounted before SNAPSHOT_CREATE_IMAGE has been
177 called. However, it MAY mount a file system that was not 153 called. However, it MAY mount a file system that was not
178 mounted at that time and perform some operations on it (eg. 154 mounted at that time and perform some operations on it (eg.
179 use it for saving the image). 155 use it for saving the image).
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5d5997ca7011..4b1a8e3d292c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1030,6 +1030,9 @@ menu "Power management options"
1030 1030
1031source "kernel/power/Kconfig" 1031source "kernel/power/Kconfig"
1032 1032
1033config ARCH_SUSPEND_POSSIBLE
1034 def_bool y
1035
1033endmenu 1036endmenu
1034 1037
1035source "net/Kconfig" 1038source "net/Kconfig"
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 4b120cc36135..a67defd50438 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -52,7 +52,7 @@ static suspend_state_t target_state;
52/* 52/*
53 * Called after processes are frozen, but before we shutdown devices. 53 * Called after processes are frozen, but before we shutdown devices.
54 */ 54 */
55static int at91_pm_set_target(suspend_state_t state) 55static int at91_pm_begin(suspend_state_t state)
56{ 56{
57 target_state = state; 57 target_state = state;
58 return 0; 58 return 0;
@@ -202,11 +202,20 @@ error:
202 return 0; 202 return 0;
203} 203}
204 204
205/*
206 * Called right prior to thawing processes.
207 */
208static void at91_pm_end(void)
209{
210 target_state = PM_SUSPEND_ON;
211}
212
205 213
206static struct platform_suspend_ops at91_pm_ops ={ 214static struct platform_suspend_ops at91_pm_ops ={
207 .valid = at91_pm_valid_state, 215 .valid = at91_pm_valid_state,
208 .set_target = at91_pm_set_target, 216 .begin = at91_pm_begin,
209 .enter = at91_pm_enter, 217 .enter = at91_pm_enter,
218 .end = at91_pm_end,
210}; 219};
211 220
212static int __init at91_pm_init(void) 221static int __init at91_pm_init(void)
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index fc7ca86ac8bf..4802eb767dc9 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -898,6 +898,10 @@ endmenu
898menu "Power management options" 898menu "Power management options"
899source "kernel/power/Kconfig" 899source "kernel/power/Kconfig"
900 900
901config ARCH_SUSPEND_POSSIBLE
902 def_bool y
903 depends on !SMP
904
901choice 905choice
902 prompt "Select PM Wakeup Event Source" 906 prompt "Select PM Wakeup Event Source"
903 default PM_WAKEUP_GPIO_BY_SIC_IWR 907 default PM_WAKEUP_GPIO_BY_SIC_IWR
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index afb19b0d761d..e3f965c91e22 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -352,6 +352,11 @@ source "drivers/pcmcia/Kconfig"
352# should probably wait a while. 352# should probably wait a while.
353 353
354menu "Power management options" 354menu "Power management options"
355
356config ARCH_SUSPEND_POSSIBLE
357 def_bool y
358 depends on !SMP
359
355source kernel/power/Kconfig 360source kernel/power/Kconfig
356endmenu 361endmenu
357 362
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 09e7bf3723df..36a4018f71d2 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2081,6 +2081,10 @@ endmenu
2081 2081
2082menu "Power management options" 2082menu "Power management options"
2083 2083
2084config ARCH_SUSPEND_POSSIBLE
2085 def_bool y
2086 depends on !SMP
2087
2084source "kernel/power/Kconfig" 2088source "kernel/power/Kconfig"
2085 2089
2086endmenu 2090endmenu
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 9c44af3db8d9..4a22c9928618 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -151,11 +151,25 @@ config DEFAULT_UIMAGE
151config REDBOOT 151config REDBOOT
152 bool 152 bool
153 153
154config PPC64_SWSUSP 154config HIBERNATE_32
155 bool 155 bool
156 depends on PPC64 && (BROKEN || (PPC_PMAC64 && EXPERIMENTAL)) 156 depends on (PPC_PMAC && !SMP) || BROKEN
157 default y 157 default y
158 158
159config HIBERNATE_64
160 bool
161 depends on BROKEN || (PPC_PMAC64 && EXPERIMENTAL)
162 default y
163
164config ARCH_HIBERNATION_POSSIBLE
165 bool
166 depends on (PPC64 && HIBERNATE_64) || (PPC32 && HIBERNATE_32)
167 default y
168
169config ARCH_SUSPEND_POSSIBLE
170 def_bool y
171 depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200
172
159config PPC_DCR_NATIVE 173config PPC_DCR_NATIVE
160 bool 174 bool
161 default n 175 default n
@@ -391,6 +405,10 @@ config CMDLINE
391 most cases you will need to specify the root device here. 405 most cases you will need to specify the root device here.
392 406
393if !44x || BROKEN 407if !44x || BROKEN
408config ARCH_WANTS_FREEZER_CONTROL
409 def_bool y
410 depends on ADB_PMU
411
394source kernel/power/Kconfig 412source kernel/power/Kconfig
395endif 413endif
396 414
diff --git a/arch/powerpc/platforms/52xx/lite5200_pm.c b/arch/powerpc/platforms/52xx/lite5200_pm.c
index c0f13e8deb0b..41c7fd91e99e 100644
--- a/arch/powerpc/platforms/52xx/lite5200_pm.c
+++ b/arch/powerpc/platforms/52xx/lite5200_pm.c
@@ -31,7 +31,7 @@ static int lite5200_pm_valid(suspend_state_t state)
31 } 31 }
32} 32}
33 33
34static int lite5200_pm_set_target(suspend_state_t state) 34static int lite5200_pm_begin(suspend_state_t state)
35{ 35{
36 if (lite5200_pm_valid(state)) { 36 if (lite5200_pm_valid(state)) {
37 lite5200_pm_target_state = state; 37 lite5200_pm_target_state = state;
@@ -219,12 +219,18 @@ static void lite5200_pm_finish(void)
219 mpc52xx_pm_finish(); 219 mpc52xx_pm_finish();
220} 220}
221 221
222static void lite5200_pm_end(void)
223{
224 lite5200_pm_target_state = PM_SUSPEND_ON;
225}
226
222static struct platform_suspend_ops lite5200_pm_ops = { 227static struct platform_suspend_ops lite5200_pm_ops = {
223 .valid = lite5200_pm_valid, 228 .valid = lite5200_pm_valid,
224 .set_target = lite5200_pm_set_target, 229 .begin = lite5200_pm_begin,
225 .prepare = lite5200_pm_prepare, 230 .prepare = lite5200_pm_prepare,
226 .enter = lite5200_pm_enter, 231 .enter = lite5200_pm_enter,
227 .finish = lite5200_pm_finish, 232 .finish = lite5200_pm_finish,
233 .end = lite5200_pm_end,
228}; 234};
229 235
230int __init lite5200_pm_init(void) 236int __init lite5200_pm_init(void)
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 1cd9c8fd927d..b30c4c376a83 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -882,6 +882,10 @@ endmenu
882menu "Power management options (EXPERIMENTAL)" 882menu "Power management options (EXPERIMENTAL)"
883depends on EXPERIMENTAL && SYS_SUPPORTS_PM 883depends on EXPERIMENTAL && SYS_SUPPORTS_PM
884 884
885config ARCH_SUSPEND_POSSIBLE
886 def_bool y
887 depends on !SMP
888
885source kernel/power/Kconfig 889source kernel/power/Kconfig
886 890
887endmenu 891endmenu
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index bb07f87d8622..7109037bdf7c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -112,6 +112,14 @@ config ARCH_SUPPORTS_OPROFILE
112 112
113select HAVE_KVM 113select HAVE_KVM
114 114
115config ARCH_HIBERNATION_POSSIBLE
116 def_bool y
117 depends on !SMP || !X86_VOYAGER
118
119config ARCH_SUSPEND_POSSIBLE
120 def_bool y
121 depends on !X86_VOYAGER
122
115config ZONE_DMA32 123config ZONE_DMA32
116 bool 124 bool
117 default X86_64 125 default X86_64
diff --git a/arch/x86/kernel/suspend_64.c b/arch/x86/kernel/suspend_64.c
index 09199511c256..7ac7130022f1 100644
--- a/arch/x86/kernel/suspend_64.c
+++ b/arch/x86/kernel/suspend_64.c
@@ -140,7 +140,12 @@ static void fix_processor_context(void)
140 int cpu = smp_processor_id(); 140 int cpu = smp_processor_id();
141 struct tss_struct *t = &per_cpu(init_tss, cpu); 141 struct tss_struct *t = &per_cpu(init_tss, cpu);
142 142
143 set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */ 143 /*
144 * This just modifies memory; should not be necessary. But... This
145 * is necessary, because 386 hardware has concept of busy TSS or some
146 * similar stupidity.
147 */
148 set_tss_desc(cpu, t);
144 149
145 get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9; 150 get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
146 151
@@ -160,7 +165,6 @@ static void fix_processor_context(void)
160 loaddebug(&current->thread, 6); 165 loaddebug(&current->thread, 6);
161 loaddebug(&current->thread, 7); 166 loaddebug(&current->thread, 7);
162 } 167 }
163
164} 168}
165 169
166#ifdef CONFIG_HIBERNATION 170#ifdef CONFIG_HIBERNATION
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index da524fb22422..f2f36f8dae52 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -423,23 +423,23 @@ static void __init pagetable_init(void)
423 paravirt_pagetable_setup_done(pgd_base); 423 paravirt_pagetable_setup_done(pgd_base);
424} 424}
425 425
426#if defined(CONFIG_HIBERNATION) || defined(CONFIG_ACPI) 426#ifdef CONFIG_ACPI_SLEEP
427/* 427/*
428 * Swap suspend & friends need this for resume because things like the intel-agp 428 * ACPI suspend needs this for resume, because things like the intel-agp
429 * driver might have split up a kernel 4MB mapping. 429 * driver might have split up a kernel 4MB mapping.
430 */ 430 */
431char __nosavedata swsusp_pg_dir[PAGE_SIZE] 431char swsusp_pg_dir[PAGE_SIZE]
432 __attribute__ ((aligned(PAGE_SIZE))); 432 __attribute__ ((aligned(PAGE_SIZE)));
433 433
434static inline void save_pg_dir(void) 434static inline void save_pg_dir(void)
435{ 435{
436 memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE); 436 memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
437} 437}
438#else 438#else /* !CONFIG_ACPI_SLEEP */
439static inline void save_pg_dir(void) 439static inline void save_pg_dir(void)
440{ 440{
441} 441}
442#endif 442#endif /* !CONFIG_ACPI_SLEEP */
443 443
444void zap_low_mappings(void) 444void zap_low_mappings(void)
445{ 445{
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index 81b248429703..fd1c4ba63367 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -192,18 +192,13 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
192 arg.type = ACPI_TYPE_INTEGER; 192 arg.type = ACPI_TYPE_INTEGER;
193 arg.integer.value = sleep_state; 193 arg.integer.value = sleep_state;
194 194
195 /* Run the _PTS and _GTS methods */ 195 /* Run the _PTS method */
196 196
197 status = acpi_evaluate_object(NULL, METHOD_NAME__PTS, &arg_list, NULL); 197 status = acpi_evaluate_object(NULL, METHOD_NAME__PTS, &arg_list, NULL);
198 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { 198 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
199 return_ACPI_STATUS(status); 199 return_ACPI_STATUS(status);
200 } 200 }
201 201
202 status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL);
203 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
204 return_ACPI_STATUS(status);
205 }
206
207 /* Setup the argument to _SST */ 202 /* Setup the argument to _SST */
208 203
209 switch (sleep_state) { 204 switch (sleep_state) {
@@ -234,10 +229,6 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
234 "While executing method _SST")); 229 "While executing method _SST"));
235 } 230 }
236 231
237 /* Disable/Clear all GPEs */
238
239 status = acpi_hw_disable_all_gpes();
240
241 return_ACPI_STATUS(status); 232 return_ACPI_STATUS(status);
242} 233}
243 234
@@ -262,6 +253,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
262 struct acpi_bit_register_info *sleep_type_reg_info; 253 struct acpi_bit_register_info *sleep_type_reg_info;
263 struct acpi_bit_register_info *sleep_enable_reg_info; 254 struct acpi_bit_register_info *sleep_enable_reg_info;
264 u32 in_value; 255 u32 in_value;
256 struct acpi_object_list arg_list;
257 union acpi_object arg;
265 acpi_status status; 258 acpi_status status;
266 259
267 ACPI_FUNCTION_TRACE(acpi_enter_sleep_state); 260 ACPI_FUNCTION_TRACE(acpi_enter_sleep_state);
@@ -307,6 +300,18 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
307 return_ACPI_STATUS(status); 300 return_ACPI_STATUS(status);
308 } 301 }
309 302
303 /* Execute the _GTS method */
304
305 arg_list.count = 1;
306 arg_list.pointer = &arg;
307 arg.type = ACPI_TYPE_INTEGER;
308 arg.integer.value = sleep_state;
309
310 status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL);
311 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
312 return_ACPI_STATUS(status);
313 }
314
310 /* Get current value of PM1A control */ 315 /* Get current value of PM1A control */
311 316
312 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); 317 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
@@ -473,17 +478,18 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios)
473 478
474/******************************************************************************* 479/*******************************************************************************
475 * 480 *
476 * FUNCTION: acpi_leave_sleep_state 481 * FUNCTION: acpi_leave_sleep_state_prep
477 * 482 *
478 * PARAMETERS: sleep_state - Which sleep state we just exited 483 * PARAMETERS: sleep_state - Which sleep state we are exiting
479 * 484 *
480 * RETURN: Status 485 * RETURN: Status
481 * 486 *
482 * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep 487 * DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a
483 * Called with interrupts ENABLED. 488 * sleep.
489 * Called with interrupts DISABLED.
484 * 490 *
485 ******************************************************************************/ 491 ******************************************************************************/
486acpi_status acpi_leave_sleep_state(u8 sleep_state) 492acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
487{ 493{
488 struct acpi_object_list arg_list; 494 struct acpi_object_list arg_list;
489 union acpi_object arg; 495 union acpi_object arg;
@@ -493,7 +499,7 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
493 u32 PM1Acontrol; 499 u32 PM1Acontrol;
494 u32 PM1Bcontrol; 500 u32 PM1Bcontrol;
495 501
496 ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); 502 ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep);
497 503
498 /* 504 /*
499 * Set SLP_TYPE and SLP_EN to state S0. 505 * Set SLP_TYPE and SLP_EN to state S0.
@@ -540,6 +546,41 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
540 } 546 }
541 } 547 }
542 548
549 /* Execute the _BFS method */
550
551 arg_list.count = 1;
552 arg_list.pointer = &arg;
553 arg.type = ACPI_TYPE_INTEGER;
554 arg.integer.value = sleep_state;
555
556 status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL);
557 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
558 ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS"));
559 }
560
561 return_ACPI_STATUS(status);
562}
563
564/*******************************************************************************
565 *
566 * FUNCTION: acpi_leave_sleep_state
567 *
568 * PARAMETERS: sleep_state - Which sleep state we just exited
569 *
570 * RETURN: Status
571 *
572 * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
573 * Called with interrupts ENABLED.
574 *
575 ******************************************************************************/
576acpi_status acpi_leave_sleep_state(u8 sleep_state)
577{
578 struct acpi_object_list arg_list;
579 union acpi_object arg;
580 acpi_status status;
581
582 ACPI_FUNCTION_TRACE(acpi_leave_sleep_state);
583
543 /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ 584 /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */
544 585
545 acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; 586 acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID;
@@ -558,12 +599,6 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
558 ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); 599 ACPI_EXCEPTION((AE_INFO, status, "During Method _SST"));
559 } 600 }
560 601
561 arg.integer.value = sleep_state;
562 status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL);
563 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
564 ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS"));
565 }
566
567 /* 602 /*
568 * GPEs must be enabled before _WAK is called as GPEs 603 * GPEs must be enabled before _WAK is called as GPEs
569 * might get fired there 604 * might get fired there
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 2c0b6630f8ba..485de1347075 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -26,9 +26,24 @@ u8 sleep_states[ACPI_S_STATE_COUNT];
26 26
27#ifdef CONFIG_PM_SLEEP 27#ifdef CONFIG_PM_SLEEP
28static u32 acpi_target_sleep_state = ACPI_STATE_S0; 28static u32 acpi_target_sleep_state = ACPI_STATE_S0;
29static bool acpi_sleep_finish_wake_up;
30
31/*
32 * ACPI 2.0 and later want us to execute _PTS after suspending devices, so we
33 * allow the user to request that behavior by using the 'acpi_new_pts_ordering'
34 * kernel command line option that causes the following variable to be set.
35 */
36static bool new_pts_ordering;
37
38static int __init acpi_new_pts_ordering(char *str)
39{
40 new_pts_ordering = true;
41 return 1;
42}
43__setup("acpi_new_pts_ordering", acpi_new_pts_ordering);
29#endif 44#endif
30 45
31int acpi_sleep_prepare(u32 acpi_state) 46static int acpi_sleep_prepare(u32 acpi_state)
32{ 47{
33#ifdef CONFIG_ACPI_SLEEP 48#ifdef CONFIG_ACPI_SLEEP
34 /* do we have a wakeup address for S2 and S3? */ 49 /* do we have a wakeup address for S2 and S3? */
@@ -44,6 +59,8 @@ int acpi_sleep_prepare(u32 acpi_state)
44 ACPI_FLUSH_CPU_CACHE(); 59 ACPI_FLUSH_CPU_CACHE();
45 acpi_enable_wakeup_device_prep(acpi_state); 60 acpi_enable_wakeup_device_prep(acpi_state);
46#endif 61#endif
62 printk(KERN_INFO PREFIX "Preparing to enter system sleep state S%d\n",
63 acpi_state);
47 acpi_enter_sleep_state_prep(acpi_state); 64 acpi_enter_sleep_state_prep(acpi_state);
48 return 0; 65 return 0;
49} 66}
@@ -63,17 +80,25 @@ static u32 acpi_suspend_states[] = {
63static int init_8259A_after_S1; 80static int init_8259A_after_S1;
64 81
65/** 82/**
66 * acpi_pm_set_target - Set the target system sleep state to the state 83 * acpi_pm_begin - Set the target system sleep state to the state
67 * associated with given @pm_state, if supported. 84 * associated with given @pm_state, if supported.
68 */ 85 */
69 86
70static int acpi_pm_set_target(suspend_state_t pm_state) 87static int acpi_pm_begin(suspend_state_t pm_state)
71{ 88{
72 u32 acpi_state = acpi_suspend_states[pm_state]; 89 u32 acpi_state = acpi_suspend_states[pm_state];
73 int error = 0; 90 int error = 0;
74 91
75 if (sleep_states[acpi_state]) { 92 if (sleep_states[acpi_state]) {
76 acpi_target_sleep_state = acpi_state; 93 acpi_target_sleep_state = acpi_state;
94 if (new_pts_ordering)
95 return 0;
96
97 error = acpi_sleep_prepare(acpi_state);
98 if (error)
99 acpi_target_sleep_state = ACPI_STATE_S0;
100 else
101 acpi_sleep_finish_wake_up = true;
77 } else { 102 } else {
78 printk(KERN_ERR "ACPI does not support this state: %d\n", 103 printk(KERN_ERR "ACPI does not support this state: %d\n",
79 pm_state); 104 pm_state);
@@ -91,12 +116,17 @@ static int acpi_pm_set_target(suspend_state_t pm_state)
91 116
92static int acpi_pm_prepare(void) 117static int acpi_pm_prepare(void)
93{ 118{
94 int error = acpi_sleep_prepare(acpi_target_sleep_state); 119 if (new_pts_ordering) {
120 int error = acpi_sleep_prepare(acpi_target_sleep_state);
95 121
96 if (error) 122 if (error) {
97 acpi_target_sleep_state = ACPI_STATE_S0; 123 acpi_target_sleep_state = ACPI_STATE_S0;
124 return error;
125 }
126 acpi_sleep_finish_wake_up = true;
127 }
98 128
99 return error; 129 return ACPI_SUCCESS(acpi_hw_disable_all_gpes()) ? 0 : -EFAULT;
100} 130}
101 131
102/** 132/**
@@ -120,10 +150,8 @@ static int acpi_pm_enter(suspend_state_t pm_state)
120 if (acpi_state == ACPI_STATE_S3) { 150 if (acpi_state == ACPI_STATE_S3) {
121 int error = acpi_save_state_mem(); 151 int error = acpi_save_state_mem();
122 152
123 if (error) { 153 if (error)
124 acpi_target_sleep_state = ACPI_STATE_S0;
125 return error; 154 return error;
126 }
127 } 155 }
128 156
129 local_irq_save(flags); 157 local_irq_save(flags);
@@ -139,6 +167,9 @@ static int acpi_pm_enter(suspend_state_t pm_state)
139 break; 167 break;
140 } 168 }
141 169
170 /* Reprogram control registers and execute _BFS */
171 acpi_leave_sleep_state_prep(acpi_state);
172
142 /* ACPI 3.0 specs (P62) says that it's the responsabilty 173 /* ACPI 3.0 specs (P62) says that it's the responsabilty
143 * of the OSPM to clear the status bit [ implying that the 174 * of the OSPM to clear the status bit [ implying that the
144 * POWER_BUTTON event should not reach userspace ] 175 * POWER_BUTTON event should not reach userspace ]
@@ -146,6 +177,13 @@ static int acpi_pm_enter(suspend_state_t pm_state)
146 if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) 177 if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3))
147 acpi_clear_event(ACPI_EVENT_POWER_BUTTON); 178 acpi_clear_event(ACPI_EVENT_POWER_BUTTON);
148 179
180 /*
181 * Disable and clear GPE status before interrupt is enabled. Some GPEs
182 * (like wakeup GPE) haven't handler, this can avoid such GPE misfire.
183 * acpi_leave_sleep_state will reenable specific GPEs later
184 */
185 acpi_hw_disable_all_gpes();
186
149 local_irq_restore(flags); 187 local_irq_restore(flags);
150 printk(KERN_DEBUG "Back to C!\n"); 188 printk(KERN_DEBUG "Back to C!\n");
151 189
@@ -157,7 +195,7 @@ static int acpi_pm_enter(suspend_state_t pm_state)
157} 195}
158 196
159/** 197/**
160 * acpi_pm_finish - Finish up suspend sequence. 198 * acpi_pm_finish - Instruct the platform to leave a sleep state.
161 * 199 *
162 * This is called after we wake back up (or if entering the sleep state 200 * This is called after we wake back up (or if entering the sleep state
163 * failed). 201 * failed).
@@ -174,6 +212,7 @@ static void acpi_pm_finish(void)
174 acpi_set_firmware_waking_vector((acpi_physical_address) 0); 212 acpi_set_firmware_waking_vector((acpi_physical_address) 0);
175 213
176 acpi_target_sleep_state = ACPI_STATE_S0; 214 acpi_target_sleep_state = ACPI_STATE_S0;
215 acpi_sleep_finish_wake_up = false;
177 216
178#ifdef CONFIG_X86 217#ifdef CONFIG_X86
179 if (init_8259A_after_S1) { 218 if (init_8259A_after_S1) {
@@ -183,6 +222,20 @@ static void acpi_pm_finish(void)
183#endif 222#endif
184} 223}
185 224
225/**
226 * acpi_pm_end - Finish up suspend sequence.
227 */
228
229static void acpi_pm_end(void)
230{
231 /*
232 * This is necessary in case acpi_pm_finish() is not called directly
233 * during a failing transition to a sleep state.
234 */
235 if (acpi_sleep_finish_wake_up)
236 acpi_pm_finish();
237}
238
186static int acpi_pm_state_valid(suspend_state_t pm_state) 239static int acpi_pm_state_valid(suspend_state_t pm_state)
187{ 240{
188 u32 acpi_state; 241 u32 acpi_state;
@@ -201,10 +254,11 @@ static int acpi_pm_state_valid(suspend_state_t pm_state)
201 254
202static struct platform_suspend_ops acpi_pm_ops = { 255static struct platform_suspend_ops acpi_pm_ops = {
203 .valid = acpi_pm_state_valid, 256 .valid = acpi_pm_state_valid,
204 .set_target = acpi_pm_set_target, 257 .begin = acpi_pm_begin,
205 .prepare = acpi_pm_prepare, 258 .prepare = acpi_pm_prepare,
206 .enter = acpi_pm_enter, 259 .enter = acpi_pm_enter,
207 .finish = acpi_pm_finish, 260 .finish = acpi_pm_finish,
261 .end = acpi_pm_end,
208}; 262};
209 263
210/* 264/*
@@ -229,15 +283,36 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
229#endif /* CONFIG_SUSPEND */ 283#endif /* CONFIG_SUSPEND */
230 284
231#ifdef CONFIG_HIBERNATION 285#ifdef CONFIG_HIBERNATION
232static int acpi_hibernation_start(void) 286static int acpi_hibernation_begin(void)
233{ 287{
288 int error;
289
234 acpi_target_sleep_state = ACPI_STATE_S4; 290 acpi_target_sleep_state = ACPI_STATE_S4;
235 return 0; 291 if (new_pts_ordering)
292 return 0;
293
294 error = acpi_sleep_prepare(ACPI_STATE_S4);
295 if (error)
296 acpi_target_sleep_state = ACPI_STATE_S0;
297 else
298 acpi_sleep_finish_wake_up = true;
299
300 return error;
236} 301}
237 302
238static int acpi_hibernation_prepare(void) 303static int acpi_hibernation_prepare(void)
239{ 304{
240 return acpi_sleep_prepare(ACPI_STATE_S4); 305 if (new_pts_ordering) {
306 int error = acpi_sleep_prepare(ACPI_STATE_S4);
307
308 if (error) {
309 acpi_target_sleep_state = ACPI_STATE_S0;
310 return error;
311 }
312 acpi_sleep_finish_wake_up = true;
313 }
314
315 return ACPI_SUCCESS(acpi_hw_disable_all_gpes()) ? 0 : -EFAULT;
241} 316}
242 317
243static int acpi_hibernation_enter(void) 318static int acpi_hibernation_enter(void)
@@ -251,6 +326,8 @@ static int acpi_hibernation_enter(void)
251 acpi_enable_wakeup_device(ACPI_STATE_S4); 326 acpi_enable_wakeup_device(ACPI_STATE_S4);
252 /* This shouldn't return. If it returns, we have a problem */ 327 /* This shouldn't return. If it returns, we have a problem */
253 status = acpi_enter_sleep_state(ACPI_STATE_S4); 328 status = acpi_enter_sleep_state(ACPI_STATE_S4);
329 /* Reprogram control registers and execute _BFS */
330 acpi_leave_sleep_state_prep(ACPI_STATE_S4);
254 local_irq_restore(flags); 331 local_irq_restore(flags);
255 332
256 return ACPI_SUCCESS(status) ? 0 : -EFAULT; 333 return ACPI_SUCCESS(status) ? 0 : -EFAULT;
@@ -263,15 +340,12 @@ static void acpi_hibernation_leave(void)
263 * enable it here. 340 * enable it here.
264 */ 341 */
265 acpi_enable(); 342 acpi_enable();
343 /* Reprogram control registers and execute _BFS */
344 acpi_leave_sleep_state_prep(ACPI_STATE_S4);
266} 345}
267 346
268static void acpi_hibernation_finish(void) 347static void acpi_hibernation_finish(void)
269{ 348{
270 /*
271 * If ACPI is not enabled by the BIOS and the boot kernel, we need to
272 * enable it here.
273 */
274 acpi_enable();
275 acpi_disable_wakeup_device(ACPI_STATE_S4); 349 acpi_disable_wakeup_device(ACPI_STATE_S4);
276 acpi_leave_sleep_state(ACPI_STATE_S4); 350 acpi_leave_sleep_state(ACPI_STATE_S4);
277 351
@@ -279,6 +353,17 @@ static void acpi_hibernation_finish(void)
279 acpi_set_firmware_waking_vector((acpi_physical_address) 0); 353 acpi_set_firmware_waking_vector((acpi_physical_address) 0);
280 354
281 acpi_target_sleep_state = ACPI_STATE_S0; 355 acpi_target_sleep_state = ACPI_STATE_S0;
356 acpi_sleep_finish_wake_up = false;
357}
358
359static void acpi_hibernation_end(void)
360{
361 /*
362 * This is necessary in case acpi_hibernation_finish() is not called
363 * directly during a failing transition to the sleep state.
364 */
365 if (acpi_sleep_finish_wake_up)
366 acpi_hibernation_finish();
282} 367}
283 368
284static int acpi_hibernation_pre_restore(void) 369static int acpi_hibernation_pre_restore(void)
@@ -296,7 +381,8 @@ static void acpi_hibernation_restore_cleanup(void)
296} 381}
297 382
298static struct platform_hibernation_ops acpi_hibernation_ops = { 383static struct platform_hibernation_ops acpi_hibernation_ops = {
299 .start = acpi_hibernation_start, 384 .begin = acpi_hibernation_begin,
385 .end = acpi_hibernation_end,
300 .pre_snapshot = acpi_hibernation_prepare, 386 .pre_snapshot = acpi_hibernation_prepare,
301 .finish = acpi_hibernation_finish, 387 .finish = acpi_hibernation_finish,
302 .prepare = acpi_hibernation_prepare, 388 .prepare = acpi_hibernation_prepare,
@@ -403,6 +489,7 @@ static void acpi_power_off_prepare(void)
403{ 489{
404 /* Prepare to power off the system */ 490 /* Prepare to power off the system */
405 acpi_sleep_prepare(ACPI_STATE_S5); 491 acpi_sleep_prepare(ACPI_STATE_S5);
492 acpi_hw_disable_all_gpes();
406} 493}
407 494
408static void acpi_power_off(void) 495static void acpi_power_off(void)
diff --git a/drivers/acpi/sleep/sleep.h b/drivers/acpi/sleep/sleep.h
index a2ea125ae2d0..cfaf8f5b0a14 100644
--- a/drivers/acpi/sleep/sleep.h
+++ b/drivers/acpi/sleep/sleep.h
@@ -5,5 +5,3 @@ extern int acpi_suspend (u32 state);
5extern void acpi_enable_wakeup_device_prep(u8 sleep_state); 5extern void acpi_enable_wakeup_device_prep(u8 sleep_state);
6extern void acpi_enable_wakeup_device(u8 sleep_state); 6extern void acpi_enable_wakeup_device(u8 sleep_state);
7extern void acpi_disable_wakeup_device(u8 sleep_state); 7extern void acpi_disable_wakeup_device(u8 sleep_state);
8
9extern int acpi_sleep_prepare(u32 acpi_state);
diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile
index de28dfd3b96c..911208b89259 100644
--- a/drivers/base/power/Makefile
+++ b/drivers/base/power/Makefile
@@ -1,6 +1,6 @@
1obj-$(CONFIG_PM) += sysfs.o 1obj-$(CONFIG_PM) += sysfs.o
2obj-$(CONFIG_PM_SLEEP) += main.o 2obj-$(CONFIG_PM_SLEEP) += main.o
3obj-$(CONFIG_PM_TRACE) += trace.o 3obj-$(CONFIG_PM_TRACE_RTC) += trace.o
4 4
5ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG 5ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
6ccflags-$(CONFIG_PM_VERBOSE) += -DDEBUG 6ccflags-$(CONFIG_PM_VERBOSE) += -DDEBUG
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 9512f0456ad1..b729e64d0d4c 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -335,6 +335,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state);
335 335
336acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void); 336acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void);
337 337
338acpi_status acpi_leave_sleep_state_prep(u8 sleep_state);
339
338acpi_status acpi_leave_sleep_state(u8 sleep_state); 340acpi_status acpi_leave_sleep_state(u8 sleep_state);
339 341
340#endif /* __ACXFACE_H__ */ 342#endif /* __ACXFACE_H__ */
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 85b2482cc736..c0f9bb78727d 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -143,6 +143,7 @@ header-y += snmp.h
143header-y += sockios.h 143header-y += sockios.h
144header-y += som.h 144header-y += som.h
145header-y += sound.h 145header-y += sound.h
146header-y += suspend_ioctls.h
146header-y += taskstats.h 147header-y += taskstats.h
147header-y += telephony.h 148header-y += telephony.h
148header-y += termios.h 149header-y += termios.h
diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index 5dfbc684ce7d..f4df40038f0c 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -228,6 +228,8 @@ static inline int notifier_to_errno(int ret)
228#define PM_POST_HIBERNATION 0x0002 /* Hibernation finished */ 228#define PM_POST_HIBERNATION 0x0002 /* Hibernation finished */
229#define PM_SUSPEND_PREPARE 0x0003 /* Going to suspend the system */ 229#define PM_SUSPEND_PREPARE 0x0003 /* Going to suspend the system */
230#define PM_POST_SUSPEND 0x0004 /* Suspend finished */ 230#define PM_POST_SUSPEND 0x0004 /* Suspend finished */
231#define PM_RESTORE_PREPARE 0x0005 /* Going to restore a saved image */
232#define PM_POST_RESTORE 0x0006 /* Restore failed */
231 233
232/* Console keyboard events. 234/* Console keyboard events.
233 * Note: KBD_KEYCODE is always sent before KBD_UNBOUND_KEYCODE, KBD_UNICODE and 235 * Note: KBD_KEYCODE is always sent before KBD_UNBOUND_KEYCODE, KBD_UNICODE and
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 40280df2a3db..646ce2d068d4 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -38,18 +38,16 @@ typedef int __bitwise suspend_state_t;
38 * There is the %suspend_valid_only_mem function available that can be 38 * There is the %suspend_valid_only_mem function available that can be
39 * assigned to this if the platform only supports mem sleep. 39 * assigned to this if the platform only supports mem sleep.
40 * 40 *
41 * @set_target: Tell the platform which system sleep state is going to be 41 * @begin: Initialise a transition to given system sleep state.
42 * entered. 42 * @begin() is executed right prior to suspending devices. The information
43 * @set_target() is executed right prior to suspending devices. The 43 * conveyed to the platform code by @begin() should be disregarded by it as
44 * information conveyed to the platform code by @set_target() should be 44 * soon as @end() is executed. If @begin() fails (ie. returns nonzero),
45 * disregarded by the platform as soon as @finish() is executed and if
46 * @prepare() fails. If @set_target() fails (ie. returns nonzero),
47 * @prepare(), @enter() and @finish() will not be called by the PM core. 45 * @prepare(), @enter() and @finish() will not be called by the PM core.
48 * This callback is optional. However, if it is implemented, the argument 46 * This callback is optional. However, if it is implemented, the argument
49 * passed to @enter() is meaningless and should be ignored. 47 * passed to @enter() is redundant and should be ignored.
50 * 48 *
51 * @prepare: Prepare the platform for entering the system sleep state indicated 49 * @prepare: Prepare the platform for entering the system sleep state indicated
52 * by @set_target(). 50 * by @begin().
53 * @prepare() is called right after devices have been suspended (ie. the 51 * @prepare() is called right after devices have been suspended (ie. the
54 * appropriate .suspend() method has been executed for each device) and 52 * appropriate .suspend() method has been executed for each device) and
55 * before the nonboot CPUs are disabled (it is executed with IRQs enabled). 53 * before the nonboot CPUs are disabled (it is executed with IRQs enabled).
@@ -57,8 +55,8 @@ typedef int __bitwise suspend_state_t;
57 * error code otherwise, in which case the system cannot enter the desired 55 * error code otherwise, in which case the system cannot enter the desired
58 * sleep state (@enter() and @finish() will not be called in that case). 56 * sleep state (@enter() and @finish() will not be called in that case).
59 * 57 *
60 * @enter: Enter the system sleep state indicated by @set_target() or 58 * @enter: Enter the system sleep state indicated by @begin() or represented by
61 * represented by the argument if @set_target() is not implemented. 59 * the argument if @begin() is not implemented.
62 * This callback is mandatory. It returns 0 on success or a negative 60 * This callback is mandatory. It returns 0 on success or a negative
63 * error code otherwise, in which case the system cannot enter the desired 61 * error code otherwise, in which case the system cannot enter the desired
64 * sleep state. 62 * sleep state.
@@ -69,13 +67,22 @@ typedef int __bitwise suspend_state_t;
69 * This callback is optional, but should be implemented by the platforms 67 * This callback is optional, but should be implemented by the platforms
70 * that implement @prepare(). If implemented, it is always called after 68 * that implement @prepare(). If implemented, it is always called after
71 * @enter() (even if @enter() fails). 69 * @enter() (even if @enter() fails).
70 *
71 * @end: Called by the PM core right after resuming devices, to indicate to
72 * the platform that the system has returned to the working state or
73 * the transition to the sleep state has been aborted.
74 * This callback is optional, but should be implemented by the platforms
75 * that implement @begin(), but platforms implementing @begin() should
76 * also provide a @end() which cleans up transitions aborted before
77 * @enter().
72 */ 78 */
73struct platform_suspend_ops { 79struct platform_suspend_ops {
74 int (*valid)(suspend_state_t state); 80 int (*valid)(suspend_state_t state);
75 int (*set_target)(suspend_state_t state); 81 int (*begin)(suspend_state_t state);
76 int (*prepare)(void); 82 int (*prepare)(void);
77 int (*enter)(suspend_state_t state); 83 int (*enter)(suspend_state_t state);
78 void (*finish)(void); 84 void (*finish)(void);
85 void (*end)(void);
79}; 86};
80 87
81#ifdef CONFIG_SUSPEND 88#ifdef CONFIG_SUSPEND
@@ -129,14 +136,17 @@ extern void mark_free_pages(struct zone *zone);
129/** 136/**
130 * struct platform_hibernation_ops - hibernation platform support 137 * struct platform_hibernation_ops - hibernation platform support
131 * 138 *
132 * The methods in this structure allow a platform to override the default 139 * The methods in this structure allow a platform to carry out special
133 * mechanism of shutting down the machine during a hibernation transition. 140 * operations required by it during a hibernation transition.
134 * 141 *
135 * All three methods must be assigned. 142 * All the methods below must be implemented.
136 * 143 *
137 * @start: Tell the platform driver that we're starting hibernation. 144 * @begin: Tell the platform driver that we're starting hibernation.
138 * Called right after shrinking memory and before freezing devices. 145 * Called right after shrinking memory and before freezing devices.
139 * 146 *
147 * @end: Called by the PM core right after resuming devices, to indicate to
148 * the platform that the system has returned to the working state.
149 *
140 * @pre_snapshot: Prepare the platform for creating the hibernation image. 150 * @pre_snapshot: Prepare the platform for creating the hibernation image.
141 * Called right after devices have been frozen and before the nonboot 151 * Called right after devices have been frozen and before the nonboot
142 * CPUs are disabled (runs with IRQs on). 152 * CPUs are disabled (runs with IRQs on).
@@ -171,7 +181,8 @@ extern void mark_free_pages(struct zone *zone);
171 * thawing devices (runs with IRQs on). 181 * thawing devices (runs with IRQs on).
172 */ 182 */
173struct platform_hibernation_ops { 183struct platform_hibernation_ops {
174 int (*start)(void); 184 int (*begin)(void);
185 void (*end)(void);
175 int (*pre_snapshot)(void); 186 int (*pre_snapshot)(void);
176 void (*finish)(void); 187 void (*finish)(void);
177 int (*prepare)(void); 188 int (*prepare)(void);
@@ -213,17 +224,8 @@ void save_processor_state(void);
213void restore_processor_state(void); 224void restore_processor_state(void);
214 225
215/* kernel/power/main.c */ 226/* kernel/power/main.c */
216extern struct blocking_notifier_head pm_chain_head; 227extern int register_pm_notifier(struct notifier_block *nb);
217 228extern int unregister_pm_notifier(struct notifier_block *nb);
218static inline int register_pm_notifier(struct notifier_block *nb)
219{
220 return blocking_notifier_chain_register(&pm_chain_head, nb);
221}
222
223static inline int unregister_pm_notifier(struct notifier_block *nb)
224{
225 return blocking_notifier_chain_unregister(&pm_chain_head, nb);
226}
227 229
228#define pm_notifier(fn, pri) { \ 230#define pm_notifier(fn, pri) { \
229 static struct notifier_block fn##_nb = \ 231 static struct notifier_block fn##_nb = \
diff --git a/include/linux/suspend_ioctls.h b/include/linux/suspend_ioctls.h
new file mode 100644
index 000000000000..2c6faec96bde
--- /dev/null
+++ b/include/linux/suspend_ioctls.h
@@ -0,0 +1,32 @@
1#ifndef _LINUX_SUSPEND_IOCTLS_H
2#define _LINUX_SUSPEND_IOCTLS_H
3
4/*
5 * This structure is used to pass the values needed for the identification
6 * of the resume swap area from a user space to the kernel via the
7 * SNAPSHOT_SET_SWAP_AREA ioctl
8 */
9struct resume_swap_area {
10 loff_t offset;
11 u_int32_t dev;
12} __attribute__((packed));
13
14#define SNAPSHOT_IOC_MAGIC '3'
15#define SNAPSHOT_FREEZE _IO(SNAPSHOT_IOC_MAGIC, 1)
16#define SNAPSHOT_UNFREEZE _IO(SNAPSHOT_IOC_MAGIC, 2)
17#define SNAPSHOT_ATOMIC_RESTORE _IO(SNAPSHOT_IOC_MAGIC, 4)
18#define SNAPSHOT_FREE _IO(SNAPSHOT_IOC_MAGIC, 5)
19#define SNAPSHOT_FREE_SWAP_PAGES _IO(SNAPSHOT_IOC_MAGIC, 9)
20#define SNAPSHOT_S2RAM _IO(SNAPSHOT_IOC_MAGIC, 11)
21#define SNAPSHOT_SET_SWAP_AREA _IOW(SNAPSHOT_IOC_MAGIC, 13, \
22 struct resume_swap_area)
23#define SNAPSHOT_GET_IMAGE_SIZE _IOR(SNAPSHOT_IOC_MAGIC, 14, loff_t)
24#define SNAPSHOT_PLATFORM_SUPPORT _IO(SNAPSHOT_IOC_MAGIC, 15)
25#define SNAPSHOT_POWER_OFF _IO(SNAPSHOT_IOC_MAGIC, 16)
26#define SNAPSHOT_CREATE_IMAGE _IOW(SNAPSHOT_IOC_MAGIC, 17, int)
27#define SNAPSHOT_PREF_IMAGE_SIZE _IO(SNAPSHOT_IOC_MAGIC, 18)
28#define SNAPSHOT_AVAIL_SWAP_SIZE _IOR(SNAPSHOT_IOC_MAGIC, 19, loff_t)
29#define SNAPSHOT_ALLOC_SWAP_PAGE _IOR(SNAPSHOT_IOC_MAGIC, 20, loff_t)
30#define SNAPSHOT_IOC_MAXNR 20
31
32#endif /* _LINUX_SUSPEND_IOCTLS_H */
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 8e186c678149..ef9b802738a5 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -44,9 +44,30 @@ config PM_VERBOSE
44 ---help--- 44 ---help---
45 This option enables verbose messages from the Power Management code. 45 This option enables verbose messages from the Power Management code.
46 46
47config CAN_PM_TRACE
48 def_bool y
49 depends on PM_DEBUG && PM_SLEEP && EXPERIMENTAL
50
47config PM_TRACE 51config PM_TRACE
52 bool
53 help
54 This enables code to save the last PM event point across
55 reboot. The architecture needs to support this, x86 for
56 example does by saving things in the RTC, see below.
57
58 The architecture specific code must provide the extern
59 functions from <linux/resume-trace.h> as well as the
60 <asm/resume-trace.h> header with a TRACE_RESUME() macro.
61
62 The way the information is presented is architecture-
63 dependent, x86 will print the information during a
64 late_initcall.
65
66config PM_TRACE_RTC
48 bool "Suspend/resume event tracing" 67 bool "Suspend/resume event tracing"
49 depends on PM_DEBUG && X86 && PM_SLEEP && EXPERIMENTAL 68 depends on CAN_PM_TRACE
69 depends on X86
70 select PM_TRACE
50 default n 71 default n
51 ---help--- 72 ---help---
52 This enables some cheesy code to save the last PM event point in the 73 This enables some cheesy code to save the last PM event point in the
@@ -63,7 +84,8 @@ config PM_TRACE
63 84
64config PM_SLEEP_SMP 85config PM_SLEEP_SMP
65 bool 86 bool
66 depends on SUSPEND_SMP_POSSIBLE || HIBERNATION_SMP_POSSIBLE 87 depends on SMP
88 depends on ARCH_SUSPEND_POSSIBLE || ARCH_HIBERNATION_POSSIBLE
67 depends on PM_SLEEP 89 depends on PM_SLEEP
68 select HOTPLUG_CPU 90 select HOTPLUG_CPU
69 default y 91 default y
@@ -73,46 +95,29 @@ config PM_SLEEP
73 depends on SUSPEND || HIBERNATION 95 depends on SUSPEND || HIBERNATION
74 default y 96 default y
75 97
76config SUSPEND_UP_POSSIBLE
77 bool
78 depends on (X86 && !X86_VOYAGER) || PPC || ARM || BLACKFIN || MIPS \
79 || SUPERH || FRV
80 depends on !SMP
81 default y
82
83config SUSPEND_SMP_POSSIBLE
84 bool
85 depends on (X86 && !X86_VOYAGER) \
86 || (PPC && (PPC_PSERIES || PPC_PMAC)) || ARM
87 depends on SMP
88 default y
89
90config SUSPEND 98config SUSPEND
91 bool "Suspend to RAM and standby" 99 bool "Suspend to RAM and standby"
92 depends on PM 100 depends on PM && ARCH_SUSPEND_POSSIBLE
93 depends on SUSPEND_UP_POSSIBLE || SUSPEND_SMP_POSSIBLE
94 default y 101 default y
95 ---help--- 102 ---help---
96 Allow the system to enter sleep states in which main memory is 103 Allow the system to enter sleep states in which main memory is
97 powered and thus its contents are preserved, such as the 104 powered and thus its contents are preserved, such as the
98 suspend-to-RAM state (i.e. the ACPI S3 state). 105 suspend-to-RAM state (e.g. the ACPI S3 state).
99 106
100config HIBERNATION_UP_POSSIBLE 107config SUSPEND_FREEZER
101 bool 108 bool "Enable freezer for suspend to RAM/standby" \
102 depends on X86 || PPC64_SWSUSP || PPC32 109 if ARCH_WANTS_FREEZER_CONTROL || BROKEN
103 depends on !SMP 110 depends on SUSPEND
104 default y 111 default y
112 help
113 This allows you to turn off the freezer for suspend. If this is
114 done, no tasks are frozen for suspend to RAM/standby.
105 115
106config HIBERNATION_SMP_POSSIBLE 116 Turning OFF this setting is NOT recommended! If in doubt, say Y.
107 bool
108 depends on (X86 && !X86_VOYAGER) || PPC64_SWSUSP
109 depends on SMP
110 default y
111 117
112config HIBERNATION 118config HIBERNATION
113 bool "Hibernation (aka 'suspend to disk')" 119 bool "Hibernation (aka 'suspend to disk')"
114 depends on PM && SWAP 120 depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE
115 depends on HIBERNATION_UP_POSSIBLE || HIBERNATION_SMP_POSSIBLE
116 ---help--- 121 ---help---
117 Enable the suspend to disk (STD) functionality, which is usually 122 Enable the suspend to disk (STD) functionality, which is usually
118 called "hibernation" in user interfaces. STD checkpoints the 123 called "hibernation" in user interfaces. STD checkpoints the
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index b138b431e271..d09da0895174 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -54,8 +54,8 @@ static struct platform_hibernation_ops *hibernation_ops;
54 54
55void hibernation_set_ops(struct platform_hibernation_ops *ops) 55void hibernation_set_ops(struct platform_hibernation_ops *ops)
56{ 56{
57 if (ops && !(ops->start && ops->pre_snapshot && ops->finish 57 if (ops && !(ops->begin && ops->end && ops->pre_snapshot
58 && ops->prepare && ops->enter && ops->pre_restore 58 && ops->prepare && ops->finish && ops->enter && ops->pre_restore
59 && ops->restore_cleanup)) { 59 && ops->restore_cleanup)) {
60 WARN_ON(1); 60 WARN_ON(1);
61 return; 61 return;
@@ -70,15 +70,55 @@ void hibernation_set_ops(struct platform_hibernation_ops *ops)
70 mutex_unlock(&pm_mutex); 70 mutex_unlock(&pm_mutex);
71} 71}
72 72
73#ifdef CONFIG_PM_DEBUG
74static void hibernation_debug_sleep(void)
75{
76 printk(KERN_INFO "hibernation debug: Waiting for 5 seconds.\n");
77 mdelay(5000);
78}
79
80static int hibernation_testmode(int mode)
81{
82 if (hibernation_mode == mode) {
83 hibernation_debug_sleep();
84 return 1;
85 }
86 return 0;
87}
88
89static int hibernation_test(int level)
90{
91 if (pm_test_level == level) {
92 hibernation_debug_sleep();
93 return 1;
94 }
95 return 0;
96}
97#else /* !CONFIG_PM_DEBUG */
98static int hibernation_testmode(int mode) { return 0; }
99static int hibernation_test(int level) { return 0; }
100#endif /* !CONFIG_PM_DEBUG */
101
73/** 102/**
74 * platform_start - tell the platform driver that we're starting 103 * platform_begin - tell the platform driver that we're starting
75 * hibernation 104 * hibernation
76 */ 105 */
77 106
78static int platform_start(int platform_mode) 107static int platform_begin(int platform_mode)
79{ 108{
80 return (platform_mode && hibernation_ops) ? 109 return (platform_mode && hibernation_ops) ?
81 hibernation_ops->start() : 0; 110 hibernation_ops->begin() : 0;
111}
112
113/**
114 * platform_end - tell the platform driver that we've entered the
115 * working state
116 */
117
118static void platform_end(int platform_mode)
119{
120 if (platform_mode && hibernation_ops)
121 hibernation_ops->end();
82} 122}
83 123
84/** 124/**
@@ -162,19 +202,25 @@ int create_image(int platform_mode)
162 */ 202 */
163 error = device_power_down(PMSG_FREEZE); 203 error = device_power_down(PMSG_FREEZE);
164 if (error) { 204 if (error) {
165 printk(KERN_ERR "Some devices failed to power down, " 205 printk(KERN_ERR "PM: Some devices failed to power down, "
166 KERN_ERR "aborting suspend\n"); 206 "aborting hibernation\n");
167 goto Enable_irqs; 207 goto Enable_irqs;
168 } 208 }
169 209
210 if (hibernation_test(TEST_CORE))
211 goto Power_up;
212
213 in_suspend = 1;
170 save_processor_state(); 214 save_processor_state();
171 error = swsusp_arch_suspend(); 215 error = swsusp_arch_suspend();
172 if (error) 216 if (error)
173 printk(KERN_ERR "Error %d while creating the image\n", error); 217 printk(KERN_ERR "PM: Error %d creating hibernation image\n",
218 error);
174 /* Restore control flow magically appears here */ 219 /* Restore control flow magically appears here */
175 restore_processor_state(); 220 restore_processor_state();
176 if (!in_suspend) 221 if (!in_suspend)
177 platform_leave(platform_mode); 222 platform_leave(platform_mode);
223 Power_up:
178 /* NOTE: device_power_up() is just a resume() for devices 224 /* NOTE: device_power_up() is just a resume() for devices
179 * that suspended with irqs off ... no overall powerup. 225 * that suspended with irqs off ... no overall powerup.
180 */ 226 */
@@ -202,36 +248,90 @@ int hibernation_snapshot(int platform_mode)
202 if (error) 248 if (error)
203 return error; 249 return error;
204 250
205 error = platform_start(platform_mode); 251 error = platform_begin(platform_mode);
206 if (error) 252 if (error)
207 return error; 253 goto Close;
208 254
209 suspend_console(); 255 suspend_console();
210 error = device_suspend(PMSG_FREEZE); 256 error = device_suspend(PMSG_FREEZE);
211 if (error) 257 if (error)
212 goto Resume_console; 258 goto Resume_console;
213 259
214 error = platform_pre_snapshot(platform_mode); 260 if (hibernation_test(TEST_DEVICES))
215 if (error)
216 goto Resume_devices; 261 goto Resume_devices;
217 262
263 error = platform_pre_snapshot(platform_mode);
264 if (error || hibernation_test(TEST_PLATFORM))
265 goto Finish;
266
218 error = disable_nonboot_cpus(); 267 error = disable_nonboot_cpus();
219 if (!error) { 268 if (!error) {
220 if (hibernation_mode != HIBERNATION_TEST) { 269 if (hibernation_test(TEST_CPUS))
221 in_suspend = 1; 270 goto Enable_cpus;
222 error = create_image(platform_mode); 271
223 /* Control returns here after successful restore */ 272 if (hibernation_testmode(HIBERNATION_TEST))
224 } else { 273 goto Enable_cpus;
225 printk("swsusp debug: Waiting for 5 seconds.\n"); 274
226 mdelay(5000); 275 error = create_image(platform_mode);
227 } 276 /* Control returns here after successful restore */
228 } 277 }
278 Enable_cpus:
229 enable_nonboot_cpus(); 279 enable_nonboot_cpus();
230 Resume_devices: 280 Finish:
231 platform_finish(platform_mode); 281 platform_finish(platform_mode);
282 Resume_devices:
232 device_resume(); 283 device_resume();
233 Resume_console: 284 Resume_console:
234 resume_console(); 285 resume_console();
286 Close:
287 platform_end(platform_mode);
288 return error;
289}
290
291/**
292 * resume_target_kernel - prepare devices that need to be suspended with
293 * interrupts off, restore the contents of highmem that have not been
294 * restored yet from the image and run the low level code that will restore
295 * the remaining contents of memory and switch to the just restored target
296 * kernel.
297 */
298
299static int resume_target_kernel(void)
300{
301 int error;
302
303 local_irq_disable();
304 error = device_power_down(PMSG_PRETHAW);
305 if (error) {
306 printk(KERN_ERR "PM: Some devices failed to power down, "
307 "aborting resume\n");
308 goto Enable_irqs;
309 }
310 /* We'll ignore saved state, but this gets preempt count (etc) right */
311 save_processor_state();
312 error = restore_highmem();
313 if (!error) {
314 error = swsusp_arch_resume();
315 /*
316 * The code below is only ever reached in case of a failure.
317 * Otherwise execution continues at place where
318 * swsusp_arch_suspend() was called
319 */
320 BUG_ON(!error);
321 /* This call to restore_highmem() undos the previous one */
322 restore_highmem();
323 }
324 /*
325 * The only reason why swsusp_arch_resume() can fail is memory being
326 * very tight, so we have to free it as soon as we can to avoid
327 * subsequent failures
328 */
329 swsusp_free();
330 restore_processor_state();
331 touch_softlockup_watchdog();
332 device_power_up();
333 Enable_irqs:
334 local_irq_enable();
235 return error; 335 return error;
236} 336}
237 337
@@ -258,7 +358,7 @@ int hibernation_restore(int platform_mode)
258 if (!error) { 358 if (!error) {
259 error = disable_nonboot_cpus(); 359 error = disable_nonboot_cpus();
260 if (!error) 360 if (!error)
261 error = swsusp_resume(); 361 error = resume_target_kernel();
262 enable_nonboot_cpus(); 362 enable_nonboot_cpus();
263 } 363 }
264 platform_restore_cleanup(platform_mode); 364 platform_restore_cleanup(platform_mode);
@@ -286,9 +386,9 @@ int hibernation_platform_enter(void)
286 * hibernation_ops->finish() before saving the image, so we should let 386 * hibernation_ops->finish() before saving the image, so we should let
287 * the firmware know that we're going to enter the sleep state after all 387 * the firmware know that we're going to enter the sleep state after all
288 */ 388 */
289 error = hibernation_ops->start(); 389 error = hibernation_ops->begin();
290 if (error) 390 if (error)
291 return error; 391 goto Close;
292 392
293 suspend_console(); 393 suspend_console();
294 error = device_suspend(PMSG_SUSPEND); 394 error = device_suspend(PMSG_SUSPEND);
@@ -322,6 +422,8 @@ int hibernation_platform_enter(void)
322 device_resume(); 422 device_resume();
323 Resume_console: 423 Resume_console:
324 resume_console(); 424 resume_console();
425 Close:
426 hibernation_ops->end();
325 return error; 427 return error;
326} 428}
327 429
@@ -352,24 +454,17 @@ static void power_down(void)
352 * Valid image is on the disk, if we continue we risk serious data 454 * Valid image is on the disk, if we continue we risk serious data
353 * corruption after resume. 455 * corruption after resume.
354 */ 456 */
355 printk(KERN_CRIT "Please power me down manually\n"); 457 printk(KERN_CRIT "PM: Please power down manually\n");
356 while(1); 458 while(1);
357} 459}
358 460
359static void unprepare_processes(void)
360{
361 thaw_processes();
362 pm_restore_console();
363}
364
365static int prepare_processes(void) 461static int prepare_processes(void)
366{ 462{
367 int error = 0; 463 int error = 0;
368 464
369 pm_prepare_console();
370 if (freeze_processes()) { 465 if (freeze_processes()) {
371 error = -EBUSY; 466 error = -EBUSY;
372 unprepare_processes(); 467 thaw_processes();
373 } 468 }
374 return error; 469 return error;
375} 470}
@@ -389,6 +484,7 @@ int hibernate(void)
389 goto Unlock; 484 goto Unlock;
390 } 485 }
391 486
487 pm_prepare_console();
392 error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE); 488 error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE);
393 if (error) 489 if (error)
394 goto Exit; 490 goto Exit;
@@ -398,7 +494,7 @@ int hibernate(void)
398 if (error) 494 if (error)
399 goto Exit; 495 goto Exit;
400 496
401 printk("Syncing filesystems ... "); 497 printk(KERN_INFO "PM: Syncing filesystems ... ");
402 sys_sync(); 498 sys_sync();
403 printk("done.\n"); 499 printk("done.\n");
404 500
@@ -406,11 +502,12 @@ int hibernate(void)
406 if (error) 502 if (error)
407 goto Finish; 503 goto Finish;
408 504
409 if (hibernation_mode == HIBERNATION_TESTPROC) { 505 if (hibernation_test(TEST_FREEZER))
410 printk("swsusp debug: Waiting for 5 seconds.\n");
411 mdelay(5000);
412 goto Thaw; 506 goto Thaw;
413 } 507
508 if (hibernation_testmode(HIBERNATION_TESTPROC))
509 goto Thaw;
510
414 error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM); 511 error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM);
415 if (in_suspend && !error) { 512 if (in_suspend && !error) {
416 unsigned int flags = 0; 513 unsigned int flags = 0;
@@ -427,11 +524,12 @@ int hibernate(void)
427 swsusp_free(); 524 swsusp_free();
428 } 525 }
429 Thaw: 526 Thaw:
430 unprepare_processes(); 527 thaw_processes();
431 Finish: 528 Finish:
432 free_basic_memory_bitmaps(); 529 free_basic_memory_bitmaps();
433 Exit: 530 Exit:
434 pm_notifier_call_chain(PM_POST_HIBERNATION); 531 pm_notifier_call_chain(PM_POST_HIBERNATION);
532 pm_restore_console();
435 atomic_inc(&snapshot_device_available); 533 atomic_inc(&snapshot_device_available);
436 Unlock: 534 Unlock:
437 mutex_unlock(&pm_mutex); 535 mutex_unlock(&pm_mutex);
@@ -473,22 +571,23 @@ static int software_resume(void)
473 return -ENOENT; 571 return -ENOENT;
474 } 572 }
475 swsusp_resume_device = name_to_dev_t(resume_file); 573 swsusp_resume_device = name_to_dev_t(resume_file);
476 pr_debug("swsusp: Resume From Partition %s\n", resume_file); 574 pr_debug("PM: Resume from partition %s\n", resume_file);
477 } else { 575 } else {
478 pr_debug("swsusp: Resume From Partition %d:%d\n", 576 pr_debug("PM: Resume from partition %d:%d\n",
479 MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device)); 577 MAJOR(swsusp_resume_device),
578 MINOR(swsusp_resume_device));
480 } 579 }
481 580
482 if (noresume) { 581 if (noresume) {
483 /** 582 /**
484 * FIXME: If noresume is specified, we need to find the partition 583 * FIXME: If noresume is specified, we need to find the
485 * and reset it back to normal swap space. 584 * partition and reset it back to normal swap space.
486 */ 585 */
487 mutex_unlock(&pm_mutex); 586 mutex_unlock(&pm_mutex);
488 return 0; 587 return 0;
489 } 588 }
490 589
491 pr_debug("PM: Checking swsusp image.\n"); 590 pr_debug("PM: Checking hibernation image.\n");
492 error = swsusp_check(); 591 error = swsusp_check();
493 if (error) 592 if (error)
494 goto Unlock; 593 goto Unlock;
@@ -499,6 +598,11 @@ static int software_resume(void)
499 goto Unlock; 598 goto Unlock;
500 } 599 }
501 600
601 pm_prepare_console();
602 error = pm_notifier_call_chain(PM_RESTORE_PREPARE);
603 if (error)
604 goto Finish;
605
502 error = create_basic_memory_bitmaps(); 606 error = create_basic_memory_bitmaps();
503 if (error) 607 if (error)
504 goto Finish; 608 goto Finish;
@@ -510,7 +614,7 @@ static int software_resume(void)
510 goto Done; 614 goto Done;
511 } 615 }
512 616
513 pr_debug("PM: Reading swsusp image.\n"); 617 pr_debug("PM: Reading hibernation image.\n");
514 618
515 error = swsusp_read(&flags); 619 error = swsusp_read(&flags);
516 if (!error) 620 if (!error)
@@ -518,10 +622,12 @@ static int software_resume(void)
518 622
519 printk(KERN_ERR "PM: Restore failed, recovering.\n"); 623 printk(KERN_ERR "PM: Restore failed, recovering.\n");
520 swsusp_free(); 624 swsusp_free();
521 unprepare_processes(); 625 thaw_processes();
522 Done: 626 Done:
523 free_basic_memory_bitmaps(); 627 free_basic_memory_bitmaps();
524 Finish: 628 Finish:
629 pm_notifier_call_chain(PM_POST_RESTORE);
630 pm_restore_console();
525 atomic_inc(&snapshot_device_available); 631 atomic_inc(&snapshot_device_available);
526 /* For success case, the suspend path will release the lock */ 632 /* For success case, the suspend path will release the lock */
527 Unlock: 633 Unlock:
@@ -636,7 +742,7 @@ static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr,
636 error = -EINVAL; 742 error = -EINVAL;
637 743
638 if (!error) 744 if (!error)
639 pr_debug("PM: suspend-to-disk mode set to '%s'\n", 745 pr_debug("PM: Hibernation mode set to '%s'\n",
640 hibernation_modes[mode]); 746 hibernation_modes[mode]);
641 mutex_unlock(&pm_mutex); 747 mutex_unlock(&pm_mutex);
642 return error ? error : n; 748 return error ? error : n;
@@ -668,7 +774,7 @@ static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr,
668 mutex_lock(&pm_mutex); 774 mutex_lock(&pm_mutex);
669 swsusp_resume_device = res; 775 swsusp_resume_device = res;
670 mutex_unlock(&pm_mutex); 776 mutex_unlock(&pm_mutex);
671 printk("Attempting manual resume\n"); 777 printk(KERN_INFO "PM: Starting manual resume from disk\n");
672 noresume = 0; 778 noresume = 0;
673 software_resume(); 779 software_resume();
674 ret = n; 780 ret = n;
diff --git a/kernel/power/main.c b/kernel/power/main.c
index efc08360e627..6a6d5eb3524e 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -24,13 +24,112 @@
24 24
25#include "power.h" 25#include "power.h"
26 26
27BLOCKING_NOTIFIER_HEAD(pm_chain_head);
28
29DEFINE_MUTEX(pm_mutex); 27DEFINE_MUTEX(pm_mutex);
30 28
31unsigned int pm_flags; 29unsigned int pm_flags;
32EXPORT_SYMBOL(pm_flags); 30EXPORT_SYMBOL(pm_flags);
33 31
32#ifdef CONFIG_PM_SLEEP
33
34/* Routines for PM-transition notifications */
35
36static BLOCKING_NOTIFIER_HEAD(pm_chain_head);
37
38int register_pm_notifier(struct notifier_block *nb)
39{
40 return blocking_notifier_chain_register(&pm_chain_head, nb);
41}
42EXPORT_SYMBOL_GPL(register_pm_notifier);
43
44int unregister_pm_notifier(struct notifier_block *nb)
45{
46 return blocking_notifier_chain_unregister(&pm_chain_head, nb);
47}
48EXPORT_SYMBOL_GPL(unregister_pm_notifier);
49
50int pm_notifier_call_chain(unsigned long val)
51{
52 return (blocking_notifier_call_chain(&pm_chain_head, val, NULL)
53 == NOTIFY_BAD) ? -EINVAL : 0;
54}
55
56#ifdef CONFIG_PM_DEBUG
57int pm_test_level = TEST_NONE;
58
59static int suspend_test(int level)
60{
61 if (pm_test_level == level) {
62 printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n");
63 mdelay(5000);
64 return 1;
65 }
66 return 0;
67}
68
69static const char * const pm_tests[__TEST_AFTER_LAST] = {
70 [TEST_NONE] = "none",
71 [TEST_CORE] = "core",
72 [TEST_CPUS] = "processors",
73 [TEST_PLATFORM] = "platform",
74 [TEST_DEVICES] = "devices",
75 [TEST_FREEZER] = "freezer",
76};
77
78static ssize_t pm_test_show(struct kobject *kobj, struct kobj_attribute *attr,
79 char *buf)
80{
81 char *s = buf;
82 int level;
83
84 for (level = TEST_FIRST; level <= TEST_MAX; level++)
85 if (pm_tests[level]) {
86 if (level == pm_test_level)
87 s += sprintf(s, "[%s] ", pm_tests[level]);
88 else
89 s += sprintf(s, "%s ", pm_tests[level]);
90 }
91
92 if (s != buf)
93 /* convert the last space to a newline */
94 *(s-1) = '\n';
95
96 return (s - buf);
97}
98
99static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr,
100 const char *buf, size_t n)
101{
102 const char * const *s;
103 int level;
104 char *p;
105 int len;
106 int error = -EINVAL;
107
108 p = memchr(buf, '\n', n);
109 len = p ? p - buf : n;
110
111 mutex_lock(&pm_mutex);
112
113 level = TEST_FIRST;
114 for (s = &pm_tests[level]; level <= TEST_MAX; s++, level++)
115 if (*s && len == strlen(*s) && !strncmp(buf, *s, len)) {
116 pm_test_level = level;
117 error = 0;
118 break;
119 }
120
121 mutex_unlock(&pm_mutex);
122
123 return error ? error : n;
124}
125
126power_attr(pm_test);
127#else /* !CONFIG_PM_DEBUG */
128static inline int suspend_test(int level) { return 0; }
129#endif /* !CONFIG_PM_DEBUG */
130
131#endif /* CONFIG_PM_SLEEP */
132
34#ifdef CONFIG_SUSPEND 133#ifdef CONFIG_SUSPEND
35 134
36/* This is just an arbitrary number */ 135/* This is just an arbitrary number */
@@ -76,13 +175,13 @@ static int suspend_prepare(void)
76 if (!suspend_ops || !suspend_ops->enter) 175 if (!suspend_ops || !suspend_ops->enter)
77 return -EPERM; 176 return -EPERM;
78 177
178 pm_prepare_console();
179
79 error = pm_notifier_call_chain(PM_SUSPEND_PREPARE); 180 error = pm_notifier_call_chain(PM_SUSPEND_PREPARE);
80 if (error) 181 if (error)
81 goto Finish; 182 goto Finish;
82 183
83 pm_prepare_console(); 184 if (suspend_freeze_processes()) {
84
85 if (freeze_processes()) {
86 error = -EAGAIN; 185 error = -EAGAIN;
87 goto Thaw; 186 goto Thaw;
88 } 187 }
@@ -100,10 +199,10 @@ static int suspend_prepare(void)
100 return 0; 199 return 0;
101 200
102 Thaw: 201 Thaw:
103 thaw_processes(); 202 suspend_thaw_processes();
104 pm_restore_console();
105 Finish: 203 Finish:
106 pm_notifier_call_chain(PM_POST_SUSPEND); 204 pm_notifier_call_chain(PM_POST_SUSPEND);
205 pm_restore_console();
107 return error; 206 return error;
108} 207}
109 208
@@ -133,10 +232,13 @@ static int suspend_enter(suspend_state_t state)
133 BUG_ON(!irqs_disabled()); 232 BUG_ON(!irqs_disabled());
134 233
135 if ((error = device_power_down(PMSG_SUSPEND))) { 234 if ((error = device_power_down(PMSG_SUSPEND))) {
136 printk(KERN_ERR "Some devices failed to power down\n"); 235 printk(KERN_ERR "PM: Some devices failed to power down\n");
137 goto Done; 236 goto Done;
138 } 237 }
139 error = suspend_ops->enter(state); 238
239 if (!suspend_test(TEST_CORE))
240 error = suspend_ops->enter(state);
241
140 device_power_up(); 242 device_power_up();
141 Done: 243 Done:
142 arch_suspend_enable_irqs(); 244 arch_suspend_enable_irqs();
@@ -145,8 +247,8 @@ static int suspend_enter(suspend_state_t state)
145} 247}
146 248
147/** 249/**
148 * suspend_devices_and_enter - suspend devices and enter the desired system sleep 250 * suspend_devices_and_enter - suspend devices and enter the desired system
149 * state. 251 * sleep state.
150 * @state: state to enter 252 * @state: state to enter
151 */ 253 */
152int suspend_devices_and_enter(suspend_state_t state) 254int suspend_devices_and_enter(suspend_state_t state)
@@ -156,33 +258,45 @@ int suspend_devices_and_enter(suspend_state_t state)
156 if (!suspend_ops) 258 if (!suspend_ops)
157 return -ENOSYS; 259 return -ENOSYS;
158 260
159 if (suspend_ops->set_target) { 261 if (suspend_ops->begin) {
160 error = suspend_ops->set_target(state); 262 error = suspend_ops->begin(state);
161 if (error) 263 if (error)
162 return error; 264 goto Close;
163 } 265 }
164 suspend_console(); 266 suspend_console();
165 error = device_suspend(PMSG_SUSPEND); 267 error = device_suspend(PMSG_SUSPEND);
166 if (error) { 268 if (error) {
167 printk(KERN_ERR "Some devices failed to suspend\n"); 269 printk(KERN_ERR "PM: Some devices failed to suspend\n");
168 goto Resume_console; 270 goto Resume_console;
169 } 271 }
272
273 if (suspend_test(TEST_DEVICES))
274 goto Resume_devices;
275
170 if (suspend_ops->prepare) { 276 if (suspend_ops->prepare) {
171 error = suspend_ops->prepare(); 277 error = suspend_ops->prepare();
172 if (error) 278 if (error)
173 goto Resume_devices; 279 goto Resume_devices;
174 } 280 }
281
282 if (suspend_test(TEST_PLATFORM))
283 goto Finish;
284
175 error = disable_nonboot_cpus(); 285 error = disable_nonboot_cpus();
176 if (!error) 286 if (!error && !suspend_test(TEST_CPUS))
177 suspend_enter(state); 287 suspend_enter(state);
178 288
179 enable_nonboot_cpus(); 289 enable_nonboot_cpus();
290 Finish:
180 if (suspend_ops->finish) 291 if (suspend_ops->finish)
181 suspend_ops->finish(); 292 suspend_ops->finish();
182 Resume_devices: 293 Resume_devices:
183 device_resume(); 294 device_resume();
184 Resume_console: 295 Resume_console:
185 resume_console(); 296 resume_console();
297 Close:
298 if (suspend_ops->end)
299 suspend_ops->end();
186 return error; 300 return error;
187} 301}
188 302
@@ -194,9 +308,9 @@ int suspend_devices_and_enter(suspend_state_t state)
194 */ 308 */
195static void suspend_finish(void) 309static void suspend_finish(void)
196{ 310{
197 thaw_processes(); 311 suspend_thaw_processes();
198 pm_restore_console();
199 pm_notifier_call_chain(PM_POST_SUSPEND); 312 pm_notifier_call_chain(PM_POST_SUSPEND);
313 pm_restore_console();
200} 314}
201 315
202 316
@@ -238,17 +352,22 @@ static int enter_state(suspend_state_t state)
238 if (!mutex_trylock(&pm_mutex)) 352 if (!mutex_trylock(&pm_mutex))
239 return -EBUSY; 353 return -EBUSY;
240 354
241 printk("Syncing filesystems ... "); 355 printk(KERN_INFO "PM: Syncing filesystems ... ");
242 sys_sync(); 356 sys_sync();
243 printk("done.\n"); 357 printk("done.\n");
244 358
245 pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]); 359 pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);
246 if ((error = suspend_prepare())) 360 error = suspend_prepare();
361 if (error)
247 goto Unlock; 362 goto Unlock;
248 363
364 if (suspend_test(TEST_FREEZER))
365 goto Finish;
366
249 pr_debug("PM: Entering %s sleep\n", pm_states[state]); 367 pr_debug("PM: Entering %s sleep\n", pm_states[state]);
250 error = suspend_devices_and_enter(state); 368 error = suspend_devices_and_enter(state);
251 369
370 Finish:
252 pr_debug("PM: Finishing wakeup.\n"); 371 pr_debug("PM: Finishing wakeup.\n");
253 suspend_finish(); 372 suspend_finish();
254 Unlock: 373 Unlock:
@@ -369,18 +488,18 @@ pm_trace_store(struct kobject *kobj, struct kobj_attribute *attr,
369} 488}
370 489
371power_attr(pm_trace); 490power_attr(pm_trace);
491#endif /* CONFIG_PM_TRACE */
372 492
373static struct attribute * g[] = { 493static struct attribute * g[] = {
374 &state_attr.attr, 494 &state_attr.attr,
495#ifdef CONFIG_PM_TRACE
375 &pm_trace_attr.attr, 496 &pm_trace_attr.attr,
497#endif
498#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PM_DEBUG)
499 &pm_test_attr.attr,
500#endif
376 NULL, 501 NULL,
377}; 502};
378#else
379static struct attribute * g[] = {
380 &state_attr.attr,
381 NULL,
382};
383#endif /* CONFIG_PM_TRACE */
384 503
385static struct attribute_group attr_group = { 504static struct attribute_group attr_group = {
386 .attrs = g, 505 .attrs = g,
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 2093c3a9a994..700f44ec8406 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -1,5 +1,7 @@
1#include <linux/suspend.h> 1#include <linux/suspend.h>
2#include <linux/suspend_ioctls.h>
2#include <linux/utsname.h> 3#include <linux/utsname.h>
4#include <linux/freezer.h>
3 5
4struct swsusp_info { 6struct swsusp_info {
5 struct new_utsname uts; 7 struct new_utsname uts;
@@ -128,42 +130,12 @@ struct snapshot_handle {
128#define data_of(handle) ((handle).buffer + (handle).buf_offset) 130#define data_of(handle) ((handle).buffer + (handle).buf_offset)
129 131
130extern unsigned int snapshot_additional_pages(struct zone *zone); 132extern unsigned int snapshot_additional_pages(struct zone *zone);
133extern unsigned long snapshot_get_image_size(void);
131extern int snapshot_read_next(struct snapshot_handle *handle, size_t count); 134extern int snapshot_read_next(struct snapshot_handle *handle, size_t count);
132extern int snapshot_write_next(struct snapshot_handle *handle, size_t count); 135extern int snapshot_write_next(struct snapshot_handle *handle, size_t count);
133extern void snapshot_write_finalize(struct snapshot_handle *handle); 136extern void snapshot_write_finalize(struct snapshot_handle *handle);
134extern int snapshot_image_loaded(struct snapshot_handle *handle); 137extern int snapshot_image_loaded(struct snapshot_handle *handle);
135 138
136/*
137 * This structure is used to pass the values needed for the identification
138 * of the resume swap area from a user space to the kernel via the
139 * SNAPSHOT_SET_SWAP_AREA ioctl
140 */
141struct resume_swap_area {
142 loff_t offset;
143 u_int32_t dev;
144} __attribute__((packed));
145
146#define SNAPSHOT_IOC_MAGIC '3'
147#define SNAPSHOT_FREEZE _IO(SNAPSHOT_IOC_MAGIC, 1)
148#define SNAPSHOT_UNFREEZE _IO(SNAPSHOT_IOC_MAGIC, 2)
149#define SNAPSHOT_ATOMIC_SNAPSHOT _IOW(SNAPSHOT_IOC_MAGIC, 3, void *)
150#define SNAPSHOT_ATOMIC_RESTORE _IO(SNAPSHOT_IOC_MAGIC, 4)
151#define SNAPSHOT_FREE _IO(SNAPSHOT_IOC_MAGIC, 5)
152#define SNAPSHOT_SET_IMAGE_SIZE _IOW(SNAPSHOT_IOC_MAGIC, 6, unsigned long)
153#define SNAPSHOT_AVAIL_SWAP _IOR(SNAPSHOT_IOC_MAGIC, 7, void *)
154#define SNAPSHOT_GET_SWAP_PAGE _IOR(SNAPSHOT_IOC_MAGIC, 8, void *)
155#define SNAPSHOT_FREE_SWAP_PAGES _IO(SNAPSHOT_IOC_MAGIC, 9)
156#define SNAPSHOT_SET_SWAP_FILE _IOW(SNAPSHOT_IOC_MAGIC, 10, unsigned int)
157#define SNAPSHOT_S2RAM _IO(SNAPSHOT_IOC_MAGIC, 11)
158#define SNAPSHOT_PMOPS _IOW(SNAPSHOT_IOC_MAGIC, 12, unsigned int)
159#define SNAPSHOT_SET_SWAP_AREA _IOW(SNAPSHOT_IOC_MAGIC, 13, \
160 struct resume_swap_area)
161#define SNAPSHOT_IOC_MAXNR 13
162
163#define PMOPS_PREPARE 1
164#define PMOPS_ENTER 2
165#define PMOPS_FINISH 3
166
167/* If unset, the snapshot device cannot be open. */ 139/* If unset, the snapshot device cannot be open. */
168extern atomic_t snapshot_device_available; 140extern atomic_t snapshot_device_available;
169 141
@@ -181,7 +153,6 @@ extern int swsusp_swap_in_use(void);
181extern int swsusp_check(void); 153extern int swsusp_check(void);
182extern int swsusp_shrink_memory(void); 154extern int swsusp_shrink_memory(void);
183extern void swsusp_free(void); 155extern void swsusp_free(void);
184extern int swsusp_resume(void);
185extern int swsusp_read(unsigned int *flags_p); 156extern int swsusp_read(unsigned int *flags_p);
186extern int swsusp_write(unsigned int flags); 157extern int swsusp_write(unsigned int flags);
187extern void swsusp_close(void); 158extern void swsusp_close(void);
@@ -201,11 +172,56 @@ static inline int suspend_devices_and_enter(suspend_state_t state)
201} 172}
202#endif /* !CONFIG_SUSPEND */ 173#endif /* !CONFIG_SUSPEND */
203 174
204/* kernel/power/common.c */ 175#ifdef CONFIG_PM_SLEEP
205extern struct blocking_notifier_head pm_chain_head; 176/* kernel/power/main.c */
177extern int pm_notifier_call_chain(unsigned long val);
178#endif
179
180#ifdef CONFIG_HIGHMEM
181unsigned int count_highmem_pages(void);
182int restore_highmem(void);
183#else
184static inline unsigned int count_highmem_pages(void) { return 0; }
185static inline int restore_highmem(void) { return 0; }
186#endif
187
188/*
189 * Suspend test levels
190 */
191enum {
192 /* keep first */
193 TEST_NONE,
194 TEST_CORE,
195 TEST_CPUS,
196 TEST_PLATFORM,
197 TEST_DEVICES,
198 TEST_FREEZER,
199 /* keep last */
200 __TEST_AFTER_LAST
201};
202
203#define TEST_FIRST TEST_NONE
204#define TEST_MAX (__TEST_AFTER_LAST - 1)
205
206extern int pm_test_level;
207
208#ifdef CONFIG_SUSPEND_FREEZER
209static inline int suspend_freeze_processes(void)
210{
211 return freeze_processes();
212}
206 213
207static inline int pm_notifier_call_chain(unsigned long val) 214static inline void suspend_thaw_processes(void)
208{ 215{
209 return (blocking_notifier_call_chain(&pm_chain_head, val, NULL) 216 thaw_processes();
210 == NOTIFY_BAD) ? -EINVAL : 0;
211} 217}
218#else
219static inline int suspend_freeze_processes(void)
220{
221 return 0;
222}
223
224static inline void suspend_thaw_processes(void)
225{
226}
227#endif
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 78039b477d2b..f6a5df934f8d 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -635,7 +635,7 @@ __register_nosave_region(unsigned long start_pfn, unsigned long end_pfn,
635 region->end_pfn = end_pfn; 635 region->end_pfn = end_pfn;
636 list_add_tail(&region->list, &nosave_regions); 636 list_add_tail(&region->list, &nosave_regions);
637 Report: 637 Report:
638 printk("swsusp: Registered nosave memory region: %016lx - %016lx\n", 638 printk(KERN_INFO "PM: Registered nosave memory: %016lx - %016lx\n",
639 start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT); 639 start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT);
640} 640}
641 641
@@ -704,7 +704,7 @@ static void mark_nosave_pages(struct memory_bitmap *bm)
704 list_for_each_entry(region, &nosave_regions, list) { 704 list_for_each_entry(region, &nosave_regions, list) {
705 unsigned long pfn; 705 unsigned long pfn;
706 706
707 printk("swsusp: Marking nosave pages: %016lx - %016lx\n", 707 pr_debug("PM: Marking nosave pages: %016lx - %016lx\n",
708 region->start_pfn << PAGE_SHIFT, 708 region->start_pfn << PAGE_SHIFT,
709 region->end_pfn << PAGE_SHIFT); 709 region->end_pfn << PAGE_SHIFT);
710 710
@@ -749,7 +749,7 @@ int create_basic_memory_bitmaps(void)
749 free_pages_map = bm2; 749 free_pages_map = bm2;
750 mark_nosave_pages(forbidden_pages_map); 750 mark_nosave_pages(forbidden_pages_map);
751 751
752 printk("swsusp: Basic memory bitmaps created\n"); 752 pr_debug("PM: Basic memory bitmaps created\n");
753 753
754 return 0; 754 return 0;
755 755
@@ -784,7 +784,7 @@ void free_basic_memory_bitmaps(void)
784 memory_bm_free(bm2, PG_UNSAFE_CLEAR); 784 memory_bm_free(bm2, PG_UNSAFE_CLEAR);
785 kfree(bm2); 785 kfree(bm2);
786 786
787 printk("swsusp: Basic memory bitmaps freed\n"); 787 pr_debug("PM: Basic memory bitmaps freed\n");
788} 788}
789 789
790/** 790/**
@@ -872,7 +872,6 @@ unsigned int count_highmem_pages(void)
872} 872}
873#else 873#else
874static inline void *saveable_highmem_page(unsigned long pfn) { return NULL; } 874static inline void *saveable_highmem_page(unsigned long pfn) { return NULL; }
875static inline unsigned int count_highmem_pages(void) { return 0; }
876#endif /* CONFIG_HIGHMEM */ 875#endif /* CONFIG_HIGHMEM */
877 876
878/** 877/**
@@ -1089,7 +1088,7 @@ static int enough_free_mem(unsigned int nr_pages, unsigned int nr_highmem)
1089 } 1088 }
1090 1089
1091 nr_pages += count_pages_for_highmem(nr_highmem); 1090 nr_pages += count_pages_for_highmem(nr_highmem);
1092 pr_debug("swsusp: Normal pages needed: %u + %u + %u, available pages: %u\n", 1091 pr_debug("PM: Normal pages needed: %u + %u + %u, available pages: %u\n",
1093 nr_pages, PAGES_FOR_IO, meta, free); 1092 nr_pages, PAGES_FOR_IO, meta, free);
1094 1093
1095 return free > nr_pages + PAGES_FOR_IO + meta; 1094 return free > nr_pages + PAGES_FOR_IO + meta;
@@ -1202,20 +1201,20 @@ asmlinkage int swsusp_save(void)
1202{ 1201{
1203 unsigned int nr_pages, nr_highmem; 1202 unsigned int nr_pages, nr_highmem;
1204 1203
1205 printk("swsusp: critical section: \n"); 1204 printk(KERN_INFO "PM: Creating hibernation image: \n");
1206 1205
1207 drain_local_pages(); 1206 drain_local_pages();
1208 nr_pages = count_data_pages(); 1207 nr_pages = count_data_pages();
1209 nr_highmem = count_highmem_pages(); 1208 nr_highmem = count_highmem_pages();
1210 printk("swsusp: Need to copy %u pages\n", nr_pages + nr_highmem); 1209 printk(KERN_INFO "PM: Need to copy %u pages\n", nr_pages + nr_highmem);
1211 1210
1212 if (!enough_free_mem(nr_pages, nr_highmem)) { 1211 if (!enough_free_mem(nr_pages, nr_highmem)) {
1213 printk(KERN_ERR "swsusp: Not enough free memory\n"); 1212 printk(KERN_ERR "PM: Not enough free memory\n");
1214 return -ENOMEM; 1213 return -ENOMEM;
1215 } 1214 }
1216 1215
1217 if (swsusp_alloc(&orig_bm, &copy_bm, nr_pages, nr_highmem)) { 1216 if (swsusp_alloc(&orig_bm, &copy_bm, nr_pages, nr_highmem)) {
1218 printk(KERN_ERR "swsusp: Memory allocation failed\n"); 1217 printk(KERN_ERR "PM: Memory allocation failed\n");
1219 return -ENOMEM; 1218 return -ENOMEM;
1220 } 1219 }
1221 1220
@@ -1235,7 +1234,8 @@ asmlinkage int swsusp_save(void)
1235 nr_copy_pages = nr_pages; 1234 nr_copy_pages = nr_pages;
1236 nr_meta_pages = DIV_ROUND_UP(nr_pages * sizeof(long), PAGE_SIZE); 1235 nr_meta_pages = DIV_ROUND_UP(nr_pages * sizeof(long), PAGE_SIZE);
1237 1236
1238 printk("swsusp: critical section: done (%d pages copied)\n", nr_pages); 1237 printk(KERN_INFO "PM: Hibernation image created (%d pages copied)\n",
1238 nr_pages);
1239 1239
1240 return 0; 1240 return 0;
1241} 1241}
@@ -1264,12 +1264,17 @@ static char *check_image_kernel(struct swsusp_info *info)
1264} 1264}
1265#endif /* CONFIG_ARCH_HIBERNATION_HEADER */ 1265#endif /* CONFIG_ARCH_HIBERNATION_HEADER */
1266 1266
1267unsigned long snapshot_get_image_size(void)
1268{
1269 return nr_copy_pages + nr_meta_pages + 1;
1270}
1271
1267static int init_header(struct swsusp_info *info) 1272static int init_header(struct swsusp_info *info)
1268{ 1273{
1269 memset(info, 0, sizeof(struct swsusp_info)); 1274 memset(info, 0, sizeof(struct swsusp_info));
1270 info->num_physpages = num_physpages; 1275 info->num_physpages = num_physpages;
1271 info->image_pages = nr_copy_pages; 1276 info->image_pages = nr_copy_pages;
1272 info->pages = nr_copy_pages + nr_meta_pages + 1; 1277 info->pages = snapshot_get_image_size();
1273 info->size = info->pages; 1278 info->size = info->pages;
1274 info->size <<= PAGE_SHIFT; 1279 info->size <<= PAGE_SHIFT;
1275 return init_header_complete(info); 1280 return init_header_complete(info);
@@ -1429,7 +1434,7 @@ static int check_header(struct swsusp_info *info)
1429 if (!reason && info->num_physpages != num_physpages) 1434 if (!reason && info->num_physpages != num_physpages)
1430 reason = "memory size"; 1435 reason = "memory size";
1431 if (reason) { 1436 if (reason) {
1432 printk(KERN_ERR "swsusp: Resume mismatch: %s\n", reason); 1437 printk(KERN_ERR "PM: Image mismatch: %s\n", reason);
1433 return -EPERM; 1438 return -EPERM;
1434 } 1439 }
1435 return 0; 1440 return 0;
diff --git a/kernel/power/swap.c b/kernel/power/swap.c
index 917aba100575..a0abf9a463f9 100644
--- a/kernel/power/swap.c
+++ b/kernel/power/swap.c
@@ -28,8 +28,6 @@
28 28
29#include "power.h" 29#include "power.h"
30 30
31extern char resume_file[];
32
33#define SWSUSP_SIG "S1SUSPEND" 31#define SWSUSP_SIG "S1SUSPEND"
34 32
35struct swsusp_header { 33struct swsusp_header {
@@ -73,7 +71,8 @@ static int submit(int rw, pgoff_t page_off, struct page *page,
73 bio->bi_end_io = end_swap_bio_read; 71 bio->bi_end_io = end_swap_bio_read;
74 72
75 if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) { 73 if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
76 printk("swsusp: ERROR: adding page to bio at %ld\n", page_off); 74 printk(KERN_ERR "PM: Adding page to bio failed at %ld\n",
75 page_off);
77 bio_put(bio); 76 bio_put(bio);
78 return -EFAULT; 77 return -EFAULT;
79 } 78 }
@@ -153,7 +152,7 @@ static int mark_swapfiles(sector_t start, unsigned int flags)
153 error = bio_write_page(swsusp_resume_block, 152 error = bio_write_page(swsusp_resume_block,
154 swsusp_header, NULL); 153 swsusp_header, NULL);
155 } else { 154 } else {
156 printk(KERN_ERR "swsusp: Swap header not found!\n"); 155 printk(KERN_ERR "PM: Swap header not found!\n");
157 error = -ENODEV; 156 error = -ENODEV;
158 } 157 }
159 return error; 158 return error;
@@ -325,7 +324,8 @@ static int save_image(struct swap_map_handle *handle,
325 struct timeval start; 324 struct timeval start;
326 struct timeval stop; 325 struct timeval stop;
327 326
328 printk("Saving image data pages (%u pages) ... ", nr_to_write); 327 printk(KERN_INFO "PM: Saving image data pages (%u pages) ... ",
328 nr_to_write);
329 m = nr_to_write / 100; 329 m = nr_to_write / 100;
330 if (!m) 330 if (!m)
331 m = 1; 331 m = 1;
@@ -365,7 +365,7 @@ static int enough_swap(unsigned int nr_pages)
365{ 365{
366 unsigned int free_swap = count_swap_pages(root_swap, 1); 366 unsigned int free_swap = count_swap_pages(root_swap, 1);
367 367
368 pr_debug("swsusp: free swap pages: %u\n", free_swap); 368 pr_debug("PM: Free swap pages: %u\n", free_swap);
369 return free_swap > nr_pages + PAGES_FOR_IO; 369 return free_swap > nr_pages + PAGES_FOR_IO;
370} 370}
371 371
@@ -388,7 +388,7 @@ int swsusp_write(unsigned int flags)
388 388
389 error = swsusp_swap_check(); 389 error = swsusp_swap_check();
390 if (error) { 390 if (error) {
391 printk(KERN_ERR "swsusp: Cannot find swap device, try " 391 printk(KERN_ERR "PM: Cannot find swap device, try "
392 "swapon -a.\n"); 392 "swapon -a.\n");
393 return error; 393 return error;
394 } 394 }
@@ -402,7 +402,7 @@ int swsusp_write(unsigned int flags)
402 } 402 }
403 header = (struct swsusp_info *)data_of(snapshot); 403 header = (struct swsusp_info *)data_of(snapshot);
404 if (!enough_swap(header->pages)) { 404 if (!enough_swap(header->pages)) {
405 printk(KERN_ERR "swsusp: Not enough free swap\n"); 405 printk(KERN_ERR "PM: Not enough free swap\n");
406 error = -ENOSPC; 406 error = -ENOSPC;
407 goto out; 407 goto out;
408 } 408 }
@@ -417,7 +417,7 @@ int swsusp_write(unsigned int flags)
417 417
418 if (!error) { 418 if (!error) {
419 flush_swap_writer(&handle); 419 flush_swap_writer(&handle);
420 printk("S"); 420 printk(KERN_INFO "PM: S");
421 error = mark_swapfiles(start, flags); 421 error = mark_swapfiles(start, flags);
422 printk("|\n"); 422 printk("|\n");
423 } 423 }
@@ -507,7 +507,8 @@ static int load_image(struct swap_map_handle *handle,
507 int err2; 507 int err2;
508 unsigned nr_pages; 508 unsigned nr_pages;
509 509
510 printk("Loading image data pages (%u pages) ... ", nr_to_read); 510 printk(KERN_INFO "PM: Loading image data pages (%u pages) ... ",
511 nr_to_read);
511 m = nr_to_read / 100; 512 m = nr_to_read / 100;
512 if (!m) 513 if (!m)
513 m = 1; 514 m = 1;
@@ -558,7 +559,7 @@ int swsusp_read(unsigned int *flags_p)
558 559
559 *flags_p = swsusp_header->flags; 560 *flags_p = swsusp_header->flags;
560 if (IS_ERR(resume_bdev)) { 561 if (IS_ERR(resume_bdev)) {
561 pr_debug("swsusp: block device not initialised\n"); 562 pr_debug("PM: Image device not initialised\n");
562 return PTR_ERR(resume_bdev); 563 return PTR_ERR(resume_bdev);
563 } 564 }
564 565
@@ -577,9 +578,9 @@ int swsusp_read(unsigned int *flags_p)
577 blkdev_put(resume_bdev); 578 blkdev_put(resume_bdev);
578 579
579 if (!error) 580 if (!error)
580 pr_debug("swsusp: Reading resume file was successful\n"); 581 pr_debug("PM: Image successfully loaded\n");
581 else 582 else
582 pr_debug("swsusp: Error %d resuming\n", error); 583 pr_debug("PM: Error %d resuming\n", error);
583 return error; 584 return error;
584} 585}
585 586
@@ -611,13 +612,13 @@ int swsusp_check(void)
611 if (error) 612 if (error)
612 blkdev_put(resume_bdev); 613 blkdev_put(resume_bdev);
613 else 614 else
614 pr_debug("swsusp: Signature found, resuming\n"); 615 pr_debug("PM: Signature found, resuming\n");
615 } else { 616 } else {
616 error = PTR_ERR(resume_bdev); 617 error = PTR_ERR(resume_bdev);
617 } 618 }
618 619
619 if (error) 620 if (error)
620 pr_debug("swsusp: Error %d check for resume file\n", error); 621 pr_debug("PM: Error %d checking image file\n", error);
621 622
622 return error; 623 return error;
623} 624}
@@ -629,7 +630,7 @@ int swsusp_check(void)
629void swsusp_close(void) 630void swsusp_close(void)
630{ 631{
631 if (IS_ERR(resume_bdev)) { 632 if (IS_ERR(resume_bdev)) {
632 pr_debug("swsusp: block device not initialised\n"); 633 pr_debug("PM: Image device not initialised\n");
633 return; 634 return;
634 } 635 }
635 636
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index e1722d3155f1..023ff2a31d89 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -64,14 +64,6 @@ unsigned long image_size = 500 * 1024 * 1024;
64 64
65int in_suspend __nosavedata = 0; 65int in_suspend __nosavedata = 0;
66 66
67#ifdef CONFIG_HIGHMEM
68unsigned int count_highmem_pages(void);
69int restore_highmem(void);
70#else
71static inline int restore_highmem(void) { return 0; }
72static inline unsigned int count_highmem_pages(void) { return 0; }
73#endif
74
75/** 67/**
76 * The following functions are used for tracing the allocated 68 * The following functions are used for tracing the allocated
77 * swap pages, so that they can be freed in case of an error. 69 * swap pages, so that they can be freed in case of an error.
@@ -196,7 +188,8 @@ void swsusp_show_speed(struct timeval *start, struct timeval *stop,
196 centisecs = 1; /* avoid div-by-zero */ 188 centisecs = 1; /* avoid div-by-zero */
197 k = nr_pages * (PAGE_SIZE / 1024); 189 k = nr_pages * (PAGE_SIZE / 1024);
198 kps = (k * 100) / centisecs; 190 kps = (k * 100) / centisecs;
199 printk("%s %d kbytes in %d.%02d seconds (%d.%02d MB/s)\n", msg, k, 191 printk(KERN_INFO "PM: %s %d kbytes in %d.%02d seconds (%d.%02d MB/s)\n",
192 msg, k,
200 centisecs / 100, centisecs % 100, 193 centisecs / 100, centisecs % 100,
201 kps / 1000, (kps % 1000) / 10); 194 kps / 1000, (kps % 1000) / 10);
202} 195}
@@ -227,7 +220,7 @@ int swsusp_shrink_memory(void)
227 char *p = "-\\|/"; 220 char *p = "-\\|/";
228 struct timeval start, stop; 221 struct timeval start, stop;
229 222
230 printk("Shrinking memory... "); 223 printk(KERN_INFO "PM: Shrinking memory... ");
231 do_gettimeofday(&start); 224 do_gettimeofday(&start);
232 do { 225 do {
233 long size, highmem_size; 226 long size, highmem_size;
@@ -269,38 +262,3 @@ int swsusp_shrink_memory(void)
269 262
270 return 0; 263 return 0;
271} 264}
272
273int swsusp_resume(void)
274{
275 int error;
276
277 local_irq_disable();
278 /* NOTE: device_power_down() is just a suspend() with irqs off;
279 * it has no special "power things down" semantics
280 */
281 if (device_power_down(PMSG_PRETHAW))
282 printk(KERN_ERR "Some devices failed to power down, very bad\n");
283 /* We'll ignore saved state, but this gets preempt count (etc) right */
284 save_processor_state();
285 error = restore_highmem();
286 if (!error) {
287 error = swsusp_arch_resume();
288 /* The code below is only ever reached in case of a failure.
289 * Otherwise execution continues at place where
290 * swsusp_arch_suspend() was called
291 */
292 BUG_ON(!error);
293 /* This call to restore_highmem() undos the previous one */
294 restore_highmem();
295 }
296 /* The only reason why swsusp_arch_resume() can fail is memory being
297 * very tight, so we have to free it as soon as we can to avoid
298 * subsequent failures
299 */
300 swsusp_free();
301 restore_processor_state();
302 touch_softlockup_watchdog();
303 device_power_up();
304 local_irq_enable();
305 return error;
306}
diff --git a/kernel/power/user.c b/kernel/power/user.c
index 5bd321bcbb75..f5512cb3aa86 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -28,6 +28,29 @@
28 28
29#include "power.h" 29#include "power.h"
30 30
31/*
32 * NOTE: The SNAPSHOT_SET_SWAP_FILE and SNAPSHOT_PMOPS ioctls are obsolete and
33 * will be removed in the future. They are only preserved here for
34 * compatibility with existing userland utilities.
35 */
36#define SNAPSHOT_SET_SWAP_FILE _IOW(SNAPSHOT_IOC_MAGIC, 10, unsigned int)
37#define SNAPSHOT_PMOPS _IOW(SNAPSHOT_IOC_MAGIC, 12, unsigned int)
38
39#define PMOPS_PREPARE 1
40#define PMOPS_ENTER 2
41#define PMOPS_FINISH 3
42
43/*
44 * NOTE: The following ioctl definitions are wrong and have been replaced with
45 * correct ones. They are only preserved here for compatibility with existing
46 * userland utilities and will be removed in the future.
47 */
48#define SNAPSHOT_ATOMIC_SNAPSHOT _IOW(SNAPSHOT_IOC_MAGIC, 3, void *)
49#define SNAPSHOT_SET_IMAGE_SIZE _IOW(SNAPSHOT_IOC_MAGIC, 6, unsigned long)
50#define SNAPSHOT_AVAIL_SWAP _IOR(SNAPSHOT_IOC_MAGIC, 7, void *)
51#define SNAPSHOT_GET_SWAP_PAGE _IOR(SNAPSHOT_IOC_MAGIC, 8, void *)
52
53
31#define SNAPSHOT_MINOR 231 54#define SNAPSHOT_MINOR 231
32 55
33static struct snapshot_data { 56static struct snapshot_data {
@@ -36,7 +59,7 @@ static struct snapshot_data {
36 int mode; 59 int mode;
37 char frozen; 60 char frozen;
38 char ready; 61 char ready;
39 char platform_suspend; 62 char platform_support;
40} snapshot_state; 63} snapshot_state;
41 64
42atomic_t snapshot_device_available = ATOMIC_INIT(1); 65atomic_t snapshot_device_available = ATOMIC_INIT(1);
@@ -44,6 +67,7 @@ atomic_t snapshot_device_available = ATOMIC_INIT(1);
44static int snapshot_open(struct inode *inode, struct file *filp) 67static int snapshot_open(struct inode *inode, struct file *filp)
45{ 68{
46 struct snapshot_data *data; 69 struct snapshot_data *data;
70 int error;
47 71
48 if (!atomic_add_unless(&snapshot_device_available, -1, 0)) 72 if (!atomic_add_unless(&snapshot_device_available, -1, 0))
49 return -EBUSY; 73 return -EBUSY;
@@ -64,13 +88,23 @@ static int snapshot_open(struct inode *inode, struct file *filp)
64 data->swap = swsusp_resume_device ? 88 data->swap = swsusp_resume_device ?
65 swap_type_of(swsusp_resume_device, 0, NULL) : -1; 89 swap_type_of(swsusp_resume_device, 0, NULL) : -1;
66 data->mode = O_RDONLY; 90 data->mode = O_RDONLY;
91 error = pm_notifier_call_chain(PM_RESTORE_PREPARE);
92 if (error)
93 pm_notifier_call_chain(PM_POST_RESTORE);
67 } else { 94 } else {
68 data->swap = -1; 95 data->swap = -1;
69 data->mode = O_WRONLY; 96 data->mode = O_WRONLY;
97 error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE);
98 if (error)
99 pm_notifier_call_chain(PM_POST_HIBERNATION);
100 }
101 if (error) {
102 atomic_inc(&snapshot_device_available);
103 return error;
70 } 104 }
71 data->frozen = 0; 105 data->frozen = 0;
72 data->ready = 0; 106 data->ready = 0;
73 data->platform_suspend = 0; 107 data->platform_support = 0;
74 108
75 return 0; 109 return 0;
76} 110}
@@ -88,6 +122,8 @@ static int snapshot_release(struct inode *inode, struct file *filp)
88 thaw_processes(); 122 thaw_processes();
89 mutex_unlock(&pm_mutex); 123 mutex_unlock(&pm_mutex);
90 } 124 }
125 pm_notifier_call_chain(data->mode == O_WRONLY ?
126 PM_POST_HIBERNATION : PM_POST_RESTORE);
91 atomic_inc(&snapshot_device_available); 127 atomic_inc(&snapshot_device_available);
92 return 0; 128 return 0;
93} 129}
@@ -133,7 +169,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
133{ 169{
134 int error = 0; 170 int error = 0;
135 struct snapshot_data *data; 171 struct snapshot_data *data;
136 loff_t avail; 172 loff_t size;
137 sector_t offset; 173 sector_t offset;
138 174
139 if (_IOC_TYPE(cmd) != SNAPSHOT_IOC_MAGIC) 175 if (_IOC_TYPE(cmd) != SNAPSHOT_IOC_MAGIC)
@@ -151,18 +187,13 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
151 if (data->frozen) 187 if (data->frozen)
152 break; 188 break;
153 mutex_lock(&pm_mutex); 189 mutex_lock(&pm_mutex);
154 error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE); 190 printk("Syncing filesystems ... ");
155 if (!error) { 191 sys_sync();
156 printk("Syncing filesystems ... "); 192 printk("done.\n");
157 sys_sync(); 193
158 printk("done.\n"); 194 error = freeze_processes();
159
160 error = freeze_processes();
161 if (error)
162 thaw_processes();
163 }
164 if (error) 195 if (error)
165 pm_notifier_call_chain(PM_POST_HIBERNATION); 196 thaw_processes();
166 mutex_unlock(&pm_mutex); 197 mutex_unlock(&pm_mutex);
167 if (!error) 198 if (!error)
168 data->frozen = 1; 199 data->frozen = 1;
@@ -173,19 +204,19 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
173 break; 204 break;
174 mutex_lock(&pm_mutex); 205 mutex_lock(&pm_mutex);
175 thaw_processes(); 206 thaw_processes();
176 pm_notifier_call_chain(PM_POST_HIBERNATION);
177 mutex_unlock(&pm_mutex); 207 mutex_unlock(&pm_mutex);
178 data->frozen = 0; 208 data->frozen = 0;
179 break; 209 break;
180 210
211 case SNAPSHOT_CREATE_IMAGE:
181 case SNAPSHOT_ATOMIC_SNAPSHOT: 212 case SNAPSHOT_ATOMIC_SNAPSHOT:
182 if (data->mode != O_RDONLY || !data->frozen || data->ready) { 213 if (data->mode != O_RDONLY || !data->frozen || data->ready) {
183 error = -EPERM; 214 error = -EPERM;
184 break; 215 break;
185 } 216 }
186 error = hibernation_snapshot(data->platform_suspend); 217 error = hibernation_snapshot(data->platform_support);
187 if (!error) 218 if (!error)
188 error = put_user(in_suspend, (unsigned int __user *)arg); 219 error = put_user(in_suspend, (int __user *)arg);
189 if (!error) 220 if (!error)
190 data->ready = 1; 221 data->ready = 1;
191 break; 222 break;
@@ -197,7 +228,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
197 error = -EPERM; 228 error = -EPERM;
198 break; 229 break;
199 } 230 }
200 error = hibernation_restore(data->platform_suspend); 231 error = hibernation_restore(data->platform_support);
201 break; 232 break;
202 233
203 case SNAPSHOT_FREE: 234 case SNAPSHOT_FREE:
@@ -206,16 +237,29 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
206 data->ready = 0; 237 data->ready = 0;
207 break; 238 break;
208 239
240 case SNAPSHOT_PREF_IMAGE_SIZE:
209 case SNAPSHOT_SET_IMAGE_SIZE: 241 case SNAPSHOT_SET_IMAGE_SIZE:
210 image_size = arg; 242 image_size = arg;
211 break; 243 break;
212 244
245 case SNAPSHOT_GET_IMAGE_SIZE:
246 if (!data->ready) {
247 error = -ENODATA;
248 break;
249 }
250 size = snapshot_get_image_size();
251 size <<= PAGE_SHIFT;
252 error = put_user(size, (loff_t __user *)arg);
253 break;
254
255 case SNAPSHOT_AVAIL_SWAP_SIZE:
213 case SNAPSHOT_AVAIL_SWAP: 256 case SNAPSHOT_AVAIL_SWAP:
214 avail = count_swap_pages(data->swap, 1); 257 size = count_swap_pages(data->swap, 1);
215 avail <<= PAGE_SHIFT; 258 size <<= PAGE_SHIFT;
216 error = put_user(avail, (loff_t __user *)arg); 259 error = put_user(size, (loff_t __user *)arg);
217 break; 260 break;
218 261
262 case SNAPSHOT_ALLOC_SWAP_PAGE:
219 case SNAPSHOT_GET_SWAP_PAGE: 263 case SNAPSHOT_GET_SWAP_PAGE:
220 if (data->swap < 0 || data->swap >= MAX_SWAPFILES) { 264 if (data->swap < 0 || data->swap >= MAX_SWAPFILES) {
221 error = -ENODEV; 265 error = -ENODEV;
@@ -224,7 +268,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
224 offset = alloc_swapdev_block(data->swap); 268 offset = alloc_swapdev_block(data->swap);
225 if (offset) { 269 if (offset) {
226 offset <<= PAGE_SHIFT; 270 offset <<= PAGE_SHIFT;
227 error = put_user(offset, (sector_t __user *)arg); 271 error = put_user(offset, (loff_t __user *)arg);
228 } else { 272 } else {
229 error = -ENOSPC; 273 error = -ENOSPC;
230 } 274 }
@@ -238,7 +282,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
238 free_all_swap_pages(data->swap); 282 free_all_swap_pages(data->swap);
239 break; 283 break;
240 284
241 case SNAPSHOT_SET_SWAP_FILE: 285 case SNAPSHOT_SET_SWAP_FILE: /* This ioctl is deprecated */
242 if (!swsusp_swap_in_use()) { 286 if (!swsusp_swap_in_use()) {
243 /* 287 /*
244 * User space encodes device types as two-byte values, 288 * User space encodes device types as two-byte values,
@@ -275,26 +319,33 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
275 mutex_unlock(&pm_mutex); 319 mutex_unlock(&pm_mutex);
276 break; 320 break;
277 321
278 case SNAPSHOT_PMOPS: 322 case SNAPSHOT_PLATFORM_SUPPORT:
323 data->platform_support = !!arg;
324 break;
325
326 case SNAPSHOT_POWER_OFF:
327 if (data->platform_support)
328 error = hibernation_platform_enter();
329 break;
330
331 case SNAPSHOT_PMOPS: /* This ioctl is deprecated */
279 error = -EINVAL; 332 error = -EINVAL;
280 333
281 switch (arg) { 334 switch (arg) {
282 335
283 case PMOPS_PREPARE: 336 case PMOPS_PREPARE:
284 data->platform_suspend = 1; 337 data->platform_support = 1;
285 error = 0; 338 error = 0;
286 break; 339 break;
287 340
288 case PMOPS_ENTER: 341 case PMOPS_ENTER:
289 if (data->platform_suspend) 342 if (data->platform_support)
290 error = hibernation_platform_enter(); 343 error = hibernation_platform_enter();
291
292 break; 344 break;
293 345
294 case PMOPS_FINISH: 346 case PMOPS_FINISH:
295 if (data->platform_suspend) 347 if (data->platform_support)
296 error = 0; 348 error = 0;
297
298 break; 349 break;
299 350
300 default: 351 default: