aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/e820.c4
-rw-r--r--drivers/acpi/Makefile3
-rw-r--r--drivers/acpi/nvs.c53
-rw-r--r--include/linux/acpi.h20
4 files changed, 70 insertions, 10 deletions
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 303a0e48f076..51c3b186e5b9 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -714,7 +714,7 @@ void __init e820_mark_nosave_regions(unsigned long limit_pfn)
714} 714}
715#endif 715#endif
716 716
717#ifdef CONFIG_HIBERNATION 717#ifdef CONFIG_ACPI
718/** 718/**
719 * Mark ACPI NVS memory region, so that we can save/restore it during 719 * Mark ACPI NVS memory region, so that we can save/restore it during
720 * hibernation and the subsequent resume. 720 * hibernation and the subsequent resume.
@@ -727,7 +727,7 @@ static int __init e820_mark_nvs_memory(void)
727 struct e820entry *ei = &e820.map[i]; 727 struct e820entry *ei = &e820.map[i];
728 728
729 if (ei->type == E820_NVS) 729 if (ei->type == E820_NVS)
730 suspend_nvs_register(ei->addr, ei->size); 730 acpi_nvs_register(ei->addr, ei->size);
731 } 731 }
732 732
733 return 0; 733 return 0;
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index ecb26b4f29a0..c07f44f05f9d 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -20,11 +20,12 @@ obj-y += acpi.o \
20# All the builtin files are in the "acpi." module_param namespace. 20# All the builtin files are in the "acpi." module_param namespace.
21acpi-y += osl.o utils.o reboot.o 21acpi-y += osl.o utils.o reboot.o
22acpi-y += atomicio.o 22acpi-y += atomicio.o
23acpi-y += nvs.o
23 24
24# sleep related files 25# sleep related files
25acpi-y += wakeup.o 26acpi-y += wakeup.o
26acpi-y += sleep.o 27acpi-y += sleep.o
27acpi-$(CONFIG_ACPI_SLEEP) += proc.o nvs.o 28acpi-$(CONFIG_ACPI_SLEEP) += proc.o
28 29
29 30
30# 31#
diff --git a/drivers/acpi/nvs.c b/drivers/acpi/nvs.c
index 096787b43c96..7a2035fa8c71 100644
--- a/drivers/acpi/nvs.c
+++ b/drivers/acpi/nvs.c
@@ -15,6 +15,56 @@
15#include <linux/acpi_io.h> 15#include <linux/acpi_io.h>
16#include <acpi/acpiosxf.h> 16#include <acpi/acpiosxf.h>
17 17
18/* ACPI NVS regions, APEI may use it */
19
20struct nvs_region {
21 __u64 phys_start;
22 __u64 size;
23 struct list_head node;
24};
25
26static LIST_HEAD(nvs_region_list);
27
28#ifdef CONFIG_ACPI_SLEEP
29static int suspend_nvs_register(unsigned long start, unsigned long size);
30#else
31static inline int suspend_nvs_register(unsigned long a, unsigned long b)
32{
33 return 0;
34}
35#endif
36
37int acpi_nvs_register(__u64 start, __u64 size)
38{
39 struct nvs_region *region;
40
41 region = kmalloc(sizeof(*region), GFP_KERNEL);
42 if (!region)
43 return -ENOMEM;
44 region->phys_start = start;
45 region->size = size;
46 list_add_tail(&region->node, &nvs_region_list);
47
48 return suspend_nvs_register(start, size);
49}
50
51int acpi_nvs_for_each_region(int (*func)(__u64 start, __u64 size, void *data),
52 void *data)
53{
54 int rc;
55 struct nvs_region *region;
56
57 list_for_each_entry(region, &nvs_region_list, node) {
58 rc = func(region->phys_start, region->size, data);
59 if (rc)
60 return rc;
61 }
62
63 return 0;
64}
65
66
67#ifdef CONFIG_ACPI_SLEEP
18/* 68/*
19 * Platforms, like ACPI, may want us to save some memory used by them during 69 * Platforms, like ACPI, may want us to save some memory used by them during
20 * suspend and to restore the contents of this memory during the subsequent 70 * suspend and to restore the contents of this memory during the subsequent
@@ -41,7 +91,7 @@ static LIST_HEAD(nvs_list);
41 * things so that the data from page-aligned addresses in this region will 91 * things so that the data from page-aligned addresses in this region will
42 * be copied into separate RAM pages. 92 * be copied into separate RAM pages.
43 */ 93 */
44int suspend_nvs_register(unsigned long start, unsigned long size) 94static int suspend_nvs_register(unsigned long start, unsigned long size)
45{ 95{
46 struct nvs_page *entry, *next; 96 struct nvs_page *entry, *next;
47 97
@@ -159,3 +209,4 @@ void suspend_nvs_restore(void)
159 if (entry->data) 209 if (entry->data)
160 memcpy(entry->kaddr, entry->data, entry->size); 210 memcpy(entry->kaddr, entry->data, entry->size);
161} 211}
212#endif
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 6001b4da39dd..26b75442ff7a 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -306,6 +306,11 @@ extern acpi_status acpi_pci_osc_control_set(acpi_handle handle,
306 u32 *mask, u32 req); 306 u32 *mask, u32 req);
307extern void acpi_early_init(void); 307extern void acpi_early_init(void);
308 308
309extern int acpi_nvs_register(__u64 start, __u64 size);
310
311extern int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *),
312 void *data);
313
309#else /* !CONFIG_ACPI */ 314#else /* !CONFIG_ACPI */
310 315
311#define acpi_disabled 1 316#define acpi_disabled 1
@@ -348,15 +353,18 @@ static inline int acpi_table_parse(char *id,
348{ 353{
349 return -1; 354 return -1;
350} 355}
351#endif /* !CONFIG_ACPI */
352 356
353#ifdef CONFIG_ACPI_SLEEP 357static inline int acpi_nvs_register(__u64 start, __u64 size)
354int suspend_nvs_register(unsigned long start, unsigned long size);
355#else
356static inline int suspend_nvs_register(unsigned long a, unsigned long b)
357{ 358{
358 return 0; 359 return 0;
359} 360}
360#endif 361
362static inline int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *),
363 void *data)
364{
365 return 0;
366}
367
368#endif /* !CONFIG_ACPI */
361 369
362#endif /*_LINUX_ACPI_H*/ 370#endif /*_LINUX_ACPI_H*/