diff options
| author | Rafael J. Wysocki <rjw@sisk.pl> | 2007-07-19 04:47:36 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-19 13:04:42 -0400 |
| commit | b10d911749d37dccfa5873d2088aea3f074b9e45 (patch) | |
| tree | 56bd0ccb2861d7ae562d4e48a737727628358b42 /include/linux | |
| parent | c2cf7d87d804c66e063829d5ca739053e901dc15 (diff) | |
PM: introduce hibernation and suspend notifiers
Make it possible to register hibernation and suspend notifiers, so that
subsystems can perform hibernation-related or suspend-related operations that
should not be carried out by device drivers' .suspend() and .resume()
routines.
[akpm@linux-foundation.org: build fixes]
[akpm@linux-foundation.org: cleanups]
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Cc: Nigel Cunningham <nigel@nigel.suspend2.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/notifier.h | 6 | ||||
| -rw-r--r-- | include/linux/suspend.h | 48 |
2 files changed, 49 insertions, 5 deletions
diff --git a/include/linux/notifier.h b/include/linux/notifier.h index 576f2bb34cc8..be3f2bb6fcf3 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h | |||
| @@ -212,5 +212,11 @@ extern int __srcu_notifier_call_chain(struct srcu_notifier_head *nh, | |||
| 212 | #define CPU_DEAD_FROZEN (CPU_DEAD | CPU_TASKS_FROZEN) | 212 | #define CPU_DEAD_FROZEN (CPU_DEAD | CPU_TASKS_FROZEN) |
| 213 | #define CPU_DYING_FROZEN (CPU_DYING | CPU_TASKS_FROZEN) | 213 | #define CPU_DYING_FROZEN (CPU_DYING | CPU_TASKS_FROZEN) |
| 214 | 214 | ||
| 215 | /* Hibernation and suspend events */ | ||
| 216 | #define PM_HIBERNATION_PREPARE 0x0001 /* Going to hibernate */ | ||
| 217 | #define PM_POST_HIBERNATION 0x0002 /* Hibernation finished */ | ||
| 218 | #define PM_SUSPEND_PREPARE 0x0003 /* Going to suspend the system */ | ||
| 219 | #define PM_POST_SUSPEND 0x0004 /* Suspend finished */ | ||
| 220 | |||
| 215 | #endif /* __KERNEL__ */ | 221 | #endif /* __KERNEL__ */ |
| 216 | #endif /* _LINUX_NOTIFIER_H */ | 222 | #endif /* _LINUX_NOTIFIER_H */ |
diff --git a/include/linux/suspend.h b/include/linux/suspend.h index d235c146da2b..e8e6da394c92 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h | |||
| @@ -54,7 +54,8 @@ struct hibernation_ops { | |||
| 54 | void (*restore_cleanup)(void); | 54 | void (*restore_cleanup)(void); |
| 55 | }; | 55 | }; |
| 56 | 56 | ||
| 57 | #if defined(CONFIG_PM) && defined(CONFIG_SOFTWARE_SUSPEND) | 57 | #ifdef CONFIG_PM |
| 58 | #ifdef CONFIG_SOFTWARE_SUSPEND | ||
| 58 | /* kernel/power/snapshot.c */ | 59 | /* kernel/power/snapshot.c */ |
| 59 | extern void __register_nosave_region(unsigned long b, unsigned long e, int km); | 60 | extern void __register_nosave_region(unsigned long b, unsigned long e, int km); |
| 60 | static inline void register_nosave_region(unsigned long b, unsigned long e) | 61 | static inline void register_nosave_region(unsigned long b, unsigned long e) |
| @@ -72,16 +73,14 @@ extern unsigned long get_safe_page(gfp_t gfp_mask); | |||
| 72 | 73 | ||
| 73 | extern void hibernation_set_ops(struct hibernation_ops *ops); | 74 | extern void hibernation_set_ops(struct hibernation_ops *ops); |
| 74 | extern int hibernate(void); | 75 | extern int hibernate(void); |
| 75 | #else | 76 | #else /* CONFIG_SOFTWARE_SUSPEND */ |
| 76 | static inline void register_nosave_region(unsigned long b, unsigned long e) {} | ||
| 77 | static inline void register_nosave_region_late(unsigned long b, unsigned long e) {} | ||
| 78 | static inline int swsusp_page_is_forbidden(struct page *p) { return 0; } | 77 | static inline int swsusp_page_is_forbidden(struct page *p) { return 0; } |
| 79 | static inline void swsusp_set_page_free(struct page *p) {} | 78 | static inline void swsusp_set_page_free(struct page *p) {} |
| 80 | static inline void swsusp_unset_page_free(struct page *p) {} | 79 | static inline void swsusp_unset_page_free(struct page *p) {} |
| 81 | 80 | ||
| 82 | static inline void hibernation_set_ops(struct hibernation_ops *ops) {} | 81 | static inline void hibernation_set_ops(struct hibernation_ops *ops) {} |
| 83 | static inline int hibernate(void) { return -ENOSYS; } | 82 | static inline int hibernate(void) { return -ENOSYS; } |
| 84 | #endif /* defined(CONFIG_PM) && defined(CONFIG_SOFTWARE_SUSPEND) */ | 83 | #endif /* CONFIG_SOFTWARE_SUSPEND */ |
| 85 | 84 | ||
| 86 | void save_processor_state(void); | 85 | void save_processor_state(void); |
| 87 | void restore_processor_state(void); | 86 | void restore_processor_state(void); |
| @@ -89,4 +88,43 @@ struct saved_context; | |||
| 89 | void __save_processor_state(struct saved_context *ctxt); | 88 | void __save_processor_state(struct saved_context *ctxt); |
| 90 | void __restore_processor_state(struct saved_context *ctxt); | 89 | void __restore_processor_state(struct saved_context *ctxt); |
| 91 | 90 | ||
| 91 | /* kernel/power/main.c */ | ||
| 92 | extern struct blocking_notifier_head pm_chain_head; | ||
| 93 | |||
| 94 | static inline int register_pm_notifier(struct notifier_block *nb) | ||
| 95 | { | ||
| 96 | return blocking_notifier_chain_register(&pm_chain_head, nb); | ||
| 97 | } | ||
| 98 | |||
| 99 | static inline int unregister_pm_notifier(struct notifier_block *nb) | ||
| 100 | { | ||
| 101 | return blocking_notifier_chain_unregister(&pm_chain_head, nb); | ||
| 102 | } | ||
| 103 | |||
| 104 | #define pm_notifier(fn, pri) { \ | ||
| 105 | static struct notifier_block fn##_nb = \ | ||
| 106 | { .notifier_call = fn, .priority = pri }; \ | ||
| 107 | register_pm_notifier(&fn##_nb); \ | ||
| 108 | } | ||
| 109 | #else /* CONFIG_PM */ | ||
| 110 | |||
| 111 | static inline int register_pm_notifier(struct notifier_block *nb) | ||
| 112 | { | ||
| 113 | return 0; | ||
| 114 | } | ||
| 115 | |||
| 116 | static inline int unregister_pm_notifier(struct notifier_block *nb) | ||
| 117 | { | ||
| 118 | return 0; | ||
| 119 | } | ||
| 120 | |||
| 121 | #define pm_notifier(fn, pri) do { (void)(fn); } while (0) | ||
| 122 | #endif /* CONFIG_PM */ | ||
| 123 | |||
| 124 | #if !defined CONFIG_SOFTWARE_SUSPEND || !defined(CONFIG_PM) | ||
| 125 | static inline void register_nosave_region(unsigned long b, unsigned long e) | ||
| 126 | { | ||
| 127 | } | ||
| 128 | #endif | ||
| 129 | |||
| 92 | #endif /* _LINUX_SWSUSP_H */ | 130 | #endif /* _LINUX_SWSUSP_H */ |
