aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2011-02-08 17:38:05 -0500
committerRafael J. Wysocki <rjw@sisk.pl>2011-02-24 13:58:41 -0500
commit7ffd0443f2502478545e23e194b7eb8e16376072 (patch)
tree467a47d0d8b9ce4de3c95aa11d25b8c9b5ce05a1 /drivers
parent7fe135dc058faea0ce319a03e3b6f98c5049955c (diff)
ACPI: Make acpi_os_map_memory() avoid creating unnecessary mappings
Modify acpi_os_map_memory() so that it doesn't call acpi_os_ioremap() unconditionally every time it is executed (except when acpi_gbl_permanent_mmap is unset), which pretty much defeats the purpose of maintaining the list of ACPI iomaps in osl.c. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/osl.c28
1 files changed, 15 insertions, 13 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index f6785bced215..445f205752a2 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -302,7 +302,7 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
302void __iomem *__init_refok 302void __iomem *__init_refok
303acpi_os_map_memory(acpi_physical_address phys, acpi_size size) 303acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
304{ 304{
305 struct acpi_ioremap *map, *tmp_map; 305 struct acpi_ioremap *map;
306 void __iomem *virt; 306 void __iomem *virt;
307 acpi_physical_address pg_off; 307 acpi_physical_address pg_off;
308 acpi_size pg_sz; 308 acpi_size pg_sz;
@@ -315,14 +315,25 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
315 if (!acpi_gbl_permanent_mmap) 315 if (!acpi_gbl_permanent_mmap)
316 return __acpi_map_table((unsigned long)phys, size); 316 return __acpi_map_table((unsigned long)phys, size);
317 317
318 mutex_lock(&acpi_ioremap_lock);
319 /* Check if there's a suitable mapping already. */
320 map = acpi_map_lookup(phys, size);
321 if (map) {
322 kref_get(&map->ref);
323 goto out;
324 }
325
318 map = kzalloc(sizeof(*map), GFP_KERNEL); 326 map = kzalloc(sizeof(*map), GFP_KERNEL);
319 if (!map) 327 if (!map) {
328 mutex_unlock(&acpi_ioremap_lock);
320 return NULL; 329 return NULL;
330 }
321 331
322 pg_off = round_down(phys, PAGE_SIZE); 332 pg_off = round_down(phys, PAGE_SIZE);
323 pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off; 333 pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
324 virt = acpi_os_ioremap(pg_off, pg_sz); 334 virt = acpi_os_ioremap(pg_off, pg_sz);
325 if (!virt) { 335 if (!virt) {
336 mutex_unlock(&acpi_ioremap_lock);
326 kfree(map); 337 kfree(map);
327 return NULL; 338 return NULL;
328 } 339 }
@@ -333,19 +344,10 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
333 map->size = pg_sz; 344 map->size = pg_sz;
334 kref_init(&map->ref); 345 kref_init(&map->ref);
335 346
336 mutex_lock(&acpi_ioremap_lock);
337 /* Check if page has already been mapped. */
338 tmp_map = acpi_map_lookup(phys, size);
339 if (tmp_map) {
340 kref_get(&tmp_map->ref);
341 mutex_unlock(&acpi_ioremap_lock);
342 iounmap(map->virt);
343 kfree(map);
344 return tmp_map->virt + (phys - tmp_map->phys);
345 }
346 list_add_tail_rcu(&map->list, &acpi_ioremaps); 347 list_add_tail_rcu(&map->list, &acpi_ioremaps);
347 mutex_unlock(&acpi_ioremap_lock);
348 348
349 out:
350 mutex_unlock(&acpi_ioremap_lock);
349 return map->virt + (phys - map->phys); 351 return map->virt + (phys - map->phys);
350} 352}
351EXPORT_SYMBOL_GPL(acpi_os_map_memory); 353EXPORT_SYMBOL_GPL(acpi_os_map_memory);