aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2011-02-08 17:38:38 -0500
committerRafael J. Wysocki <rjw@sisk.pl>2011-02-24 13:58:42 -0500
commitbb45e394e21eb2abc710ad43d98ebac1069bf355 (patch)
tree13e250fb395b358bb8c9471880d3d8fc121d6c2b /drivers/acpi
parent13606a2de1996f8d83a9ce296f74022bdbadf712 (diff)
ACPI / PM: Use existing ACPI iomaps for NVS save/restore (v2)
Modify the NVS save/restore code to use acpi_os_get_iomem() and acpi_os_unmap_memory() to acquire and release references to ACPI iomaps, respectively. If there's no ACPI iomap corresponding to the given NVS page, acpi_os_ioremap() is used to map that page and iounmap() is used to unmap it during resume. [If the page is not present in the ACPI iomaps already, it doesn't make sense to add its mapping to the list of ACPI iomaps, because it's going to be thrown away during the subsequent resume anyway.] Testing on my HP nx6325 shows that approx. 90% of the NVS pages have already been mapped by ACPI before suspend and are present in the ACPI iomaps, so this change appears to be the right thing to do in general. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/nvs.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/drivers/acpi/nvs.c b/drivers/acpi/nvs.c
index fa5a1df42b79..096787b43c96 100644
--- a/drivers/acpi/nvs.c
+++ b/drivers/acpi/nvs.c
@@ -26,6 +26,7 @@ struct nvs_page {
26 unsigned int size; 26 unsigned int size;
27 void *kaddr; 27 void *kaddr;
28 void *data; 28 void *data;
29 bool unmap;
29 struct list_head node; 30 struct list_head node;
30}; 31};
31 32
@@ -44,6 +45,9 @@ int suspend_nvs_register(unsigned long start, unsigned long size)
44{ 45{
45 struct nvs_page *entry, *next; 46 struct nvs_page *entry, *next;
46 47
48 pr_info("PM: Registering ACPI NVS region at %lx (%ld bytes)\n",
49 start, size);
50
47 while (size > 0) { 51 while (size > 0) {
48 unsigned int nr_bytes; 52 unsigned int nr_bytes;
49 53
@@ -81,7 +85,13 @@ void suspend_nvs_free(void)
81 free_page((unsigned long)entry->data); 85 free_page((unsigned long)entry->data);
82 entry->data = NULL; 86 entry->data = NULL;
83 if (entry->kaddr) { 87 if (entry->kaddr) {
84 iounmap(entry->kaddr); 88 if (entry->unmap) {
89 iounmap(entry->kaddr);
90 entry->unmap = false;
91 } else {
92 acpi_os_unmap_memory(entry->kaddr,
93 entry->size);
94 }
85 entry->kaddr = NULL; 95 entry->kaddr = NULL;
86 } 96 }
87 } 97 }
@@ -115,8 +125,14 @@ int suspend_nvs_save(void)
115 125
116 list_for_each_entry(entry, &nvs_list, node) 126 list_for_each_entry(entry, &nvs_list, node)
117 if (entry->data) { 127 if (entry->data) {
118 entry->kaddr = acpi_os_ioremap(entry->phys_start, 128 unsigned long phys = entry->phys_start;
119 entry->size); 129 unsigned int size = entry->size;
130
131 entry->kaddr = acpi_os_get_iomem(phys, size);
132 if (!entry->kaddr) {
133 entry->kaddr = acpi_os_ioremap(phys, size);
134 entry->unmap = !!entry->kaddr;
135 }
120 if (!entry->kaddr) { 136 if (!entry->kaddr) {
121 suspend_nvs_free(); 137 suspend_nvs_free();
122 return -ENOMEM; 138 return -ENOMEM;