Ver código fonte

suspend: Move NVS save/restore code to generic suspend functionality

Saving platform non-volatile state may be required for suspend to RAM as
well as hibernation. Move it to more generic code.

Signed-off-by: Matthew Garrett <mjg@redhat.com>
Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
Tested-by: Maxim Levitsky <maximlevitsky@gmail.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Matthew Garrett 15 anos atrás
pai
commit
dd4c4f17d7

+ 1 - 1
arch/x86/kernel/e820.c

@@ -729,7 +729,7 @@ static int __init e820_mark_nvs_memory(void)
 		struct e820entry *ei = &e820.map[i];
 		struct e820entry *ei = &e820.map[i];
 
 
 		if (ei->type == E820_NVS)
 		if (ei->type == E820_NVS)
-			hibernate_nvs_register(ei->addr, ei->size);
+			suspend_nvs_register(ei->addr, ei->size);
 	}
 	}
 
 
 	return 0;
 	return 0;

+ 6 - 6
drivers/acpi/sleep.c

@@ -393,7 +393,7 @@ static int acpi_hibernation_begin(void)
 {
 {
 	int error;
 	int error;
 
 
-	error = s4_no_nvs ? 0 : hibernate_nvs_alloc();
+	error = s4_no_nvs ? 0 : suspend_nvs_alloc();
 	if (!error) {
 	if (!error) {
 		acpi_target_sleep_state = ACPI_STATE_S4;
 		acpi_target_sleep_state = ACPI_STATE_S4;
 		acpi_sleep_tts_switch(acpi_target_sleep_state);
 		acpi_sleep_tts_switch(acpi_target_sleep_state);
@@ -407,7 +407,7 @@ static int acpi_hibernation_pre_snapshot(void)
 	int error = acpi_pm_prepare();
 	int error = acpi_pm_prepare();
 
 
 	if (!error)
 	if (!error)
-		hibernate_nvs_save();
+		suspend_nvs_save();
 
 
 	return error;
 	return error;
 }
 }
@@ -432,7 +432,7 @@ static int acpi_hibernation_enter(void)
 
 
 static void acpi_hibernation_finish(void)
 static void acpi_hibernation_finish(void)
 {
 {
-	hibernate_nvs_free();
+	suspend_nvs_free();
 	acpi_pm_finish();
 	acpi_pm_finish();
 }
 }
 
 
@@ -452,7 +452,7 @@ static void acpi_hibernation_leave(void)
 		panic("ACPI S4 hardware signature mismatch");
 		panic("ACPI S4 hardware signature mismatch");
 	}
 	}
 	/* Restore the NVS memory area */
 	/* Restore the NVS memory area */
-	hibernate_nvs_restore();
+	suspend_nvs_restore();
 }
 }
 
 
 static int acpi_pm_pre_restore(void)
 static int acpi_pm_pre_restore(void)
@@ -501,7 +501,7 @@ static int acpi_hibernation_begin_old(void)
 
 
 	if (!error) {
 	if (!error) {
 		if (!s4_no_nvs)
 		if (!s4_no_nvs)
-			error = hibernate_nvs_alloc();
+			error = suspend_nvs_alloc();
 		if (!error)
 		if (!error)
 			acpi_target_sleep_state = ACPI_STATE_S4;
 			acpi_target_sleep_state = ACPI_STATE_S4;
 	}
 	}
@@ -513,7 +513,7 @@ static int acpi_hibernation_pre_snapshot_old(void)
 	int error = acpi_pm_disable_gpes();
 	int error = acpi_pm_disable_gpes();
 
 
 	if (!error)
 	if (!error)
-		hibernate_nvs_save();
+		suspend_nvs_save();
 
 
 	return error;
 	return error;
 }
 }

+ 13 - 13
include/linux/suspend.h

@@ -256,22 +256,22 @@ static inline int hibernate(void) { return -ENOSYS; }
 static inline bool system_entering_hibernation(void) { return false; }
 static inline bool system_entering_hibernation(void) { return false; }
 #endif /* CONFIG_HIBERNATION */
 #endif /* CONFIG_HIBERNATION */
 
 
-#ifdef CONFIG_HIBERNATION_NVS
-extern int hibernate_nvs_register(unsigned long start, unsigned long size);
-extern int hibernate_nvs_alloc(void);
-extern void hibernate_nvs_free(void);
-extern void hibernate_nvs_save(void);
-extern void hibernate_nvs_restore(void);
-#else /* CONFIG_HIBERNATION_NVS */
-static inline int hibernate_nvs_register(unsigned long a, unsigned long b)
+#ifdef CONFIG_SUSPEND_NVS
+extern int suspend_nvs_register(unsigned long start, unsigned long size);
+extern int suspend_nvs_alloc(void);
+extern void suspend_nvs_free(void);
+extern void suspend_nvs_save(void);
+extern void suspend_nvs_restore(void);
+#else /* CONFIG_SUSPEND_NVS */
+static inline int suspend_nvs_register(unsigned long a, unsigned long b)
 {
 {
 	return 0;
 	return 0;
 }
 }
-static inline int hibernate_nvs_alloc(void) { return 0; }
-static inline void hibernate_nvs_free(void) {}
-static inline void hibernate_nvs_save(void) {}
-static inline void hibernate_nvs_restore(void) {}
-#endif /* CONFIG_HIBERNATION_NVS */
+static inline int suspend_nvs_alloc(void) { return 0; }
+static inline void suspend_nvs_free(void) {}
+static inline void suspend_nvs_save(void) {}
+static inline void suspend_nvs_restore(void) {}
+#endif /* CONFIG_SUSPEND_NVS */
 
 
 #ifdef CONFIG_PM_SLEEP
 #ifdef CONFIG_PM_SLEEP
 void save_processor_state(void);
 void save_processor_state(void);

+ 5 - 4
kernel/power/Kconfig

@@ -99,9 +99,13 @@ config PM_SLEEP_ADVANCED_DEBUG
 	depends on PM_ADVANCED_DEBUG
 	depends on PM_ADVANCED_DEBUG
 	default n
 	default n
 
 
+config SUSPEND_NVS
+       bool
+
 config SUSPEND
 config SUSPEND
 	bool "Suspend to RAM and standby"
 	bool "Suspend to RAM and standby"
 	depends on PM && ARCH_SUSPEND_POSSIBLE
 	depends on PM && ARCH_SUSPEND_POSSIBLE
+	select SUSPEND_NVS if HAS_IOMEM
 	default y
 	default y
 	---help---
 	---help---
 	  Allow the system to enter sleep states in which main memory is
 	  Allow the system to enter sleep states in which main memory is
@@ -130,13 +134,10 @@ config SUSPEND_FREEZER
 
 
 	  Turning OFF this setting is NOT recommended! If in doubt, say Y.
 	  Turning OFF this setting is NOT recommended! If in doubt, say Y.
 
 
-config HIBERNATION_NVS
-	bool
-
 config HIBERNATION
 config HIBERNATION
 	bool "Hibernation (aka 'suspend to disk')"
 	bool "Hibernation (aka 'suspend to disk')"
 	depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE
 	depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE
-	select HIBERNATION_NVS if HAS_IOMEM
+	select SUSPEND_NVS if HAS_IOMEM
 	---help---
 	---help---
 	  Enable the suspend to disk (STD) functionality, which is usually
 	  Enable the suspend to disk (STD) functionality, which is usually
 	  called "hibernation" in user interfaces.  STD checkpoints the
 	  called "hibernation" in user interfaces.  STD checkpoints the

+ 1 - 1
kernel/power/Makefile

@@ -10,6 +10,6 @@ obj-$(CONFIG_SUSPEND)		+= suspend.o
 obj-$(CONFIG_PM_TEST_SUSPEND)	+= suspend_test.o
 obj-$(CONFIG_PM_TEST_SUSPEND)	+= suspend_test.o
 obj-$(CONFIG_HIBERNATION)	+= hibernate.o snapshot.o swap.o user.o \
 obj-$(CONFIG_HIBERNATION)	+= hibernate.o snapshot.o swap.o user.o \
 				   block_io.o
 				   block_io.o
-obj-$(CONFIG_HIBERNATION_NVS)	+= hibernate_nvs.o
+obj-$(CONFIG_SUSPEND_NVS)	+= nvs.o
 
 
 obj-$(CONFIG_MAGIC_SYSRQ)	+= poweroff.o
 obj-$(CONFIG_MAGIC_SYSRQ)	+= poweroff.o

+ 12 - 12
kernel/power/hibernate_nvs.c → kernel/power/nvs.c

@@ -15,7 +15,7 @@
 
 
 /*
 /*
  * Platforms, like ACPI, may want us to save some memory used by them during
  * Platforms, like ACPI, may want us to save some memory used by them during
- * hibernation and to restore the contents of this memory during the subsequent
+ * suspend and to restore the contents of this memory during the subsequent
  * resume.  The code below implements a mechanism allowing us to do that.
  * resume.  The code below implements a mechanism allowing us to do that.
  */
  */
 
 
@@ -30,7 +30,7 @@ struct nvs_page {
 static LIST_HEAD(nvs_list);
 static LIST_HEAD(nvs_list);
 
 
 /**
 /**
- *	hibernate_nvs_register - register platform NVS memory region to save
+ *	suspend_nvs_register - register platform NVS memory region to save
  *	@start - physical address of the region
  *	@start - physical address of the region
  *	@size - size of the region
  *	@size - size of the region
  *
  *
@@ -38,7 +38,7 @@ static LIST_HEAD(nvs_list);
  *	things so that the data from page-aligned addresses in this region will
  *	things so that the data from page-aligned addresses in this region will
  *	be copied into separate RAM pages.
  *	be copied into separate RAM pages.
  */
  */
-int hibernate_nvs_register(unsigned long start, unsigned long size)
+int suspend_nvs_register(unsigned long start, unsigned long size)
 {
 {
 	struct nvs_page *entry, *next;
 	struct nvs_page *entry, *next;
 
 
@@ -68,9 +68,9 @@ int hibernate_nvs_register(unsigned long start, unsigned long size)
 }
 }
 
 
 /**
 /**
- *	hibernate_nvs_free - free data pages allocated for saving NVS regions
+ *	suspend_nvs_free - free data pages allocated for saving NVS regions
  */
  */
-void hibernate_nvs_free(void)
+void suspend_nvs_free(void)
 {
 {
 	struct nvs_page *entry;
 	struct nvs_page *entry;
 
 
@@ -86,16 +86,16 @@ void hibernate_nvs_free(void)
 }
 }
 
 
 /**
 /**
- *	hibernate_nvs_alloc - allocate memory necessary for saving NVS regions
+ *	suspend_nvs_alloc - allocate memory necessary for saving NVS regions
  */
  */
-int hibernate_nvs_alloc(void)
+int suspend_nvs_alloc(void)
 {
 {
 	struct nvs_page *entry;
 	struct nvs_page *entry;
 
 
 	list_for_each_entry(entry, &nvs_list, node) {
 	list_for_each_entry(entry, &nvs_list, node) {
 		entry->data = (void *)__get_free_page(GFP_KERNEL);
 		entry->data = (void *)__get_free_page(GFP_KERNEL);
 		if (!entry->data) {
 		if (!entry->data) {
-			hibernate_nvs_free();
+			suspend_nvs_free();
 			return -ENOMEM;
 			return -ENOMEM;
 		}
 		}
 	}
 	}
@@ -103,9 +103,9 @@ int hibernate_nvs_alloc(void)
 }
 }
 
 
 /**
 /**
- *	hibernate_nvs_save - save NVS memory regions
+ *	suspend_nvs_save - save NVS memory regions
  */
  */
-void hibernate_nvs_save(void)
+void suspend_nvs_save(void)
 {
 {
 	struct nvs_page *entry;
 	struct nvs_page *entry;
 
 
@@ -119,12 +119,12 @@ void hibernate_nvs_save(void)
 }
 }
 
 
 /**
 /**
- *	hibernate_nvs_restore - restore NVS memory regions
+ *	suspend_nvs_restore - restore NVS memory regions
  *
  *
  *	This function is going to be called with interrupts disabled, so it
  *	This function is going to be called with interrupts disabled, so it
  *	cannot iounmap the virtual addresses used to access the NVS region.
  *	cannot iounmap the virtual addresses used to access the NVS region.
  */
  */
-void hibernate_nvs_restore(void)
+void suspend_nvs_restore(void)
 {
 {
 	struct nvs_page *entry;
 	struct nvs_page *entry;
 
 

+ 6 - 0
kernel/power/suspend.c

@@ -16,6 +16,12 @@
 #include <linux/cpu.h>
 #include <linux/cpu.h>
 #include <linux/syscalls.h>
 #include <linux/syscalls.h>
 #include <linux/gfp.h>
 #include <linux/gfp.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/suspend.h>
 
 
 #include "power.h"
 #include "power.h"