| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | #include <linux/suspend.h> | 
| Rafael J. Wysocki | 3010f8c | 2007-10-26 01:05:05 +0200 | [diff] [blame] | 2 | #include <linux/suspend_ioctls.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 3 | #include <linux/utsname.h> | 
| Johannes Berg | b28f508 | 2008-01-15 23:17:00 -0500 | [diff] [blame] | 4 | #include <linux/freezer.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 5 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 6 | struct swsusp_info { | 
|  | 7 | struct new_utsname	uts; | 
|  | 8 | u32			version_code; | 
|  | 9 | unsigned long		num_physpages; | 
|  | 10 | int			cpus; | 
|  | 11 | unsigned long		image_pages; | 
| Rafael J. Wysocki | 7088a5c | 2006-01-06 00:13:05 -0800 | [diff] [blame] | 12 | unsigned long		pages; | 
| Rafael J. Wysocki | 6e1819d | 2006-03-23 03:00:03 -0800 | [diff] [blame] | 13 | unsigned long		size; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 14 | } __attribute__((aligned(PAGE_SIZE))); | 
|  | 15 |  | 
| Rafael J. Wysocki | b0cb1a1 | 2007-07-29 23:24:36 +0200 | [diff] [blame] | 16 | #ifdef CONFIG_HIBERNATION | 
| Rafael J. Wysocki | d307c4a | 2007-10-18 03:04:52 -0700 | [diff] [blame] | 17 | #ifdef CONFIG_ARCH_HIBERNATION_HEADER | 
|  | 18 | /* Maximum size of architecture specific data in a hibernation header */ | 
|  | 19 | #define MAX_ARCH_HEADER_SIZE	(sizeof(struct new_utsname) + 4) | 
|  | 20 |  | 
|  | 21 | extern int arch_hibernation_header_save(void *addr, unsigned int max_size); | 
|  | 22 | extern int arch_hibernation_header_restore(void *addr); | 
|  | 23 |  | 
|  | 24 | static inline int init_header_complete(struct swsusp_info *info) | 
|  | 25 | { | 
|  | 26 | return arch_hibernation_header_save(info, MAX_ARCH_HEADER_SIZE); | 
|  | 27 | } | 
|  | 28 |  | 
|  | 29 | static inline char *check_image_kernel(struct swsusp_info *info) | 
|  | 30 | { | 
|  | 31 | return arch_hibernation_header_restore(info) ? | 
|  | 32 | "architecture specific data" : NULL; | 
|  | 33 | } | 
|  | 34 | #endif /* CONFIG_ARCH_HIBERNATION_HEADER */ | 
|  | 35 |  | 
| Rafael J. Wysocki | 56f99bc | 2007-05-06 14:50:52 -0700 | [diff] [blame] | 36 | /* | 
|  | 37 | * Keep some memory free so that I/O operations can succeed without paging | 
|  | 38 | * [Might this be more than 4 MB?] | 
|  | 39 | */ | 
|  | 40 | #define PAGES_FOR_IO	((4096 * 1024) >> PAGE_SHIFT) | 
| Rafael J. Wysocki | d307c4a | 2007-10-18 03:04:52 -0700 | [diff] [blame] | 41 |  | 
| Rafael J. Wysocki | 56f99bc | 2007-05-06 14:50:52 -0700 | [diff] [blame] | 42 | /* | 
|  | 43 | * Keep 1 MB of memory free so that device drivers can allocate some pages in | 
|  | 44 | * their .suspend() routines without breaking the suspend to disk. | 
|  | 45 | */ | 
|  | 46 | #define SPARE_PAGES	((1024 * 1024) >> PAGE_SHIFT) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 47 |  | 
| Rafael J. Wysocki | 7777fab | 2007-07-19 01:47:29 -0700 | [diff] [blame] | 48 | /* kernel/power/disk.c */ | 
|  | 49 | extern int hibernation_snapshot(int platform_mode); | 
| Rafael J. Wysocki | a634cc1 | 2007-07-19 01:47:30 -0700 | [diff] [blame] | 50 | extern int hibernation_restore(int platform_mode); | 
| Rafael J. Wysocki | 7777fab | 2007-07-19 01:47:29 -0700 | [diff] [blame] | 51 | extern int hibernation_platform_enter(void); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 52 | #endif | 
| Stephen Hemminger | a6d7098 | 2006-12-06 20:34:35 -0800 | [diff] [blame] | 53 |  | 
| Vivek Goyal | 49c3df6 | 2007-05-02 19:27:07 +0200 | [diff] [blame] | 54 | extern int pfn_is_nosave(unsigned long); | 
|  | 55 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 56 | #define power_attr(_name) \ | 
| Kay Sievers | 386f275 | 2007-11-02 13:47:53 +0100 | [diff] [blame] | 57 | static struct kobj_attribute _name##_attr = {	\ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 58 | .attr	= {				\ | 
|  | 59 | .name = __stringify(_name),	\ | 
|  | 60 | .mode = 0644,			\ | 
|  | 61 | },					\ | 
|  | 62 | .show	= _name##_show,			\ | 
|  | 63 | .store	= _name##_store,		\ | 
|  | 64 | } | 
|  | 65 |  | 
| Rafael J. Wysocki | 853609b | 2006-02-01 03:05:07 -0800 | [diff] [blame] | 66 | /* Preferred image size in bytes (default 500 MB) */ | 
|  | 67 | extern unsigned long image_size; | 
| Rafael J. Wysocki | f577eb3 | 2006-03-23 02:59:59 -0800 | [diff] [blame] | 68 | extern int in_suspend; | 
| Rafael J. Wysocki | 61159a3 | 2006-03-23 03:00:00 -0800 | [diff] [blame] | 69 | extern dev_t swsusp_resume_device; | 
| Rafael J. Wysocki | 9a154d9 | 2006-12-06 20:34:12 -0800 | [diff] [blame] | 70 | extern sector_t swsusp_resume_block; | 
| Rafael J. Wysocki | f577eb3 | 2006-03-23 02:59:59 -0800 | [diff] [blame] | 71 |  | 
| Rafael J. Wysocki | 25761b6 | 2005-10-30 14:59:56 -0800 | [diff] [blame] | 72 | extern asmlinkage int swsusp_arch_suspend(void); | 
|  | 73 | extern asmlinkage int swsusp_arch_resume(void); | 
|  | 74 |  | 
| Rafael J. Wysocki | 74dfd66 | 2007-05-06 14:50:43 -0700 | [diff] [blame] | 75 | extern int create_basic_memory_bitmaps(void); | 
|  | 76 | extern void free_basic_memory_bitmaps(void); | 
| Rafael J. Wysocki | 72a97e0 | 2006-01-06 00:13:46 -0800 | [diff] [blame] | 77 | extern unsigned int count_data_pages(void); | 
| Rafael J. Wysocki | f577eb3 | 2006-03-23 02:59:59 -0800 | [diff] [blame] | 78 |  | 
| Rafael J. Wysocki | fb13a28 | 2006-09-25 23:32:46 -0700 | [diff] [blame] | 79 | /** | 
|  | 80 | *	Auxiliary structure used for reading the snapshot image data and | 
|  | 81 | *	metadata from and writing them to the list of page backup entries | 
|  | 82 | *	(PBEs) which is the main data structure of swsusp. | 
|  | 83 | * | 
|  | 84 | *	Using struct snapshot_handle we can transfer the image, including its | 
|  | 85 | *	metadata, as a continuous sequence of bytes with the help of | 
|  | 86 | *	snapshot_read_next() and snapshot_write_next(). | 
|  | 87 | * | 
|  | 88 | *	The code that writes the image to a storage or transfers it to | 
|  | 89 | *	the user land is required to use snapshot_read_next() for this | 
|  | 90 | *	purpose and it should not make any assumptions regarding the internal | 
|  | 91 | *	structure of the image.  Similarly, the code that reads the image from | 
|  | 92 | *	a storage or transfers it from the user land is required to use | 
|  | 93 | *	snapshot_write_next(). | 
|  | 94 | * | 
|  | 95 | *	This may allow us to change the internal structure of the image | 
|  | 96 | *	in the future with considerably less effort. | 
|  | 97 | */ | 
|  | 98 |  | 
| Rafael J. Wysocki | f577eb3 | 2006-03-23 02:59:59 -0800 | [diff] [blame] | 99 | struct snapshot_handle { | 
| Rafael J. Wysocki | fb13a28 | 2006-09-25 23:32:46 -0700 | [diff] [blame] | 100 | loff_t		offset;	/* number of the last byte ready for reading | 
|  | 101 | * or writing in the sequence | 
|  | 102 | */ | 
|  | 103 | unsigned int	cur;	/* number of the block of PAGE_SIZE bytes the | 
|  | 104 | * next operation will refer to (ie. current) | 
|  | 105 | */ | 
|  | 106 | unsigned int	cur_offset;	/* offset with respect to the current | 
|  | 107 | * block (for the next operation) | 
|  | 108 | */ | 
|  | 109 | unsigned int	prev;	/* number of the block of PAGE_SIZE bytes that | 
|  | 110 | * was the current one previously | 
|  | 111 | */ | 
| Rafael J. Wysocki | fb13a28 | 2006-09-25 23:32:46 -0700 | [diff] [blame] | 112 | void		*buffer;	/* address of the block to read from | 
|  | 113 | * or write to | 
|  | 114 | */ | 
|  | 115 | unsigned int	buf_offset;	/* location to read from or write to, | 
|  | 116 | * given as a displacement from 'buffer' | 
|  | 117 | */ | 
|  | 118 | int		sync_read;	/* Set to one to notify the caller of | 
|  | 119 | * snapshot_write_next() that it may | 
|  | 120 | * need to call wait_on_bio_chain() | 
|  | 121 | */ | 
| Rafael J. Wysocki | f577eb3 | 2006-03-23 02:59:59 -0800 | [diff] [blame] | 122 | }; | 
|  | 123 |  | 
| Rafael J. Wysocki | fb13a28 | 2006-09-25 23:32:46 -0700 | [diff] [blame] | 124 | /* This macro returns the address from/to which the caller of | 
|  | 125 | * snapshot_read_next()/snapshot_write_next() is allowed to | 
|  | 126 | * read/write data after the function returns | 
|  | 127 | */ | 
| Rafael J. Wysocki | f577eb3 | 2006-03-23 02:59:59 -0800 | [diff] [blame] | 128 | #define data_of(handle)	((handle).buffer + (handle).buf_offset) | 
|  | 129 |  | 
| Rafael J. Wysocki | b788db7 | 2006-09-25 23:32:54 -0700 | [diff] [blame] | 130 | extern unsigned int snapshot_additional_pages(struct zone *zone); | 
| Rafael J. Wysocki | af508b3 | 2007-10-26 00:59:31 +0200 | [diff] [blame] | 131 | extern unsigned long snapshot_get_image_size(void); | 
| Rafael J. Wysocki | f577eb3 | 2006-03-23 02:59:59 -0800 | [diff] [blame] | 132 | extern int snapshot_read_next(struct snapshot_handle *handle, size_t count); | 
|  | 133 | extern int snapshot_write_next(struct snapshot_handle *handle, size_t count); | 
| Rafael J. Wysocki | 8357376 | 2006-12-06 20:34:18 -0800 | [diff] [blame] | 134 | extern void snapshot_write_finalize(struct snapshot_handle *handle); | 
| Rafael J. Wysocki | b788db7 | 2006-09-25 23:32:54 -0700 | [diff] [blame] | 135 | extern int snapshot_image_loaded(struct snapshot_handle *handle); | 
| Rafael J. Wysocki | 61159a3 | 2006-03-23 03:00:00 -0800 | [diff] [blame] | 136 |  | 
| Rafael J. Wysocki | 0709db6 | 2007-05-06 14:50:45 -0700 | [diff] [blame] | 137 | /* If unset, the snapshot device cannot be open. */ | 
|  | 138 | extern atomic_t snapshot_device_available; | 
|  | 139 |  | 
| Rafael J. Wysocki | d1d241c | 2007-05-06 14:50:47 -0700 | [diff] [blame] | 140 | extern sector_t alloc_swapdev_block(int swap); | 
|  | 141 | extern void free_all_swap_pages(int swap); | 
|  | 142 | extern int swsusp_swap_in_use(void); | 
| Rafael J. Wysocki | 61159a3 | 2006-03-23 03:00:00 -0800 | [diff] [blame] | 143 |  | 
| Rafael J. Wysocki | a634cc1 | 2007-07-19 01:47:30 -0700 | [diff] [blame] | 144 | /* | 
|  | 145 | * Flags that can be passed from the hibernatig hernel to the "boot" kernel in | 
|  | 146 | * the image header. | 
|  | 147 | */ | 
|  | 148 | #define SF_PLATFORM_MODE	1 | 
|  | 149 |  | 
|  | 150 | /* kernel/power/disk.c */ | 
| Randy Dunlap | 74c7e2e | 2006-03-23 03:00:01 -0800 | [diff] [blame] | 151 | extern int swsusp_check(void); | 
| Rafael J. Wysocki | 61159a3 | 2006-03-23 03:00:00 -0800 | [diff] [blame] | 152 | extern int swsusp_shrink_memory(void); | 
| Randy Dunlap | 74c7e2e | 2006-03-23 03:00:01 -0800 | [diff] [blame] | 153 | extern void swsusp_free(void); | 
| Rafael J. Wysocki | a634cc1 | 2007-07-19 01:47:30 -0700 | [diff] [blame] | 154 | extern int swsusp_read(unsigned int *flags_p); | 
|  | 155 | extern int swsusp_write(unsigned int flags); | 
| Al Viro | c2dd0da | 2007-10-08 13:21:10 -0400 | [diff] [blame] | 156 | extern void swsusp_close(fmode_t); | 
| Rafael J. Wysocki | 0d3a9ab | 2006-12-06 20:34:32 -0800 | [diff] [blame] | 157 |  | 
|  | 158 | struct timeval; | 
| Rafael J. Wysocki | b10d911 | 2007-07-19 01:47:36 -0700 | [diff] [blame] | 159 | /* kernel/power/swsusp.c */ | 
| Rafael J. Wysocki | 0d3a9ab | 2006-12-06 20:34:32 -0800 | [diff] [blame] | 160 | extern void swsusp_show_speed(struct timeval *, struct timeval *, | 
|  | 161 | unsigned int, char *); | 
| Rafael J. Wysocki | b10d911 | 2007-07-19 01:47:36 -0700 | [diff] [blame] | 162 |  | 
| Rafael J. Wysocki | 296699d | 2007-07-29 23:27:18 +0200 | [diff] [blame] | 163 | #ifdef CONFIG_SUSPEND | 
| Rafael J. Wysocki | b10d911 | 2007-07-19 01:47:36 -0700 | [diff] [blame] | 164 | /* kernel/power/main.c */ | 
| Rafael J. Wysocki | 6c961df | 2007-07-19 01:47:38 -0700 | [diff] [blame] | 165 | extern int suspend_devices_and_enter(suspend_state_t state); | 
| Rafael J. Wysocki | 296699d | 2007-07-29 23:27:18 +0200 | [diff] [blame] | 166 | #else /* !CONFIG_SUSPEND */ | 
|  | 167 | static inline int suspend_devices_and_enter(suspend_state_t state) | 
|  | 168 | { | 
|  | 169 | return -ENOSYS; | 
|  | 170 | } | 
|  | 171 | #endif /* !CONFIG_SUSPEND */ | 
|  | 172 |  | 
| Alan Stern | 8252575 | 2007-11-19 23:49:18 +0100 | [diff] [blame] | 173 | #ifdef CONFIG_PM_SLEEP | 
|  | 174 | /* kernel/power/main.c */ | 
|  | 175 | extern int pm_notifier_call_chain(unsigned long val); | 
|  | 176 | #endif | 
| Adrian Bunk | 2f8ed1c | 2007-11-19 23:36:20 +0100 | [diff] [blame] | 177 |  | 
|  | 178 | #ifdef CONFIG_HIGHMEM | 
|  | 179 | unsigned int count_highmem_pages(void); | 
|  | 180 | int restore_highmem(void); | 
|  | 181 | #else | 
|  | 182 | static inline unsigned int count_highmem_pages(void) { return 0; } | 
|  | 183 | static inline int restore_highmem(void) { return 0; } | 
|  | 184 | #endif | 
| Rafael J. Wysocki | 0e7d56e | 2007-11-19 23:41:19 +0100 | [diff] [blame] | 185 |  | 
|  | 186 | /* | 
|  | 187 | * Suspend test levels | 
|  | 188 | */ | 
|  | 189 | enum { | 
|  | 190 | /* keep first */ | 
|  | 191 | TEST_NONE, | 
|  | 192 | TEST_CORE, | 
|  | 193 | TEST_CPUS, | 
|  | 194 | TEST_PLATFORM, | 
|  | 195 | TEST_DEVICES, | 
|  | 196 | TEST_FREEZER, | 
|  | 197 | /* keep last */ | 
|  | 198 | __TEST_AFTER_LAST | 
|  | 199 | }; | 
|  | 200 |  | 
|  | 201 | #define TEST_FIRST	TEST_NONE | 
|  | 202 | #define TEST_MAX	(__TEST_AFTER_LAST - 1) | 
| Rafael J. Wysocki | 4cc7977 | 2007-11-19 23:42:31 +0100 | [diff] [blame] | 203 |  | 
|  | 204 | extern int pm_test_level; | 
| Johannes Berg | b28f508 | 2008-01-15 23:17:00 -0500 | [diff] [blame] | 205 |  | 
|  | 206 | #ifdef CONFIG_SUSPEND_FREEZER | 
|  | 207 | static inline int suspend_freeze_processes(void) | 
|  | 208 | { | 
|  | 209 | return freeze_processes(); | 
|  | 210 | } | 
|  | 211 |  | 
|  | 212 | static inline void suspend_thaw_processes(void) | 
|  | 213 | { | 
|  | 214 | thaw_processes(); | 
|  | 215 | } | 
|  | 216 | #else | 
|  | 217 | static inline int suspend_freeze_processes(void) | 
|  | 218 | { | 
|  | 219 | return 0; | 
|  | 220 | } | 
|  | 221 |  | 
|  | 222 | static inline void suspend_thaw_processes(void) | 
|  | 223 | { | 
|  | 224 | } | 
|  | 225 | #endif |