Commit 42de5532 authored by Len Brown's avatar Len Brown

Merge branch 'bugzilla-13931-sleep-nvs' into release

Conflicts:
	drivers/acpi/sleep.c
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parents e9e8b4dd 2a6b6976
...@@ -729,7 +729,7 @@ static int __init e820_mark_nvs_memory(void) ...@@ -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;
......
...@@ -114,6 +114,8 @@ static int __acpi_pm_prepare(void) ...@@ -114,6 +114,8 @@ static int __acpi_pm_prepare(void)
{ {
int error = acpi_sleep_prepare(acpi_target_sleep_state); int error = acpi_sleep_prepare(acpi_target_sleep_state);
suspend_nvs_save();
if (error) if (error)
acpi_target_sleep_state = ACPI_STATE_S0; acpi_target_sleep_state = ACPI_STATE_S0;
return error; return error;
...@@ -143,6 +145,9 @@ static void acpi_pm_finish(void) ...@@ -143,6 +145,9 @@ static void acpi_pm_finish(void)
{ {
u32 acpi_state = acpi_target_sleep_state; u32 acpi_state = acpi_target_sleep_state;
suspend_nvs_free();
acpi_ec_unblock_transactions();
if (acpi_state == ACPI_STATE_S0) if (acpi_state == ACPI_STATE_S0)
return; return;
...@@ -192,6 +197,11 @@ static int acpi_suspend_begin(suspend_state_t pm_state) ...@@ -192,6 +197,11 @@ static int acpi_suspend_begin(suspend_state_t pm_state)
u32 acpi_state = acpi_suspend_states[pm_state]; u32 acpi_state = acpi_suspend_states[pm_state];
int error = 0; int error = 0;
error = suspend_nvs_alloc();
if (error)
return error;
if (sleep_states[acpi_state]) { if (sleep_states[acpi_state]) {
acpi_target_sleep_state = acpi_state; acpi_target_sleep_state = acpi_state;
acpi_sleep_tts_switch(acpi_target_sleep_state); acpi_sleep_tts_switch(acpi_target_sleep_state);
...@@ -269,12 +279,13 @@ static int acpi_suspend_enter(suspend_state_t pm_state) ...@@ -269,12 +279,13 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
if (acpi_state == ACPI_STATE_S3) if (acpi_state == ACPI_STATE_S3)
acpi_restore_state_mem(); acpi_restore_state_mem();
suspend_nvs_restore();
return ACPI_SUCCESS(status) ? 0 : -EFAULT; return ACPI_SUCCESS(status) ? 0 : -EFAULT;
} }
static void acpi_suspend_finish(void) static void acpi_suspend_finish(void)
{ {
acpi_ec_unblock_transactions();
acpi_pm_finish(); acpi_pm_finish();
} }
...@@ -404,7 +415,7 @@ static int acpi_hibernation_begin(void) ...@@ -404,7 +415,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);
...@@ -418,7 +429,7 @@ static int acpi_hibernation_pre_snapshot(void) ...@@ -418,7 +429,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;
} }
...@@ -441,13 +452,6 @@ static int acpi_hibernation_enter(void) ...@@ -441,13 +452,6 @@ static int acpi_hibernation_enter(void)
return ACPI_SUCCESS(status) ? 0 : -EFAULT; return ACPI_SUCCESS(status) ? 0 : -EFAULT;
} }
static void acpi_hibernation_finish(void)
{
hibernate_nvs_free();
acpi_ec_unblock_transactions();
acpi_pm_finish();
}
static void acpi_hibernation_leave(void) static void acpi_hibernation_leave(void)
{ {
/* /*
...@@ -464,7 +468,7 @@ static void acpi_hibernation_leave(void) ...@@ -464,7 +468,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();
/* Allow EC transactions to happen. */ /* Allow EC transactions to happen. */
acpi_ec_unblock_transactions_early(); acpi_ec_unblock_transactions_early();
} }
...@@ -479,7 +483,7 @@ static struct platform_hibernation_ops acpi_hibernation_ops = { ...@@ -479,7 +483,7 @@ static struct platform_hibernation_ops acpi_hibernation_ops = {
.begin = acpi_hibernation_begin, .begin = acpi_hibernation_begin,
.end = acpi_pm_end, .end = acpi_pm_end,
.pre_snapshot = acpi_hibernation_pre_snapshot, .pre_snapshot = acpi_hibernation_pre_snapshot,
.finish = acpi_hibernation_finish, .finish = acpi_pm_finish,
.prepare = acpi_pm_prepare, .prepare = acpi_pm_prepare,
.enter = acpi_hibernation_enter, .enter = acpi_hibernation_enter,
.leave = acpi_hibernation_leave, .leave = acpi_hibernation_leave,
...@@ -507,7 +511,7 @@ static int acpi_hibernation_begin_old(void) ...@@ -507,7 +511,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;
} }
...@@ -517,7 +521,7 @@ static int acpi_hibernation_begin_old(void) ...@@ -517,7 +521,7 @@ static int acpi_hibernation_begin_old(void)
static int acpi_hibernation_pre_snapshot_old(void) static int acpi_hibernation_pre_snapshot_old(void)
{ {
acpi_pm_freeze(); acpi_pm_freeze();
hibernate_nvs_save(); suspend_nvs_save();
return 0; return 0;
} }
...@@ -529,8 +533,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops_old = { ...@@ -529,8 +533,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops_old = {
.begin = acpi_hibernation_begin_old, .begin = acpi_hibernation_begin_old,
.end = acpi_pm_end, .end = acpi_pm_end,
.pre_snapshot = acpi_hibernation_pre_snapshot_old, .pre_snapshot = acpi_hibernation_pre_snapshot_old,
.finish = acpi_hibernation_finish,
.prepare = acpi_pm_freeze, .prepare = acpi_pm_freeze,
.finish = acpi_pm_finish,
.enter = acpi_hibernation_enter, .enter = acpi_hibernation_enter,
.leave = acpi_hibernation_leave, .leave = acpi_hibernation_leave,
.pre_restore = acpi_pm_freeze, .pre_restore = acpi_pm_freeze,
......
...@@ -256,22 +256,22 @@ static inline int hibernate(void) { return -ENOSYS; } ...@@ -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 #ifdef CONFIG_SUSPEND_NVS
extern int hibernate_nvs_register(unsigned long start, unsigned long size); extern int suspend_nvs_register(unsigned long start, unsigned long size);
extern int hibernate_nvs_alloc(void); extern int suspend_nvs_alloc(void);
extern void hibernate_nvs_free(void); extern void suspend_nvs_free(void);
extern void hibernate_nvs_save(void); extern void suspend_nvs_save(void);
extern void hibernate_nvs_restore(void); extern void suspend_nvs_restore(void);
#else /* CONFIG_HIBERNATION_NVS */ #else /* CONFIG_SUSPEND_NVS */
static inline int hibernate_nvs_register(unsigned long a, unsigned long b) 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 int suspend_nvs_alloc(void) { return 0; }
static inline void hibernate_nvs_free(void) {} static inline void suspend_nvs_free(void) {}
static inline void hibernate_nvs_save(void) {} static inline void suspend_nvs_save(void) {}
static inline void hibernate_nvs_restore(void) {} static inline void suspend_nvs_restore(void) {}
#endif /* CONFIG_HIBERNATION_NVS */ #endif /* CONFIG_SUSPEND_NVS */
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
void save_processor_state(void); void save_processor_state(void);
......
...@@ -99,9 +99,13 @@ config PM_SLEEP_ADVANCED_DEBUG ...@@ -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 ...@@ -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
......
...@@ -10,6 +10,6 @@ obj-$(CONFIG_SUSPEND) += suspend.o ...@@ -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
...@@ -15,7 +15,7 @@ ...@@ -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 { ...@@ -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); ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
......
...@@ -16,6 +16,12 @@ ...@@ -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"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment