aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorHuang Ying <ying.huang@intel.com>2011-12-07 22:25:49 -0500
committerLen Brown <len.brown@intel.com>2012-01-17 03:54:44 -0500
commitb54ac6d2a25084667da781c7ca2cebef52a2bcdd (patch)
treeb4dbaa790dcecff6b5b0772846d43b360f6389d7 /drivers/acpi
parentb4e008dc53a31cb4bf6a12d9dbaf1d5c6070a838 (diff)
ACPI, Record ACPI NVS regions
Some firmware will access memory in ACPI NVS region via APEI. That is, instructions in APEI ERST/EINJ table will read/write ACPI NVS region. The original resource conflict checking in APEI code will check memory/ioport accessed by APEI via general resource management mechanism. But ACPI NVS region is marked as busy already, so that the false resource conflict will prevent APEI ERST/EINJ to work. To fix this, this patch record ACPI NVS regions, so that we can avoid request resources for memory region inside it. Signed-off-by: Huang Ying <ying.huang@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/Makefile3
-rw-r--r--drivers/acpi/nvs.c53
2 files changed, 54 insertions, 2 deletions
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