diff options
Diffstat (limited to 'drivers/acpi/osl.c')
-rw-r--r-- | drivers/acpi/osl.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 5498a6d88ba2..412a1e04a922 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/mm.h> | 33 | #include <linux/mm.h> |
34 | #include <linux/highmem.h> | ||
34 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
35 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
36 | #include <linux/kmod.h> | 37 | #include <linux/kmod.h> |
@@ -321,6 +322,37 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size size) | |||
321 | return NULL; | 322 | return NULL; |
322 | } | 323 | } |
323 | 324 | ||
325 | #ifndef CONFIG_IA64 | ||
326 | #define should_use_kmap(pfn) page_is_ram(pfn) | ||
327 | #else | ||
328 | /* ioremap will take care of cache attributes */ | ||
329 | #define should_use_kmap(pfn) 0 | ||
330 | #endif | ||
331 | |||
332 | static void __iomem *acpi_map(acpi_physical_address pg_off, unsigned long pg_sz) | ||
333 | { | ||
334 | unsigned long pfn; | ||
335 | |||
336 | pfn = pg_off >> PAGE_SHIFT; | ||
337 | if (should_use_kmap(pfn)) { | ||
338 | if (pg_sz > PAGE_SIZE) | ||
339 | return NULL; | ||
340 | return (void __iomem __force *)kmap(pfn_to_page(pfn)); | ||
341 | } else | ||
342 | return acpi_os_ioremap(pg_off, pg_sz); | ||
343 | } | ||
344 | |||
345 | static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr) | ||
346 | { | ||
347 | unsigned long pfn; | ||
348 | |||
349 | pfn = pg_off >> PAGE_SHIFT; | ||
350 | if (page_is_ram(pfn)) | ||
351 | kunmap(pfn_to_page(pfn)); | ||
352 | else | ||
353 | iounmap(vaddr); | ||
354 | } | ||
355 | |||
324 | void __iomem *__init_refok | 356 | void __iomem *__init_refok |
325 | acpi_os_map_memory(acpi_physical_address phys, acpi_size size) | 357 | acpi_os_map_memory(acpi_physical_address phys, acpi_size size) |
326 | { | 358 | { |
@@ -353,7 +385,7 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size) | |||
353 | 385 | ||
354 | pg_off = round_down(phys, PAGE_SIZE); | 386 | pg_off = round_down(phys, PAGE_SIZE); |
355 | pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off; | 387 | pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off; |
356 | virt = acpi_os_ioremap(pg_off, pg_sz); | 388 | virt = acpi_map(pg_off, pg_sz); |
357 | if (!virt) { | 389 | if (!virt) { |
358 | mutex_unlock(&acpi_ioremap_lock); | 390 | mutex_unlock(&acpi_ioremap_lock); |
359 | kfree(map); | 391 | kfree(map); |
@@ -384,7 +416,7 @@ static void acpi_os_map_cleanup(struct acpi_ioremap *map) | |||
384 | { | 416 | { |
385 | if (!map->refcount) { | 417 | if (!map->refcount) { |
386 | synchronize_rcu(); | 418 | synchronize_rcu(); |
387 | iounmap(map->virt); | 419 | acpi_unmap(map->phys, map->virt); |
388 | kfree(map); | 420 | kfree(map); |
389 | } | 421 | } |
390 | } | 422 | } |