Hibernation: Introduce begin() and end() callbacks

Introduce global hibernation callback .end() and rename global
hibernation callback .start() to .begin(), in analogy with the
recent modifications of the global suspend callbacks.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Len Brown <len.brown@intel.com>

authored by Rafael J. Wysocki and committed by Len Brown caea99ef 60417f59

+45 -16
+12 -2
drivers/acpi/sleep/main.c
··· 281 #endif /* CONFIG_SUSPEND */ 282 283 #ifdef CONFIG_HIBERNATION 284 - static int acpi_hibernation_start(void) 285 { 286 acpi_target_sleep_state = ACPI_STATE_S4; 287 return 0; ··· 341 acpi_target_sleep_state = ACPI_STATE_S0; 342 } 343 344 static int acpi_hibernation_pre_restore(void) 345 { 346 acpi_status status; ··· 365 } 366 367 static struct platform_hibernation_ops acpi_hibernation_ops = { 368 - .start = acpi_hibernation_start, 369 .pre_snapshot = acpi_hibernation_prepare, 370 .finish = acpi_hibernation_finish, 371 .prepare = acpi_hibernation_prepare,
··· 281 #endif /* CONFIG_SUSPEND */ 282 283 #ifdef CONFIG_HIBERNATION 284 + static int acpi_hibernation_begin(void) 285 { 286 acpi_target_sleep_state = ACPI_STATE_S4; 287 return 0; ··· 341 acpi_target_sleep_state = ACPI_STATE_S0; 342 } 343 344 + static void acpi_hibernation_end(void) 345 + { 346 + /* 347 + * This is necessary in case acpi_hibernation_finish() is not called 348 + * during a failing transition to the sleep state. 349 + */ 350 + acpi_target_sleep_state = ACPI_STATE_S0; 351 + } 352 + 353 static int acpi_hibernation_pre_restore(void) 354 { 355 acpi_status status; ··· 356 } 357 358 static struct platform_hibernation_ops acpi_hibernation_ops = { 359 + .begin = acpi_hibernation_begin, 360 + .end = acpi_hibernation_end, 361 .pre_snapshot = acpi_hibernation_prepare, 362 .finish = acpi_hibernation_finish, 363 .prepare = acpi_hibernation_prepare,
+9 -5
include/linux/suspend.h
··· 136 /** 137 * struct platform_hibernation_ops - hibernation platform support 138 * 139 - * The methods in this structure allow a platform to override the default 140 - * mechanism of shutting down the machine during a hibernation transition. 141 * 142 - * All three methods must be assigned. 143 * 144 - * @start: Tell the platform driver that we're starting hibernation. 145 * Called right after shrinking memory and before freezing devices. 146 * 147 * @pre_snapshot: Prepare the platform for creating the hibernation image. 148 * Called right after devices have been frozen and before the nonboot ··· 181 * thawing devices (runs with IRQs on). 182 */ 183 struct platform_hibernation_ops { 184 - int (*start)(void); 185 int (*pre_snapshot)(void); 186 void (*finish)(void); 187 int (*prepare)(void);
··· 136 /** 137 * struct platform_hibernation_ops - hibernation platform support 138 * 139 + * The methods in this structure allow a platform to carry out special 140 + * operations required by it during a hibernation transition. 141 * 142 + * All the methods below must be implemented. 143 * 144 + * @begin: Tell the platform driver that we're starting hibernation. 145 * Called right after shrinking memory and before freezing devices. 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 * 150 * @pre_snapshot: Prepare the platform for creating the hibernation image. 151 * Called right after devices have been frozen and before the nonboot ··· 178 * thawing devices (runs with IRQs on). 179 */ 180 struct platform_hibernation_ops { 181 + int (*begin)(void); 182 + void (*end)(void); 183 int (*pre_snapshot)(void); 184 void (*finish)(void); 185 int (*prepare)(void);
+24 -9
kernel/power/disk.c
··· 54 55 void hibernation_set_ops(struct platform_hibernation_ops *ops) 56 { 57 - if (ops && !(ops->start && ops->pre_snapshot && ops->finish 58 - && ops->prepare && ops->enter && ops->pre_restore 59 && ops->restore_cleanup)) { 60 WARN_ON(1); 61 return; ··· 100 #endif /* !CONFIG_PM_DEBUG */ 101 102 /** 103 - * platform_start - tell the platform driver that we're starting 104 * hibernation 105 */ 106 107 - static int platform_start(int platform_mode) 108 { 109 return (platform_mode && hibernation_ops) ? 110 - hibernation_ops->start() : 0; 111 } 112 113 /** ··· 248 if (error) 249 return error; 250 251 - error = platform_start(platform_mode); 252 if (error) 253 - return error; 254 255 suspend_console(); 256 error = device_suspend(PMSG_FREEZE); ··· 283 device_resume(); 284 Resume_console: 285 resume_console(); 286 return error; 287 } 288 ··· 386 * hibernation_ops->finish() before saving the image, so we should let 387 * the firmware know that we're going to enter the sleep state after all 388 */ 389 - error = hibernation_ops->start(); 390 if (error) 391 - return error; 392 393 suspend_console(); 394 error = device_suspend(PMSG_SUSPEND); ··· 422 device_resume(); 423 Resume_console: 424 resume_console(); 425 return error; 426 } 427
··· 54 55 void hibernation_set_ops(struct platform_hibernation_ops *ops) 56 { 57 + if (ops && !(ops->begin && ops->end && ops->pre_snapshot 58 + && ops->prepare && ops->finish && ops->enter && ops->pre_restore 59 && ops->restore_cleanup)) { 60 WARN_ON(1); 61 return; ··· 100 #endif /* !CONFIG_PM_DEBUG */ 101 102 /** 103 + * platform_begin - tell the platform driver that we're starting 104 * hibernation 105 */ 106 107 + static int platform_begin(int platform_mode) 108 { 109 return (platform_mode && hibernation_ops) ? 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 + 118 + static void platform_end(int platform_mode) 119 + { 120 + if (platform_mode && hibernation_ops) 121 + hibernation_ops->end(); 122 } 123 124 /** ··· 237 if (error) 238 return error; 239 240 + error = platform_begin(platform_mode); 241 if (error) 242 + goto Close; 243 244 suspend_console(); 245 error = device_suspend(PMSG_FREEZE); ··· 272 device_resume(); 273 Resume_console: 274 resume_console(); 275 + Close: 276 + platform_end(platform_mode); 277 return error; 278 } 279 ··· 373 * hibernation_ops->finish() before saving the image, so we should let 374 * the firmware know that we're going to enter the sleep state after all 375 */ 376 + error = hibernation_ops->begin(); 377 if (error) 378 + goto Close; 379 380 suspend_console(); 381 error = device_suspend(PMSG_SUSPEND); ··· 409 device_resume(); 410 Resume_console: 411 resume_console(); 412 + Close: 413 + hibernation_ops->end(); 414 return error; 415 } 416