Skip to content

Commit

Permalink
suspend: Move NVS save/restore code to generic suspend functionality
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Matthew Garrett authored and Len Brown committed Jun 10, 2010
1 parent 67a3e12 commit dd4c4f1
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 37 deletions.
2 changes: 1 addition & 1 deletion arch/x86/kernel/e820.c
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ static int __init e820_mark_nvs_memory(void)
struct e820entry *ei = &e820.map[i];

if (ei->type == E820_NVS)
hibernate_nvs_register(ei->addr, ei->size);
suspend_nvs_register(ei->addr, ei->size);
}

return 0;
Expand Down
12 changes: 6 additions & 6 deletions drivers/acpi/sleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ static int acpi_hibernation_begin(void)
{
int error;

error = s4_no_nvs ? 0 : hibernate_nvs_alloc();
error = s4_no_nvs ? 0 : suspend_nvs_alloc();
if (!error) {
acpi_target_sleep_state = ACPI_STATE_S4;
acpi_sleep_tts_switch(acpi_target_sleep_state);
Expand All @@ -407,7 +407,7 @@ static int acpi_hibernation_pre_snapshot(void)
int error = acpi_pm_prepare();

if (!error)
hibernate_nvs_save();
suspend_nvs_save();

return error;
}
Expand All @@ -432,7 +432,7 @@ static int acpi_hibernation_enter(void)

static void acpi_hibernation_finish(void)
{
hibernate_nvs_free();
suspend_nvs_free();
acpi_pm_finish();
}

Expand All @@ -452,7 +452,7 @@ static void acpi_hibernation_leave(void)
panic("ACPI S4 hardware signature mismatch");
}
/* Restore the NVS memory area */
hibernate_nvs_restore();
suspend_nvs_restore();
}

static int acpi_pm_pre_restore(void)
Expand Down Expand Up @@ -501,7 +501,7 @@ static int acpi_hibernation_begin_old(void)

if (!error) {
if (!s4_no_nvs)
error = hibernate_nvs_alloc();
error = suspend_nvs_alloc();
if (!error)
acpi_target_sleep_state = ACPI_STATE_S4;
}
Expand All @@ -513,7 +513,7 @@ static int acpi_hibernation_pre_snapshot_old(void)
int error = acpi_pm_disable_gpes();

if (!error)
hibernate_nvs_save();
suspend_nvs_save();

return error;
}
Expand Down
26 changes: 13 additions & 13 deletions include/linux/suspend.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,22 +256,22 @@ static inline int hibernate(void) { return -ENOSYS; }
static inline bool system_entering_hibernation(void) { return false; }
#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;
}
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
void save_processor_state(void);
Expand Down
9 changes: 5 additions & 4 deletions kernel/power/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,13 @@ config PM_SLEEP_ADVANCED_DEBUG
depends on PM_ADVANCED_DEBUG
default n

config SUSPEND_NVS
bool

config SUSPEND
bool "Suspend to RAM and standby"
depends on PM && ARCH_SUSPEND_POSSIBLE
select SUSPEND_NVS if HAS_IOMEM
default y
---help---
Allow the system to enter sleep states in which main memory is
Expand Down Expand Up @@ -130,13 +134,10 @@ config SUSPEND_FREEZER

Turning OFF this setting is NOT recommended! If in doubt, say Y.

config HIBERNATION_NVS
bool

config HIBERNATION
bool "Hibernation (aka 'suspend to disk')"
depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE
select HIBERNATION_NVS if HAS_IOMEM
select SUSPEND_NVS if HAS_IOMEM
---help---
Enable the suspend to disk (STD) functionality, which is usually
called "hibernation" in user interfaces. STD checkpoints the
Expand Down
2 changes: 1 addition & 1 deletion kernel/power/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ obj-$(CONFIG_SUSPEND) += suspend.o
obj-$(CONFIG_PM_TEST_SUSPEND) += suspend_test.o
obj-$(CONFIG_HIBERNATION) += hibernate.o snapshot.o swap.o user.o \
block_io.o
obj-$(CONFIG_HIBERNATION_NVS) += hibernate_nvs.o
obj-$(CONFIG_SUSPEND_NVS) += nvs.o

obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o
24 changes: 12 additions & 12 deletions kernel/power/hibernate_nvs.c → kernel/power/nvs.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

/*
* 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.
*/

Expand All @@ -30,15 +30,15 @@ struct nvs_page {
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
* @size - size of the region
*
* The NVS region need not be page-aligned (both ends) and we arrange
* things so that the data from page-aligned addresses in this region will
* 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;

Expand Down Expand Up @@ -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;

Expand All @@ -86,26 +86,26 @@ 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;

list_for_each_entry(entry, &nvs_list, node) {
entry->data = (void *)__get_free_page(GFP_KERNEL);
if (!entry->data) {
hibernate_nvs_free();
suspend_nvs_free();
return -ENOMEM;
}
}
return 0;
}

/**
* 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;

Expand All @@ -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
* 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;

Expand Down
6 changes: 6 additions & 0 deletions kernel/power/suspend.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
#include <linux/cpu.h>
#include <linux/syscalls.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"

Expand Down

0 comments on commit dd4c4f1

Please sign in to comment.