| .. | .. |
|---|
| 8 | 8 | #include <linux/pm.h> |
|---|
| 9 | 9 | #include <linux/mm.h> |
|---|
| 10 | 10 | #include <linux/freezer.h> |
|---|
| 11 | +#include <linux/android_kabi.h> |
|---|
| 11 | 12 | #include <asm/errno.h> |
|---|
| 12 | 13 | |
|---|
| 13 | 14 | #ifdef CONFIG_VT |
|---|
| .. | .. |
|---|
| 37 | 38 | #define PM_SUSPEND_TO_IDLE ((__force suspend_state_t) 1) |
|---|
| 38 | 39 | #define PM_SUSPEND_STANDBY ((__force suspend_state_t) 2) |
|---|
| 39 | 40 | #define PM_SUSPEND_MEM ((__force suspend_state_t) 3) |
|---|
| 40 | | -#define PM_SUSPEND_MEM_LITE ((__force suspend_state_t) 4) |
|---|
| 41 | | -#define PM_SUSPEND_MEM_ULTRA ((__force suspend_state_t) 5) |
|---|
| 42 | 41 | #define PM_SUSPEND_MIN PM_SUSPEND_TO_IDLE |
|---|
| 43 | | -#define PM_SUSPEND_MAX ((__force suspend_state_t) 6) |
|---|
| 42 | +#define PM_SUSPEND_MAX ((__force suspend_state_t) 4) |
|---|
| 44 | 43 | |
|---|
| 45 | 44 | enum suspend_stat_step { |
|---|
| 46 | 45 | SUSPEND_FREEZE = 1, |
|---|
| .. | .. |
|---|
| 187 | 186 | bool (*suspend_again)(void); |
|---|
| 188 | 187 | void (*end)(void); |
|---|
| 189 | 188 | void (*recover)(void); |
|---|
| 189 | + |
|---|
| 190 | + ANDROID_KABI_RESERVE(1); |
|---|
| 190 | 191 | }; |
|---|
| 191 | 192 | |
|---|
| 192 | 193 | struct platform_s2idle_ops { |
|---|
| 193 | 194 | int (*begin)(void); |
|---|
| 194 | 195 | int (*prepare)(void); |
|---|
| 195 | | - void (*wake)(void); |
|---|
| 196 | | - void (*sync)(void); |
|---|
| 196 | + int (*prepare_late)(void); |
|---|
| 197 | + bool (*wake)(void); |
|---|
| 198 | + void (*restore_early)(void); |
|---|
| 197 | 199 | void (*restore)(void); |
|---|
| 198 | 200 | void (*end)(void); |
|---|
| 199 | | -}; |
|---|
| 200 | 201 | |
|---|
| 201 | | -#if defined(CONFIG_SUSPEND) || defined(CONFIG_HIBERNATION) |
|---|
| 202 | | -extern bool pm_in_action; |
|---|
| 203 | | -#else |
|---|
| 204 | | -# define pm_in_action false |
|---|
| 205 | | -#endif |
|---|
| 202 | + ANDROID_KABI_RESERVE(1); |
|---|
| 203 | +}; |
|---|
| 206 | 204 | |
|---|
| 207 | 205 | #ifdef CONFIG_SUSPEND |
|---|
| 208 | 206 | extern suspend_state_t mem_sleep_current; |
|---|
| .. | .. |
|---|
| 217 | 215 | |
|---|
| 218 | 216 | extern unsigned int pm_suspend_global_flags; |
|---|
| 219 | 217 | |
|---|
| 220 | | -#define PM_SUSPEND_FLAG_FW_SUSPEND (1 << 0) |
|---|
| 221 | | -#define PM_SUSPEND_FLAG_FW_RESUME (1 << 1) |
|---|
| 218 | +#define PM_SUSPEND_FLAG_FW_SUSPEND BIT(0) |
|---|
| 219 | +#define PM_SUSPEND_FLAG_FW_RESUME BIT(1) |
|---|
| 220 | +#define PM_SUSPEND_FLAG_NO_PLATFORM BIT(2) |
|---|
| 222 | 221 | |
|---|
| 223 | 222 | static inline void pm_suspend_clear_flags(void) |
|---|
| 224 | 223 | { |
|---|
| .. | .. |
|---|
| 235 | 234 | pm_suspend_global_flags |= PM_SUSPEND_FLAG_FW_RESUME; |
|---|
| 236 | 235 | } |
|---|
| 237 | 236 | |
|---|
| 237 | +static inline void pm_set_suspend_no_platform(void) |
|---|
| 238 | +{ |
|---|
| 239 | + pm_suspend_global_flags |= PM_SUSPEND_FLAG_NO_PLATFORM; |
|---|
| 240 | +} |
|---|
| 241 | + |
|---|
| 242 | +/** |
|---|
| 243 | + * pm_suspend_via_firmware - Check if platform firmware will suspend the system. |
|---|
| 244 | + * |
|---|
| 245 | + * To be called during system-wide power management transitions to sleep states |
|---|
| 246 | + * or during the subsequent system-wide transitions back to the working state. |
|---|
| 247 | + * |
|---|
| 248 | + * Return 'true' if the platform firmware is going to be invoked at the end of |
|---|
| 249 | + * the system-wide power management transition (to a sleep state) in progress in |
|---|
| 250 | + * order to complete it, or if the platform firmware has been invoked in order |
|---|
| 251 | + * to complete the last (or preceding) transition of the system to a sleep |
|---|
| 252 | + * state. |
|---|
| 253 | + * |
|---|
| 254 | + * This matters if the caller needs or wants to carry out some special actions |
|---|
| 255 | + * depending on whether or not control will be passed to the platform firmware |
|---|
| 256 | + * subsequently (for example, the device may need to be reset before letting the |
|---|
| 257 | + * platform firmware manipulate it, which is not necessary when the platform |
|---|
| 258 | + * firmware is not going to be invoked) or when such special actions may have |
|---|
| 259 | + * been carried out during the preceding transition of the system to a sleep |
|---|
| 260 | + * state (as they may need to be taken into account). |
|---|
| 261 | + */ |
|---|
| 238 | 262 | static inline bool pm_suspend_via_firmware(void) |
|---|
| 239 | 263 | { |
|---|
| 240 | 264 | return !!(pm_suspend_global_flags & PM_SUSPEND_FLAG_FW_SUSPEND); |
|---|
| 241 | 265 | } |
|---|
| 242 | 266 | |
|---|
| 267 | +/** |
|---|
| 268 | + * pm_resume_via_firmware - Check if platform firmware has woken up the system. |
|---|
| 269 | + * |
|---|
| 270 | + * To be called during system-wide power management transitions from sleep |
|---|
| 271 | + * states. |
|---|
| 272 | + * |
|---|
| 273 | + * Return 'true' if the platform firmware has passed control to the kernel at |
|---|
| 274 | + * the beginning of the system-wide power management transition in progress, so |
|---|
| 275 | + * the event that woke up the system from sleep has been handled by the platform |
|---|
| 276 | + * firmware. |
|---|
| 277 | + */ |
|---|
| 243 | 278 | static inline bool pm_resume_via_firmware(void) |
|---|
| 244 | 279 | { |
|---|
| 245 | 280 | return !!(pm_suspend_global_flags & PM_SUSPEND_FLAG_FW_RESUME); |
|---|
| 281 | +} |
|---|
| 282 | + |
|---|
| 283 | +/** |
|---|
| 284 | + * pm_suspend_no_platform - Check if platform may change device power states. |
|---|
| 285 | + * |
|---|
| 286 | + * To be called during system-wide power management transitions to sleep states |
|---|
| 287 | + * or during the subsequent system-wide transitions back to the working state. |
|---|
| 288 | + * |
|---|
| 289 | + * Return 'true' if the power states of devices remain under full control of the |
|---|
| 290 | + * kernel throughout the system-wide suspend and resume cycle in progress (that |
|---|
| 291 | + * is, if a device is put into a certain power state during suspend, it can be |
|---|
| 292 | + * expected to remain in that state during resume). |
|---|
| 293 | + */ |
|---|
| 294 | +static inline bool pm_suspend_no_platform(void) |
|---|
| 295 | +{ |
|---|
| 296 | + return !!(pm_suspend_global_flags & PM_SUSPEND_FLAG_NO_PLATFORM); |
|---|
| 246 | 297 | } |
|---|
| 247 | 298 | |
|---|
| 248 | 299 | /* Suspend-to-idle state machnine. */ |
|---|
| .. | .. |
|---|
| 259 | 310 | return unlikely(s2idle_state == S2IDLE_STATE_ENTER); |
|---|
| 260 | 311 | } |
|---|
| 261 | 312 | |
|---|
| 262 | | -extern bool pm_suspend_via_s2idle(void); |
|---|
| 313 | +extern bool pm_suspend_default_s2idle(void); |
|---|
| 263 | 314 | extern void __init pm_states_init(void); |
|---|
| 264 | 315 | extern void s2idle_set_ops(const struct platform_s2idle_ops *ops); |
|---|
| 265 | 316 | extern void s2idle_wake(void); |
|---|
| .. | .. |
|---|
| 283 | 334 | extern void arch_suspend_enable_irqs(void); |
|---|
| 284 | 335 | |
|---|
| 285 | 336 | extern int pm_suspend(suspend_state_t state); |
|---|
| 337 | +extern bool sync_on_suspend_enabled; |
|---|
| 286 | 338 | #else /* !CONFIG_SUSPEND */ |
|---|
| 287 | 339 | #define suspend_valid_only_mem NULL |
|---|
| 288 | 340 | |
|---|
| .. | .. |
|---|
| 291 | 343 | static inline void pm_set_resume_via_firmware(void) {} |
|---|
| 292 | 344 | static inline bool pm_suspend_via_firmware(void) { return false; } |
|---|
| 293 | 345 | static inline bool pm_resume_via_firmware(void) { return false; } |
|---|
| 294 | | -static inline bool pm_suspend_via_s2idle(void) { return false; } |
|---|
| 346 | +static inline bool pm_suspend_no_platform(void) { return false; } |
|---|
| 347 | +static inline bool pm_suspend_default_s2idle(void) { return false; } |
|---|
| 295 | 348 | |
|---|
| 296 | 349 | static inline void suspend_set_ops(const struct platform_suspend_ops *ops) {} |
|---|
| 297 | 350 | static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; } |
|---|
| 351 | +static inline bool sync_on_suspend_enabled(void) { return true; } |
|---|
| 298 | 352 | static inline bool idle_should_enter_s2idle(void) { return false; } |
|---|
| 299 | 353 | static inline void __init pm_states_init(void) {} |
|---|
| 300 | 354 | static inline void s2idle_set_ops(const struct platform_s2idle_ops *ops) {} |
|---|
| .. | .. |
|---|
| 367 | 421 | * platforms which require special recovery actions in that situation. |
|---|
| 368 | 422 | */ |
|---|
| 369 | 423 | struct platform_hibernation_ops { |
|---|
| 370 | | - int (*begin)(void); |
|---|
| 424 | + int (*begin)(pm_message_t stage); |
|---|
| 371 | 425 | void (*end)(void); |
|---|
| 372 | 426 | int (*pre_snapshot)(void); |
|---|
| 373 | 427 | void (*finish)(void); |
|---|
| .. | .. |
|---|
| 377 | 431 | int (*pre_restore)(void); |
|---|
| 378 | 432 | void (*restore_cleanup)(void); |
|---|
| 379 | 433 | void (*recover)(void); |
|---|
| 434 | + |
|---|
| 435 | + ANDROID_KABI_RESERVE(1); |
|---|
| 380 | 436 | }; |
|---|
| 381 | 437 | |
|---|
| 382 | 438 | #ifdef CONFIG_HIBERNATION |
|---|
| 383 | 439 | /* kernel/power/snapshot.c */ |
|---|
| 384 | | -extern void __register_nosave_region(unsigned long b, unsigned long e, int km); |
|---|
| 385 | | -static inline void __init register_nosave_region(unsigned long b, unsigned long e) |
|---|
| 386 | | -{ |
|---|
| 387 | | - __register_nosave_region(b, e, 0); |
|---|
| 388 | | -} |
|---|
| 389 | | -static inline void __init register_nosave_region_late(unsigned long b, unsigned long e) |
|---|
| 390 | | -{ |
|---|
| 391 | | - __register_nosave_region(b, e, 1); |
|---|
| 392 | | -} |
|---|
| 440 | +extern void register_nosave_region(unsigned long b, unsigned long e); |
|---|
| 393 | 441 | extern int swsusp_page_is_forbidden(struct page *); |
|---|
| 394 | 442 | extern void swsusp_set_page_free(struct page *); |
|---|
| 395 | 443 | extern void swsusp_unset_page_free(struct page *); |
|---|
| .. | .. |
|---|
| 403 | 451 | extern bool hibernation_available(void); |
|---|
| 404 | 452 | asmlinkage int swsusp_save(void); |
|---|
| 405 | 453 | extern struct pbe *restore_pblist; |
|---|
| 454 | +int pfn_is_nosave(unsigned long pfn); |
|---|
| 455 | + |
|---|
| 456 | +int hibernate_quiet_exec(int (*func)(void *data), void *data); |
|---|
| 406 | 457 | #else /* CONFIG_HIBERNATION */ |
|---|
| 407 | 458 | static inline void register_nosave_region(unsigned long b, unsigned long e) {} |
|---|
| 408 | | -static inline void register_nosave_region_late(unsigned long b, unsigned long e) {} |
|---|
| 409 | 459 | static inline int swsusp_page_is_forbidden(struct page *p) { return 0; } |
|---|
| 410 | 460 | static inline void swsusp_set_page_free(struct page *p) {} |
|---|
| 411 | 461 | static inline void swsusp_unset_page_free(struct page *p) {} |
|---|
| .. | .. |
|---|
| 414 | 464 | static inline int hibernate(void) { return -ENOSYS; } |
|---|
| 415 | 465 | static inline bool system_entering_hibernation(void) { return false; } |
|---|
| 416 | 466 | static inline bool hibernation_available(void) { return false; } |
|---|
| 467 | + |
|---|
| 468 | +static inline int hibernate_quiet_exec(int (*func)(void *data), void *data) { |
|---|
| 469 | + return -ENOTSUPP; |
|---|
| 470 | +} |
|---|
| 417 | 471 | #endif /* CONFIG_HIBERNATION */ |
|---|
| 472 | + |
|---|
| 473 | +#ifdef CONFIG_HIBERNATION_SNAPSHOT_DEV |
|---|
| 474 | +int is_hibernate_resume_dev(dev_t dev); |
|---|
| 475 | +#else |
|---|
| 476 | +static inline int is_hibernate_resume_dev(dev_t dev) { return 0; } |
|---|
| 477 | +#endif |
|---|
| 418 | 478 | |
|---|
| 419 | 479 | /* Hibernation and suspend events */ |
|---|
| 420 | 480 | #define PM_HIBERNATION_PREPARE 0x0001 /* Going to hibernate */ |
|---|
| .. | .. |
|---|
| 433 | 493 | /* kernel/power/main.c */ |
|---|
| 434 | 494 | extern int register_pm_notifier(struct notifier_block *nb); |
|---|
| 435 | 495 | extern int unregister_pm_notifier(struct notifier_block *nb); |
|---|
| 496 | +extern void ksys_sync_helper(void); |
|---|
| 436 | 497 | |
|---|
| 437 | 498 | #define pm_notifier(fn, pri) { \ |
|---|
| 438 | 499 | static struct notifier_block fn##_nb = \ |
|---|
| .. | .. |
|---|
| 442 | 503 | |
|---|
| 443 | 504 | /* drivers/base/power/wakeup.c */ |
|---|
| 444 | 505 | extern bool events_check_enabled; |
|---|
| 445 | | -extern unsigned int pm_wakeup_irq; |
|---|
| 446 | 506 | extern suspend_state_t pm_suspend_target_state; |
|---|
| 447 | 507 | |
|---|
| 448 | 508 | extern bool pm_wakeup_pending(void); |
|---|
| 449 | 509 | extern void pm_system_wakeup(void); |
|---|
| 450 | 510 | extern void pm_system_cancel_wakeup(void); |
|---|
| 451 | | -extern void pm_wakeup_clear(bool reset); |
|---|
| 511 | +extern void pm_wakeup_clear(unsigned int irq_number); |
|---|
| 452 | 512 | extern void pm_system_irq_wakeup(unsigned int irq_number); |
|---|
| 513 | +extern unsigned int pm_wakeup_irq(void); |
|---|
| 453 | 514 | extern bool pm_get_wakeup_count(unsigned int *count, bool block); |
|---|
| 454 | 515 | extern bool pm_save_wakeup_count(unsigned int count); |
|---|
| 455 | 516 | extern void pm_wakep_autosleep_enabled(bool set); |
|---|
| .. | .. |
|---|
| 470 | 531 | { |
|---|
| 471 | 532 | return 0; |
|---|
| 472 | 533 | } |
|---|
| 534 | + |
|---|
| 535 | +static inline void ksys_sync_helper(void) {} |
|---|
| 473 | 536 | |
|---|
| 474 | 537 | #define pm_notifier(fn, pri) do { (void)(fn); } while (0) |
|---|
| 475 | 538 | |
|---|
| .. | .. |
|---|
| 513 | 576 | static inline void queue_up_suspend_work(void) {} |
|---|
| 514 | 577 | |
|---|
| 515 | 578 | #endif /* !CONFIG_PM_AUTOSLEEP */ |
|---|
| 516 | | - |
|---|
| 517 | | -#ifdef CONFIG_ARCH_SAVE_PAGE_KEYS |
|---|
| 518 | | -/* |
|---|
| 519 | | - * The ARCH_SAVE_PAGE_KEYS functions can be used by an architecture |
|---|
| 520 | | - * to save/restore additional information to/from the array of page |
|---|
| 521 | | - * frame numbers in the hibernation image. For s390 this is used to |
|---|
| 522 | | - * save and restore the storage key for each page that is included |
|---|
| 523 | | - * in the hibernation image. |
|---|
| 524 | | - */ |
|---|
| 525 | | -unsigned long page_key_additional_pages(unsigned long pages); |
|---|
| 526 | | -int page_key_alloc(unsigned long pages); |
|---|
| 527 | | -void page_key_free(void); |
|---|
| 528 | | -void page_key_read(unsigned long *pfn); |
|---|
| 529 | | -void page_key_memorize(unsigned long *pfn); |
|---|
| 530 | | -void page_key_write(void *address); |
|---|
| 531 | | - |
|---|
| 532 | | -#else /* !CONFIG_ARCH_SAVE_PAGE_KEYS */ |
|---|
| 533 | | - |
|---|
| 534 | | -static inline unsigned long page_key_additional_pages(unsigned long pages) |
|---|
| 535 | | -{ |
|---|
| 536 | | - return 0; |
|---|
| 537 | | -} |
|---|
| 538 | | - |
|---|
| 539 | | -static inline int page_key_alloc(unsigned long pages) |
|---|
| 540 | | -{ |
|---|
| 541 | | - return 0; |
|---|
| 542 | | -} |
|---|
| 543 | | - |
|---|
| 544 | | -static inline void page_key_free(void) {} |
|---|
| 545 | | -static inline void page_key_read(unsigned long *pfn) {} |
|---|
| 546 | | -static inline void page_key_memorize(unsigned long *pfn) {} |
|---|
| 547 | | -static inline void page_key_write(void *address) {} |
|---|
| 548 | | - |
|---|
| 549 | | -#endif /* !CONFIG_ARCH_SAVE_PAGE_KEYS */ |
|---|
| 550 | 579 | |
|---|
| 551 | 580 | #endif /* _LINUX_SUSPEND_H */ |
|---|