diff options
Diffstat (limited to 'arch/ia64/mm/ioremap.c')
-rw-r--r-- | arch/ia64/mm/ioremap.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/arch/ia64/mm/ioremap.c b/arch/ia64/mm/ioremap.c index 643ccc6960ce..07bd02b6c372 100644 --- a/arch/ia64/mm/ioremap.c +++ b/arch/ia64/mm/ioremap.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/efi.h> | 12 | #include <linux/efi.h> |
13 | #include <asm/io.h> | 13 | #include <asm/io.h> |
14 | #include <asm/meminit.h> | ||
14 | 15 | ||
15 | static inline void __iomem * | 16 | static inline void __iomem * |
16 | __ioremap (unsigned long offset, unsigned long size) | 17 | __ioremap (unsigned long offset, unsigned long size) |
@@ -21,16 +22,29 @@ __ioremap (unsigned long offset, unsigned long size) | |||
21 | void __iomem * | 22 | void __iomem * |
22 | ioremap (unsigned long offset, unsigned long size) | 23 | ioremap (unsigned long offset, unsigned long size) |
23 | { | 24 | { |
24 | if (efi_mem_attribute_range(offset, size, EFI_MEMORY_WB)) | 25 | u64 attr; |
25 | return phys_to_virt(offset); | 26 | unsigned long gran_base, gran_size; |
26 | 27 | ||
27 | if (efi_mem_attribute_range(offset, size, EFI_MEMORY_UC)) | 28 | /* |
29 | * For things in kern_memmap, we must use the same attribute | ||
30 | * as the rest of the kernel. For more details, see | ||
31 | * Documentation/ia64/aliasing.txt. | ||
32 | */ | ||
33 | attr = kern_mem_attribute(offset, size); | ||
34 | if (attr & EFI_MEMORY_WB) | ||
35 | return phys_to_virt(offset); | ||
36 | else if (attr & EFI_MEMORY_UC) | ||
28 | return __ioremap(offset, size); | 37 | return __ioremap(offset, size); |
29 | 38 | ||
30 | /* | 39 | /* |
31 | * Someday this should check ACPI resources so we | 40 | * Some chipsets don't support UC access to memory. If |
32 | * can do the right thing for hot-plugged regions. | 41 | * WB is supported for the whole granule, we prefer that. |
33 | */ | 42 | */ |
43 | gran_base = GRANULEROUNDDOWN(offset); | ||
44 | gran_size = GRANULEROUNDUP(offset + size) - gran_base; | ||
45 | if (efi_mem_attribute(gran_base, gran_size) & EFI_MEMORY_WB) | ||
46 | return phys_to_virt(offset); | ||
47 | |||
34 | return __ioremap(offset, size); | 48 | return __ioremap(offset, size); |
35 | } | 49 | } |
36 | EXPORT_SYMBOL(ioremap); | 50 | EXPORT_SYMBOL(ioremap); |
@@ -38,6 +52,9 @@ EXPORT_SYMBOL(ioremap); | |||
38 | void __iomem * | 52 | void __iomem * |
39 | ioremap_nocache (unsigned long offset, unsigned long size) | 53 | ioremap_nocache (unsigned long offset, unsigned long size) |
40 | { | 54 | { |
55 | if (kern_mem_attribute(offset, size) & EFI_MEMORY_WB) | ||
56 | return 0; | ||
57 | |||
41 | return __ioremap(offset, size); | 58 | return __ioremap(offset, size); |
42 | } | 59 | } |
43 | EXPORT_SYMBOL(ioremap_nocache); | 60 | EXPORT_SYMBOL(ioremap_nocache); |