|
@@ -26,6 +26,7 @@ struct nvs_page {
|
|
|
unsigned int size;
|
|
|
void *kaddr;
|
|
|
void *data;
|
|
|
+ bool unmap;
|
|
|
struct list_head node;
|
|
|
};
|
|
|
|
|
@@ -44,6 +45,9 @@ int suspend_nvs_register(unsigned long start, unsigned long size)
|
|
|
{
|
|
|
struct nvs_page *entry, *next;
|
|
|
|
|
|
+ pr_info("PM: Registering ACPI NVS region at %lx (%ld bytes)\n",
|
|
|
+ start, size);
|
|
|
+
|
|
|
while (size > 0) {
|
|
|
unsigned int nr_bytes;
|
|
|
|
|
@@ -81,7 +85,13 @@ void suspend_nvs_free(void)
|
|
|
free_page((unsigned long)entry->data);
|
|
|
entry->data = NULL;
|
|
|
if (entry->kaddr) {
|
|
|
- iounmap(entry->kaddr);
|
|
|
+ if (entry->unmap) {
|
|
|
+ iounmap(entry->kaddr);
|
|
|
+ entry->unmap = false;
|
|
|
+ } else {
|
|
|
+ acpi_os_unmap_memory(entry->kaddr,
|
|
|
+ entry->size);
|
|
|
+ }
|
|
|
entry->kaddr = NULL;
|
|
|
}
|
|
|
}
|
|
@@ -115,8 +125,14 @@ int suspend_nvs_save(void)
|
|
|
|
|
|
list_for_each_entry(entry, &nvs_list, node)
|
|
|
if (entry->data) {
|
|
|
- entry->kaddr = acpi_os_ioremap(entry->phys_start,
|
|
|
- entry->size);
|
|
|
+ unsigned long phys = entry->phys_start;
|
|
|
+ unsigned int size = entry->size;
|
|
|
+
|
|
|
+ entry->kaddr = acpi_os_get_iomem(phys, size);
|
|
|
+ if (!entry->kaddr) {
|
|
|
+ entry->kaddr = acpi_os_ioremap(phys, size);
|
|
|
+ entry->unmap = !!entry->kaddr;
|
|
|
+ }
|
|
|
if (!entry->kaddr) {
|
|
|
suspend_nvs_free();
|
|
|
return -ENOMEM;
|