Merge tag 'r8169-20060920-00' of git://electric-eye.fr.zoreil.com/home/romieu/linux...
[pandora-kernel.git] / arch / ia64 / mm / ioremap.c
index 643ccc6..4280c07 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/efi.h>
 #include <asm/io.h>
+#include <asm/meminit.h>
 
 static inline void __iomem *
 __ioremap (unsigned long offset, unsigned long size)
@@ -21,16 +22,29 @@ __ioremap (unsigned long offset, unsigned long size)
 void __iomem *
 ioremap (unsigned long offset, unsigned long size)
 {
-       if (efi_mem_attribute_range(offset, size, EFI_MEMORY_WB))
-               return phys_to_virt(offset);
+       u64 attr;
+       unsigned long gran_base, gran_size;
 
-       if (efi_mem_attribute_range(offset, size, EFI_MEMORY_UC))
+       /*
+        * For things in kern_memmap, we must use the same attribute
+        * as the rest of the kernel.  For more details, see
+        * Documentation/ia64/aliasing.txt.
+        */
+       attr = kern_mem_attribute(offset, size);
+       if (attr & EFI_MEMORY_WB)
+               return (void __iomem *) phys_to_virt(offset);
+       else if (attr & EFI_MEMORY_UC)
                return __ioremap(offset, size);
 
        /*
-        * Someday this should check ACPI resources so we
-        * can do the right thing for hot-plugged regions.
+        * Some chipsets don't support UC access to memory.  If
+        * WB is supported for the whole granule, we prefer that.
         */
+       gran_base = GRANULEROUNDDOWN(offset);
+       gran_size = GRANULEROUNDUP(offset + size) - gran_base;
+       if (efi_mem_attribute(gran_base, gran_size) & EFI_MEMORY_WB)
+               return (void __iomem *) phys_to_virt(offset);
+
        return __ioremap(offset, size);
 }
 EXPORT_SYMBOL(ioremap);
@@ -38,6 +52,9 @@ EXPORT_SYMBOL(ioremap);
 void __iomem *
 ioremap_nocache (unsigned long offset, unsigned long size)
 {
+       if (kern_mem_attribute(offset, size) & EFI_MEMORY_WB)
+               return NULL;
+
        return __ioremap(offset, size);
 }
 EXPORT_SYMBOL(ioremap_nocache);