Commit 2d6d9fd3a54a28c6f67f26eb6c74803307a1b11e

Authored by Rafael J. Wysocki
Committed by Linus Torvalds
1 parent 8d99641f6c

ACPI: Introduce acpi_os_ioremap()

Commit ca9b600be38c ("ACPI / PM: Make suspend_nvs_save() use
acpi_os_map_memory()") attempted to prevent the code in osl.c and nvs.c
from using different ioremap() variants by making the latter use
acpi_os_map_memory() for mapping the NVS pages.  However, that also
requires acpi_os_unmap_memory() to be used for unmapping them, which
causes synchronize_rcu() to be executed many times in a row
unnecessarily and introduces substantial delays during resume on some
systems.

Instead of using acpi_os_map_memory() for mapping the NVS pages in nvs.c
introduce acpi_os_ioremap() calling ioremap_cache() and make the code in
both osl.c and nvs.c use it.

Reported-by: Jeff Chua <jeff.chua.linux@gmail.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 4 changed files with 27 additions and 11 deletions Side-by-side Diff

... ... @@ -12,6 +12,7 @@
12 12 #include <linux/mm.h>
13 13 #include <linux/slab.h>
14 14 #include <linux/acpi.h>
  15 +#include <linux/acpi_io.h>
15 16 #include <acpi/acpiosxf.h>
16 17  
17 18 /*
... ... @@ -80,7 +81,7 @@
80 81 free_page((unsigned long)entry->data);
81 82 entry->data = NULL;
82 83 if (entry->kaddr) {
83   - acpi_os_unmap_memory(entry->kaddr, entry->size);
  84 + iounmap(entry->kaddr);
84 85 entry->kaddr = NULL;
85 86 }
86 87 }
... ... @@ -114,8 +115,8 @@
114 115  
115 116 list_for_each_entry(entry, &nvs_list, node)
116 117 if (entry->data) {
117   - entry->kaddr = acpi_os_map_memory(entry->phys_start,
118   - entry->size);
  118 + entry->kaddr = acpi_os_ioremap(entry->phys_start,
  119 + entry->size);
119 120 if (!entry->kaddr) {
120 121 suspend_nvs_free();
121 122 return -ENOMEM;
... ... @@ -38,6 +38,7 @@
38 38 #include <linux/workqueue.h>
39 39 #include <linux/nmi.h>
40 40 #include <linux/acpi.h>
  41 +#include <linux/acpi_io.h>
41 42 #include <linux/efi.h>
42 43 #include <linux/ioport.h>
43 44 #include <linux/list.h>
44 45  
... ... @@ -302,9 +303,10 @@
302 303 acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
303 304 {
304 305 struct acpi_ioremap *map, *tmp_map;
305   - unsigned long flags, pg_sz;
  306 + unsigned long flags;
306 307 void __iomem *virt;
307   - phys_addr_t pg_off;
  308 + acpi_physical_address pg_off;
  309 + acpi_size pg_sz;
308 310  
309 311 if (phys > ULONG_MAX) {
310 312 printk(KERN_ERR PREFIX "Cannot map memory that high\n");
... ... @@ -320,7 +322,7 @@
320 322  
321 323 pg_off = round_down(phys, PAGE_SIZE);
322 324 pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
323   - virt = ioremap_cache(pg_off, pg_sz);
  325 + virt = acpi_os_ioremap(pg_off, pg_sz);
324 326 if (!virt) {
325 327 kfree(map);
326 328 return NULL;
... ... @@ -642,7 +644,7 @@
642 644 virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
643 645 rcu_read_unlock();
644 646 if (!virt_addr) {
645   - virt_addr = ioremap_cache(phys_addr, size);
  647 + virt_addr = acpi_os_ioremap(phys_addr, size);
646 648 unmap = 1;
647 649 }
648 650 if (!value)
... ... @@ -678,7 +680,7 @@
678 680 virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
679 681 rcu_read_unlock();
680 682 if (!virt_addr) {
681   - virt_addr = ioremap_cache(phys_addr, size);
  683 + virt_addr = acpi_os_ioremap(phys_addr, size);
682 684 unmap = 1;
683 685 }
684 686  
include/linux/acpi.h
... ... @@ -306,9 +306,6 @@
306 306 u32 *mask, u32 req);
307 307 extern void acpi_early_init(void);
308 308  
309   -int acpi_os_map_generic_address(struct acpi_generic_address *addr);
310   -void acpi_os_unmap_generic_address(struct acpi_generic_address *addr);
311   -
312 309 #else /* !CONFIG_ACPI */
313 310  
314 311 #define acpi_disabled 1
include/linux/acpi_io.h
  1 +#ifndef _ACPI_IO_H_
  2 +#define _ACPI_IO_H_
  3 +
  4 +#include <linux/io.h>
  5 +#include <acpi/acpi.h>
  6 +
  7 +static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys,
  8 + acpi_size size)
  9 +{
  10 + return ioremap_cache(phys, size);
  11 +}
  12 +
  13 +int acpi_os_map_generic_address(struct acpi_generic_address *addr);
  14 +void acpi_os_unmap_generic_address(struct acpi_generic_address *addr);
  15 +
  16 +#endif