aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2011-04-11 16:54:42 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2011-04-11 16:54:42 -0400
commit1f112cee07b314e244ee9e71d9c1e6950dc13327 (patch)
treee089e646c78701e37b4ebe00db36082e47cab2d5
parentb42282e5a05018ecdc0d63a4ad530b0999785912 (diff)
PM / Hibernate: Introduce CONFIG_HIBERNATE_CALLBACKS
Xen save/restore is going to use hibernate device callbacks for quiescing devices and putting them back to normal operations and it would need to select CONFIG_HIBERNATION for this purpose. However, that also would cause the hibernate interfaces for user space to be enabled, which might confuse user space, because the Xen kernels don't support hibernation. Moreover, it would be wasteful, as it would make the Xen kernels include a substantial amount of code that they would never use. To address this issue introduce new power management Kconfig option CONFIG_HIBERNATE_CALLBACKS, such that it will only select the code that is necessary for the hibernate device callbacks to work and make CONFIG_HIBERNATION select it. Then, Xen save/restore will be able to select CONFIG_HIBERNATE_CALLBACKS without dragging the entire hibernate code along with it. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Tested-by: Shriram Rajagopalan <rshriram@cs.ubc.ca>
-rw-r--r--arch/powerpc/kernel/ibmebus.c6
-rw-r--r--drivers/amba/bus.c6
-rw-r--r--drivers/base/platform.c6
-rw-r--r--drivers/base/power/main.c8
-rw-r--r--drivers/pci/pci-driver.c6
-rw-r--r--drivers/xen/manage.c6
-rw-r--r--include/linux/suspend.h11
-rw-r--r--kernel/power/Kconfig6
8 files changed, 27 insertions, 28 deletions
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index c00d4ca1ee15..28581f1ad2c0 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -527,7 +527,7 @@ static int ibmebus_bus_pm_resume_noirq(struct device *dev)
527 527
528#endif /* !CONFIG_SUSPEND */ 528#endif /* !CONFIG_SUSPEND */
529 529
530#ifdef CONFIG_HIBERNATION 530#ifdef CONFIG_HIBERNATE_CALLBACKS
531 531
532static int ibmebus_bus_pm_freeze(struct device *dev) 532static int ibmebus_bus_pm_freeze(struct device *dev)
533{ 533{
@@ -665,7 +665,7 @@ static int ibmebus_bus_pm_restore_noirq(struct device *dev)
665 return ret; 665 return ret;
666} 666}
667 667
668#else /* !CONFIG_HIBERNATION */ 668#else /* !CONFIG_HIBERNATE_CALLBACKS */
669 669
670#define ibmebus_bus_pm_freeze NULL 670#define ibmebus_bus_pm_freeze NULL
671#define ibmebus_bus_pm_thaw NULL 671#define ibmebus_bus_pm_thaw NULL
@@ -676,7 +676,7 @@ static int ibmebus_bus_pm_restore_noirq(struct device *dev)
676#define ibmebus_bus_pm_poweroff_noirq NULL 676#define ibmebus_bus_pm_poweroff_noirq NULL
677#define ibmebus_bus_pm_restore_noirq NULL 677#define ibmebus_bus_pm_restore_noirq NULL
678 678
679#endif /* !CONFIG_HIBERNATION */ 679#endif /* !CONFIG_HIBERNATE_CALLBACKS */
680 680
681static struct dev_pm_ops ibmebus_bus_dev_pm_ops = { 681static struct dev_pm_ops ibmebus_bus_dev_pm_ops = {
682 .prepare = ibmebus_bus_pm_prepare, 682 .prepare = ibmebus_bus_pm_prepare,
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 821040503154..7025593a58c8 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -214,7 +214,7 @@ static int amba_pm_resume_noirq(struct device *dev)
214 214
215#endif /* !CONFIG_SUSPEND */ 215#endif /* !CONFIG_SUSPEND */
216 216
217#ifdef CONFIG_HIBERNATION 217#ifdef CONFIG_HIBERNATE_CALLBACKS
218 218
219static int amba_pm_freeze(struct device *dev) 219static int amba_pm_freeze(struct device *dev)
220{ 220{
@@ -352,7 +352,7 @@ static int amba_pm_restore_noirq(struct device *dev)
352 return ret; 352 return ret;
353} 353}
354 354
355#else /* !CONFIG_HIBERNATION */ 355#else /* !CONFIG_HIBERNATE_CALLBACKS */
356 356
357#define amba_pm_freeze NULL 357#define amba_pm_freeze NULL
358#define amba_pm_thaw NULL 358#define amba_pm_thaw NULL
@@ -363,7 +363,7 @@ static int amba_pm_restore_noirq(struct device *dev)
363#define amba_pm_poweroff_noirq NULL 363#define amba_pm_poweroff_noirq NULL
364#define amba_pm_restore_noirq NULL 364#define amba_pm_restore_noirq NULL
365 365
366#endif /* !CONFIG_HIBERNATION */ 366#endif /* !CONFIG_HIBERNATE_CALLBACKS */
367 367
368#ifdef CONFIG_PM 368#ifdef CONFIG_PM
369 369
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index f051cfff18af..92792313d24a 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -771,7 +771,7 @@ int __weak platform_pm_resume_noirq(struct device *dev)
771 771
772#endif /* !CONFIG_SUSPEND */ 772#endif /* !CONFIG_SUSPEND */
773 773
774#ifdef CONFIG_HIBERNATION 774#ifdef CONFIG_HIBERNATE_CALLBACKS
775 775
776static int platform_pm_freeze(struct device *dev) 776static int platform_pm_freeze(struct device *dev)
777{ 777{
@@ -909,7 +909,7 @@ static int platform_pm_restore_noirq(struct device *dev)
909 return ret; 909 return ret;
910} 910}
911 911
912#else /* !CONFIG_HIBERNATION */ 912#else /* !CONFIG_HIBERNATE_CALLBACKS */
913 913
914#define platform_pm_freeze NULL 914#define platform_pm_freeze NULL
915#define platform_pm_thaw NULL 915#define platform_pm_thaw NULL
@@ -920,7 +920,7 @@ static int platform_pm_restore_noirq(struct device *dev)
920#define platform_pm_poweroff_noirq NULL 920#define platform_pm_poweroff_noirq NULL
921#define platform_pm_restore_noirq NULL 921#define platform_pm_restore_noirq NULL
922 922
923#endif /* !CONFIG_HIBERNATION */ 923#endif /* !CONFIG_HIBERNATE_CALLBACKS */
924 924
925#ifdef CONFIG_PM_RUNTIME 925#ifdef CONFIG_PM_RUNTIME
926 926
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 052dc53eef38..fbc5b6e7c591 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -233,7 +233,7 @@ static int pm_op(struct device *dev,
233 } 233 }
234 break; 234 break;
235#endif /* CONFIG_SUSPEND */ 235#endif /* CONFIG_SUSPEND */
236#ifdef CONFIG_HIBERNATION 236#ifdef CONFIG_HIBERNATE_CALLBACKS
237 case PM_EVENT_FREEZE: 237 case PM_EVENT_FREEZE:
238 case PM_EVENT_QUIESCE: 238 case PM_EVENT_QUIESCE:
239 if (ops->freeze) { 239 if (ops->freeze) {
@@ -260,7 +260,7 @@ static int pm_op(struct device *dev,
260 suspend_report_result(ops->restore, error); 260 suspend_report_result(ops->restore, error);
261 } 261 }
262 break; 262 break;
263#endif /* CONFIG_HIBERNATION */ 263#endif /* CONFIG_HIBERNATE_CALLBACKS */
264 default: 264 default:
265 error = -EINVAL; 265 error = -EINVAL;
266 } 266 }
@@ -308,7 +308,7 @@ static int pm_noirq_op(struct device *dev,
308 } 308 }
309 break; 309 break;
310#endif /* CONFIG_SUSPEND */ 310#endif /* CONFIG_SUSPEND */
311#ifdef CONFIG_HIBERNATION 311#ifdef CONFIG_HIBERNATE_CALLBACKS
312 case PM_EVENT_FREEZE: 312 case PM_EVENT_FREEZE:
313 case PM_EVENT_QUIESCE: 313 case PM_EVENT_QUIESCE:
314 if (ops->freeze_noirq) { 314 if (ops->freeze_noirq) {
@@ -335,7 +335,7 @@ static int pm_noirq_op(struct device *dev,
335 suspend_report_result(ops->restore_noirq, error); 335 suspend_report_result(ops->restore_noirq, error);
336 } 336 }
337 break; 337 break;
338#endif /* CONFIG_HIBERNATION */ 338#endif /* CONFIG_HIBERNATE_CALLBACKS */
339 default: 339 default:
340 error = -EINVAL; 340 error = -EINVAL;
341 } 341 }
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index d86ea8b01137..135df164a4c1 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -781,7 +781,7 @@ static int pci_pm_resume(struct device *dev)
781 781
782#endif /* !CONFIG_SUSPEND */ 782#endif /* !CONFIG_SUSPEND */
783 783
784#ifdef CONFIG_HIBERNATION 784#ifdef CONFIG_HIBERNATE_CALLBACKS
785 785
786static int pci_pm_freeze(struct device *dev) 786static int pci_pm_freeze(struct device *dev)
787{ 787{
@@ -970,7 +970,7 @@ static int pci_pm_restore(struct device *dev)
970 return error; 970 return error;
971} 971}
972 972
973#else /* !CONFIG_HIBERNATION */ 973#else /* !CONFIG_HIBERNATE_CALLBACKS */
974 974
975#define pci_pm_freeze NULL 975#define pci_pm_freeze NULL
976#define pci_pm_freeze_noirq NULL 976#define pci_pm_freeze_noirq NULL
@@ -981,7 +981,7 @@ static int pci_pm_restore(struct device *dev)
981#define pci_pm_restore NULL 981#define pci_pm_restore NULL
982#define pci_pm_restore_noirq NULL 982#define pci_pm_restore_noirq NULL
983 983
984#endif /* !CONFIG_HIBERNATION */ 984#endif /* !CONFIG_HIBERNATE_CALLBACKS */
985 985
986#ifdef CONFIG_PM_RUNTIME 986#ifdef CONFIG_PM_RUNTIME
987 987
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 95143dd6904d..1ac94125bf93 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -61,7 +61,7 @@ static void xen_post_suspend(int cancelled)
61 xen_mm_unpin_all(); 61 xen_mm_unpin_all();
62} 62}
63 63
64#ifdef CONFIG_HIBERNATION 64#ifdef CONFIG_HIBERNATE_CALLBACKS
65static int xen_suspend(void *data) 65static int xen_suspend(void *data)
66{ 66{
67 struct suspend_info *si = data; 67 struct suspend_info *si = data;
@@ -173,7 +173,7 @@ out:
173#endif 173#endif
174 shutting_down = SHUTDOWN_INVALID; 174 shutting_down = SHUTDOWN_INVALID;
175} 175}
176#endif /* CONFIG_HIBERNATION */ 176#endif /* CONFIG_HIBERNATE_CALLBACKS */
177 177
178struct shutdown_handler { 178struct shutdown_handler {
179 const char *command; 179 const char *command;
@@ -202,7 +202,7 @@ static void shutdown_handler(struct xenbus_watch *watch,
202 { "poweroff", do_poweroff }, 202 { "poweroff", do_poweroff },
203 { "halt", do_poweroff }, 203 { "halt", do_poweroff },
204 { "reboot", do_reboot }, 204 { "reboot", do_reboot },
205#ifdef CONFIG_HIBERNATION 205#ifdef CONFIG_HIBERNATE_CALLBACKS
206 { "suspend", do_suspend }, 206 { "suspend", do_suspend },
207#endif 207#endif
208 {NULL, NULL}, 208 {NULL, NULL},
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 5a89e3612875..083ffea7ba18 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -249,6 +249,8 @@ extern void hibernation_set_ops(const struct platform_hibernation_ops *ops);
249extern int hibernate(void); 249extern int hibernate(void);
250extern bool system_entering_hibernation(void); 250extern bool system_entering_hibernation(void);
251#else /* CONFIG_HIBERNATION */ 251#else /* CONFIG_HIBERNATION */
252static inline void register_nosave_region(unsigned long b, unsigned long e) {}
253static inline void register_nosave_region_late(unsigned long b, unsigned long e) {}
252static inline int swsusp_page_is_forbidden(struct page *p) { return 0; } 254static inline int swsusp_page_is_forbidden(struct page *p) { return 0; }
253static inline void swsusp_set_page_free(struct page *p) {} 255static inline void swsusp_set_page_free(struct page *p) {}
254static inline void swsusp_unset_page_free(struct page *p) {} 256static inline void swsusp_unset_page_free(struct page *p) {}
@@ -297,14 +299,7 @@ static inline bool pm_wakeup_pending(void) { return false; }
297 299
298extern struct mutex pm_mutex; 300extern struct mutex pm_mutex;
299 301
300#ifndef CONFIG_HIBERNATION 302#ifndef CONFIG_HIBERNATE_CALLBACKS
301static inline void register_nosave_region(unsigned long b, unsigned long e)
302{
303}
304static inline void register_nosave_region_late(unsigned long b, unsigned long e)
305{
306}
307
308static inline void lock_system_sleep(void) {} 303static inline void lock_system_sleep(void) {}
309static inline void unlock_system_sleep(void) {} 304static inline void unlock_system_sleep(void) {}
310 305
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 4603f08dc47b..049791468d37 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -18,9 +18,13 @@ config SUSPEND_FREEZER
18 18
19 Turning OFF this setting is NOT recommended! If in doubt, say Y. 19 Turning OFF this setting is NOT recommended! If in doubt, say Y.
20 20
21config HIBERNATE_CALLBACKS
22 bool
23
21config HIBERNATION 24config HIBERNATION
22 bool "Hibernation (aka 'suspend to disk')" 25 bool "Hibernation (aka 'suspend to disk')"
23 depends on SWAP && ARCH_HIBERNATION_POSSIBLE 26 depends on SWAP && ARCH_HIBERNATION_POSSIBLE
27 select HIBERNATE_CALLBACKS
24 select LZO_COMPRESS 28 select LZO_COMPRESS
25 select LZO_DECOMPRESS 29 select LZO_DECOMPRESS
26 ---help--- 30 ---help---
@@ -85,7 +89,7 @@ config PM_STD_PARTITION
85 89
86config PM_SLEEP 90config PM_SLEEP
87 def_bool y 91 def_bool y
88 depends on SUSPEND || HIBERNATION || XEN_SAVE_RESTORE 92 depends on SUSPEND || HIBERNATE_CALLBACKS || XEN_SAVE_RESTORE
89 93
90config PM_SLEEP_SMP 94config PM_SLEEP_SMP
91 def_bool y 95 def_bool y