]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/s390/kernel/suspend.c
s390/hibernate: Save and restore absolute zero pages
[karo-tx-linux.git] / arch / s390 / kernel / suspend.c
index aa1494d0e380f907f56c74e53198dcad2dff592d..c479d2f9605ba6ef3dede5a669be872f97494b0f 100644 (file)
@@ -41,6 +41,7 @@ struct page_key_data {
 static struct page_key_data *page_key_data;
 static struct page_key_data *page_key_rp, *page_key_wp;
 static unsigned long page_key_rx, page_key_wx;
+unsigned long suspend_zero_pages;
 
 /*
  * For each page in the hibernation image one additional byte is
@@ -149,6 +150,36 @@ int pfn_is_nosave(unsigned long pfn)
        return 0;
 }
 
+/*
+ * PM notifier callback for suspend
+ */
+static int suspend_pm_cb(struct notifier_block *nb, unsigned long action,
+                        void *ptr)
+{
+       switch (action) {
+       case PM_SUSPEND_PREPARE:
+       case PM_HIBERNATION_PREPARE:
+               suspend_zero_pages = __get_free_pages(GFP_KERNEL, LC_ORDER);
+               if (!suspend_zero_pages)
+                       return NOTIFY_BAD;
+               break;
+       case PM_POST_SUSPEND:
+       case PM_POST_HIBERNATION:
+               free_pages(suspend_zero_pages, LC_ORDER);
+               break;
+       default:
+               return NOTIFY_DONE;
+       }
+       return NOTIFY_OK;
+}
+
+static int __init suspend_pm_init(void)
+{
+       pm_notifier(suspend_pm_cb, 0);
+       return 0;
+}
+arch_initcall(suspend_pm_init);
+
 void save_processor_state(void)
 {
        /* swsusp_arch_suspend() actually saves all cpu register contents.