2 * Copyright (C) 2004-2007 Nigel Cunningham (nigel at suspend2 net)
4 * This file is released under the GPLv2.
6 #include <linux/module.h>
7 #include <linux/resume-trace.h>
8 #include <linux/syscalls.h>
9 #include <linux/kernel.h>
10 #include <linux/swap.h>
11 #include <linux/syscalls.h>
12 #include <linux/bio.h>
13 #include <linux/root_dev.h>
14 #include <linux/freezer.h>
15 #include <linux/reboot.h>
16 #include <linux/writeback.h>
17 #include <linux/tty.h>
18 #include <linux/crypto.h>
19 #include <linux/cpu.h>
20 #include <linux/dyn_pageflags.h>
26 #include "prepare_image.h"
31 #include "suspend_builtin.h"
33 #ifdef CONFIG_SUSPEND2_CORE_EXPORTS
34 #ifdef CONFIG_SOFTWARE_SUSPEND
35 EXPORT_SYMBOL_GPL(resume_file
);
38 EXPORT_SYMBOL_GPL(max_pfn
);
39 EXPORT_SYMBOL_GPL(free_dyn_pageflags
);
40 EXPORT_SYMBOL_GPL(clear_dynpageflag
);
41 EXPORT_SYMBOL_GPL(test_dynpageflag
);
42 EXPORT_SYMBOL_GPL(set_dynpageflag
);
43 EXPORT_SYMBOL_GPL(get_next_bit_on
);
44 EXPORT_SYMBOL_GPL(allocate_dyn_pageflags
);
45 EXPORT_SYMBOL_GPL(clear_dyn_pageflags
);
48 EXPORT_SYMBOL_GPL(restore_processor_state
);
49 EXPORT_SYMBOL_GPL(save_processor_state
);
52 EXPORT_SYMBOL_GPL(kernel_shutdown_prepare
);
53 EXPORT_SYMBOL_GPL(drop_pagecache
);
54 EXPORT_SYMBOL_GPL(pagedir_nosave
);
55 EXPORT_SYMBOL_GPL(pm_sem
);
56 EXPORT_SYMBOL_GPL(pm_restore_console
);
57 EXPORT_SYMBOL_GPL(super_blocks
);
58 EXPORT_SYMBOL_GPL(next_zone
);
60 EXPORT_SYMBOL_GPL(freeze_processes
);
61 EXPORT_SYMBOL_GPL(thaw_processes
);
62 EXPORT_SYMBOL_GPL(thaw_kernel_threads
);
63 EXPORT_SYMBOL_GPL(shrink_all_memory
);
64 EXPORT_SYMBOL_GPL(shrink_one_zone
);
65 EXPORT_SYMBOL_GPL(saveable
);
66 EXPORT_SYMBOL_GPL(swsusp_arch_suspend
);
67 EXPORT_SYMBOL_GPL(swsusp_arch_resume
);
68 EXPORT_SYMBOL_GPL(pm_ops
);
69 EXPORT_SYMBOL_GPL(pm_prepare_console
);
70 EXPORT_SYMBOL_GPL(follow_page
);
71 EXPORT_SYMBOL_GPL(machine_halt
);
72 EXPORT_SYMBOL_GPL(block_dump
);
73 EXPORT_SYMBOL_GPL(unlink_lru_lists
);
74 EXPORT_SYMBOL_GPL(relink_lru_lists
);
75 EXPORT_SYMBOL_GPL(power_subsys
);
76 EXPORT_SYMBOL_GPL(machine_power_off
);
77 EXPORT_SYMBOL_GPL(suspend_enter
);
78 EXPORT_SYMBOL_GPL(first_online_pgdat
);
79 EXPORT_SYMBOL_GPL(next_online_pgdat
);
80 EXPORT_SYMBOL_GPL(machine_restart
);
81 EXPORT_SYMBOL_GPL(saved_command_line
);
82 EXPORT_SYMBOL_GPL(tasklist_lock
);
83 #ifdef CONFIG_SUSPEND_SMP
84 EXPORT_SYMBOL_GPL(disable_nonboot_cpus
);
85 EXPORT_SYMBOL_GPL(enable_nonboot_cpus
);
89 #ifdef CONFIG_SUSPEND2_USERUI_EXPORTS
90 EXPORT_SYMBOL_GPL(kmsg_redirect
);
91 EXPORT_SYMBOL_GPL(console_printk
);
93 EXPORT_SYMBOL_GPL(sys_ioctl
);
97 #ifdef CONFIG_SUSPEND2_SWAP_EXPORTS /* Suspend swap specific */
98 EXPORT_SYMBOL_GPL(sys_swapon
);
99 EXPORT_SYMBOL_GPL(sys_swapoff
);
100 EXPORT_SYMBOL_GPL(si_swapinfo
);
101 EXPORT_SYMBOL_GPL(map_swap_page
);
102 EXPORT_SYMBOL_GPL(get_swap_page
);
103 EXPORT_SYMBOL_GPL(swap_free
);
104 EXPORT_SYMBOL_GPL(get_swap_info_struct
);
107 #ifdef CONFIG_SUSPEND2_FILE_EXPORTS
108 /* Suspend_file specific */
109 extern char * __initdata root_device_name
;
111 EXPORT_SYMBOL_GPL(ROOT_DEV
);
112 EXPORT_SYMBOL_GPL(root_device_name
);
113 EXPORT_SYMBOL_GPL(sys_unlink
);
114 EXPORT_SYMBOL_GPL(sys_mknod
);
118 #if defined(CONFIG_SUSPEND2_FILE_EXPORTS) || defined(CONFIG_SUSPEND2_SWAP_EXPORTS)
119 EXPORT_SYMBOL_GPL(bio_set_pages_dirty
);
120 EXPORT_SYMBOL_GPL(name_to_dev_t
);
123 #if defined(CONFIG_SUSPEND2_EXPORTS) || defined(CONFIG_SUSPEND2_CORE_EXPORTS)
124 EXPORT_SYMBOL_GPL(snprintf_used
);
126 struct suspend2_core_fns
*s2_core_fns
;
127 EXPORT_SYMBOL_GPL(s2_core_fns
);
129 dyn_pageflags_t pageset1_map
;
130 dyn_pageflags_t pageset1_copy_map
;
131 EXPORT_SYMBOL_GPL(pageset1_map
);
132 EXPORT_SYMBOL_GPL(pageset1_copy_map
);
134 unsigned long suspend_result
= 0;
135 unsigned long suspend_debug_state
= 0;
136 int suspend_io_time
[2][2];
137 struct pagedir pagedir1
= {1};
139 EXPORT_SYMBOL_GPL(suspend_io_time
);
140 EXPORT_SYMBOL_GPL(suspend_debug_state
);
141 EXPORT_SYMBOL_GPL(suspend_result
);
142 EXPORT_SYMBOL_GPL(pagedir1
);
144 unsigned long suspend_get_nonconflicting_page(void)
146 return s2_core_fns
->get_nonconflicting_page();
149 int suspend_post_context_save(void)
151 return s2_core_fns
->post_context_save();
154 int suspend2_try_suspend(int have_pmsem
)
159 return s2_core_fns
->try_suspend(have_pmsem
);
162 void suspend2_try_resume(void)
165 s2_core_fns
->try_resume();
168 int suspend2_lowlevel_builtin(void)
172 save_processor_state();
173 if ((error
= swsusp_arch_suspend()))
174 printk(KERN_ERR
"Error %d suspending\n", error
);
175 /* Restore control flow appears here */
176 restore_processor_state();
181 EXPORT_SYMBOL_GPL(suspend2_lowlevel_builtin
);
183 unsigned long suspend_compress_bytes_in
, suspend_compress_bytes_out
;
184 EXPORT_SYMBOL_GPL(suspend_compress_bytes_in
);
185 EXPORT_SYMBOL_GPL(suspend_compress_bytes_out
);
187 #ifdef CONFIG_SUSPEND2_REPLACE_SWSUSP
188 unsigned long suspend_action
= (1 << SUSPEND_REPLACE_SWSUSP
) | (1 << SUSPEND_PAGESET2_FULL
);
190 unsigned long suspend_action
= 1 << SUSPEND_PAGESET2_FULL
;
192 EXPORT_SYMBOL_GPL(suspend_action
);
194 unsigned long suspend_state
= ((1 << SUSPEND_BOOT_TIME
) |
195 (1 << SUSPEND_RESUME_NOT_DONE
) |
196 (1 << SUSPEND_IGNORE_LOGLEVEL
) |
197 (1 << SUSPEND_IO_STOPPED
));
198 EXPORT_SYMBOL_GPL(suspend_state
);
200 /* The number of suspends we have started (some may have been cancelled) */
201 unsigned int nr_suspends
;
202 EXPORT_SYMBOL_GPL(nr_suspends
);
204 char resume2_file
[256] = CONFIG_SUSPEND2_DEFAULT_RESUME2
;
205 EXPORT_SYMBOL_GPL(resume2_file
);
207 int suspend2_running
= 0;
208 EXPORT_SYMBOL_GPL(suspend2_running
);
210 int suspend2_in_suspend __nosavedata
;
211 EXPORT_SYMBOL_GPL(suspend2_in_suspend
);
213 unsigned long suspend2_nosave_state1 __nosavedata
= 0;
214 unsigned long suspend2_nosave_state2 __nosavedata
= 0;
215 int suspend2_nosave_state3 __nosavedata
= 0;
216 int suspend2_nosave_io_speed
[2][2] __nosavedata
;
217 __nosavedata
char suspend2_nosave_commandline
[COMMAND_LINE_SIZE
];
219 __nosavedata
struct pbe
*restore_highmem_pblist
;
221 #ifdef CONFIG_SUSPEND2_CORE_EXPORTS
222 #ifdef CONFIG_HIGHMEM
223 EXPORT_SYMBOL_GPL(nr_free_highpages
);
224 EXPORT_SYMBOL_GPL(restore_highmem_pblist
);
227 EXPORT_SYMBOL_GPL(suspend2_nosave_state1
);
228 EXPORT_SYMBOL_GPL(suspend2_nosave_state2
);
229 EXPORT_SYMBOL_GPL(suspend2_nosave_state3
);
230 EXPORT_SYMBOL_GPL(suspend2_nosave_io_speed
);
231 EXPORT_SYMBOL_GPL(suspend2_nosave_commandline
);
234 /* -- Commandline Parameter Handling ---
236 * Resume setup: obtain the storage device.
238 static int __init
resume2_setup(char *str
)
243 strncpy(resume2_file
, str
, 255);
248 * Allow the user to specify that we should ignore any image found and
249 * invalidate the image if necesssary. This is equivalent to running
250 * the task queue and a sync and then turning off the power. The same
251 * precautions should be taken: fsck if you're not journalled.
253 static int __init
noresume2_setup(char *str
)
255 set_suspend_state(SUSPEND_NORESUME_SPECIFIED
);
259 static int __init
suspend_retry_resume_setup(char *str
)
261 set_suspend_state(SUSPEND_RETRY_RESUME
);
265 #ifndef CONFIG_SOFTWARE_SUSPEND
266 static int __init
resume_setup(char *str
)
271 strncpy(resume2_file
, str
, 255);
275 static int __init
noresume_setup(char *str
)
277 set_suspend_state(SUSPEND_NORESUME_SPECIFIED
);
280 __setup("noresume", noresume_setup
);
281 __setup("resume=", resume_setup
);
284 __setup("noresume2", noresume2_setup
);
285 __setup("resume2=", resume2_setup
);
286 __setup("suspend_retry_resume", suspend_retry_resume_setup
);