diff options
author | Myron Stowe <mstowe@redhat.com> | 2012-01-20 21:13:30 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2012-01-21 01:08:38 -0500 |
commit | ba242d5b1a84bc6611732296517ee40d5a80a4d9 (patch) | |
tree | 96b24f78882f776c23121bf6851921136fc9af64 /drivers/acpi | |
parent | e615bf5b5519862ab66172f4dec7455d6543a578 (diff) |
ACPI, APEI: Add RAM mapping support to ACPI
This patch adds support for RAM to ACPI's mapping capabilities in order
to support APEI error injection (EINJ) actions.
This patch re-factors similar functionality introduced in commit
76da3fb3575, bringing it into osl.c in preparation for removing
./drivers/acpi/atomicio.[ch].
Signed-off-by: Myron Stowe <myron.stowe@redhat.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-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 | } |