Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Hibernation: Rework platform support ioctls (rev. 2)

Modify the hibernation userland interface by adding two new ioctls to it,
SNAPSHOT_PLATFORM_SUPPORT and SNAPSHOT_POWER_OFF, that can be used,
respectively, to switch the hibernation platform support on/off and to make the
kernel transition the system to the hibernation state (eg. ACPI S4) using the
platform (eg. ACPI) driver.

These ioctls are intended to replace the misdesigned SNAPSHOT_PMOPS ioctl,
which from now is regarded as obsolete and will be removed in the future.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Len Brown <len.brown@intel.com>

authored by

Rafael J. Wysocki and committed by
Len Brown
eb57c1cf af508b34

+38 -34
+6 -18
Documentation/power/userland-swsusp.txt
··· 85 85 recommended to always use this call, because the code to set the resume 86 86 partition may be removed from future kernels 87 87 88 + SNAPSHOT_PLATFORM_SUPPORT - enable/disable the hibernation platform support, 89 + depending on the argument value (enable, if the argument is nonzero) 90 + 91 + SNAPSHOT_POWER_OFF - make the kernel transition the system to the hibernation 92 + state (eg. ACPI S4) using the platform (eg. ACPI) driver 93 + 88 94 SNAPSHOT_S2RAM - suspend to RAM; using this call causes the kernel to 89 95 immediately enter the suspend-to-RAM state, so this call must always 90 96 be preceded by the SNAPSHOT_FREEZE call and it is also necessary ··· 100 94 to disk, and then the system is suspended to RAM (this makes it possible 101 95 to resume the system from RAM if there's enough battery power or restore 102 96 its state on the basis of the saved suspend image otherwise) 103 - 104 - SNAPSHOT_PMOPS - enable the usage of the hibernation_ops->prepare, 105 - hibernate_ops->enter and hibernation_ops->finish methods (the in-kernel 106 - swsusp knows these as the "platform method") which are needed on many 107 - machines to (among others) speed up the resume by letting the BIOS skip 108 - some steps or to let the system recognise the correct state of the 109 - hardware after the resume (in particular on many machines this ensures 110 - that unplugged AC adapters get correctly detected and that kacpid does 111 - not run wild after the resume). The last ioctl() argument can take one 112 - of the three values, defined in kernel/power/power.h: 113 - PMOPS_PREPARE - make the kernel carry out the 114 - hibernation_ops->prepare() operation 115 - PMOPS_ENTER - make the kernel power off the system by calling 116 - hibernation_ops->enter() 117 - PMOPS_FINISH - make the kernel carry out the 118 - hibernation_ops->finish() operation 119 - Note that the actual constants are misnamed because they surface 120 - internal kernel implementation details that have changed. 121 97 122 98 The device's read() operation can be used to transfer the snapshot image from 123 99 the kernel. It has the following limitations:
+3 -6
kernel/power/power.h
··· 156 156 #define SNAPSHOT_FREE_SWAP_PAGES _IO(SNAPSHOT_IOC_MAGIC, 9) 157 157 #define SNAPSHOT_SET_SWAP_FILE _IOW(SNAPSHOT_IOC_MAGIC, 10, unsigned int) 158 158 #define SNAPSHOT_S2RAM _IO(SNAPSHOT_IOC_MAGIC, 11) 159 - #define SNAPSHOT_PMOPS _IOW(SNAPSHOT_IOC_MAGIC, 12, unsigned int) 160 159 #define SNAPSHOT_SET_SWAP_AREA _IOW(SNAPSHOT_IOC_MAGIC, 13, \ 161 160 struct resume_swap_area) 162 161 #define SNAPSHOT_GET_IMAGE_SIZE _IOR(SNAPSHOT_IOC_MAGIC, 14, loff_t) 163 - #define SNAPSHOT_IOC_MAXNR 14 164 - 165 - #define PMOPS_PREPARE 1 166 - #define PMOPS_ENTER 2 167 - #define PMOPS_FINISH 3 162 + #define SNAPSHOT_PLATFORM_SUPPORT _IO(SNAPSHOT_IOC_MAGIC, 15) 163 + #define SNAPSHOT_POWER_OFF _IO(SNAPSHOT_IOC_MAGIC, 16) 164 + #define SNAPSHOT_IOC_MAXNR 16 168 165 169 166 /* If unset, the snapshot device cannot be open. */ 170 167 extern atomic_t snapshot_device_available;
+29 -10
kernel/power/user.c
··· 28 28 29 29 #include "power.h" 30 30 31 + /* 32 + * NOTE: The SNAPSHOT_PMOPS ioctl is obsolete and will be removed in the 33 + * future. It is only preserved here for compatibility with existing userland 34 + * utilities. 35 + */ 36 + #define SNAPSHOT_PMOPS _IOW(SNAPSHOT_IOC_MAGIC, 12, unsigned int) 37 + 38 + #define PMOPS_PREPARE 1 39 + #define PMOPS_ENTER 2 40 + #define PMOPS_FINISH 3 41 + 42 + 31 43 #define SNAPSHOT_MINOR 231 32 44 33 45 static struct snapshot_data { ··· 48 36 int mode; 49 37 char frozen; 50 38 char ready; 51 - char platform_suspend; 39 + char platform_support; 52 40 } snapshot_state; 53 41 54 42 atomic_t snapshot_device_available = ATOMIC_INIT(1); ··· 82 70 } 83 71 data->frozen = 0; 84 72 data->ready = 0; 85 - data->platform_suspend = 0; 73 + data->platform_support = 0; 86 74 87 75 return 0; 88 76 } ··· 195 183 error = -EPERM; 196 184 break; 197 185 } 198 - error = hibernation_snapshot(data->platform_suspend); 186 + error = hibernation_snapshot(data->platform_support); 199 187 if (!error) 200 188 error = put_user(in_suspend, (unsigned int __user *)arg); 201 189 if (!error) ··· 209 197 error = -EPERM; 210 198 break; 211 199 } 212 - error = hibernation_restore(data->platform_suspend); 200 + error = hibernation_restore(data->platform_support); 213 201 break; 214 202 215 203 case SNAPSHOT_FREE: ··· 297 285 mutex_unlock(&pm_mutex); 298 286 break; 299 287 300 - case SNAPSHOT_PMOPS: 288 + case SNAPSHOT_PLATFORM_SUPPORT: 289 + data->platform_support = !!arg; 290 + break; 291 + 292 + case SNAPSHOT_POWER_OFF: 293 + if (data->platform_support) 294 + error = hibernation_platform_enter(); 295 + break; 296 + 297 + case SNAPSHOT_PMOPS: /* This ioctl is deprecated */ 301 298 error = -EINVAL; 302 299 303 300 switch (arg) { 304 301 305 302 case PMOPS_PREPARE: 306 - data->platform_suspend = 1; 303 + data->platform_support = 1; 307 304 error = 0; 308 305 break; 309 306 310 307 case PMOPS_ENTER: 311 - if (data->platform_suspend) 308 + if (data->platform_support) 312 309 error = hibernation_platform_enter(); 313 - 314 310 break; 315 311 316 312 case PMOPS_FINISH: 317 - if (data->platform_suspend) 313 + if (data->platform_support) 318 314 error = 0; 319 - 320 315 break; 321 316 322 317 default: