mm: HUGE_VMAP arch support cleanup
[linux-2.6-microblaze.git] / mm / ioremap.c
index 3f4d36f..3264d02 100644 (file)
 #include "pgalloc-track.h"
 
 #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP
-static int __read_mostly ioremap_p4d_capable;
-static int __read_mostly ioremap_pud_capable;
-static int __read_mostly ioremap_pmd_capable;
-static int __read_mostly ioremap_huge_disabled;
+static bool __ro_after_init iomap_max_page_shift = PAGE_SHIFT;
 
 static int __init set_nohugeiomap(char *str)
 {
-       ioremap_huge_disabled = 1;
+       iomap_max_page_shift = P4D_SHIFT;
        return 0;
 }
 early_param("nohugeiomap", set_nohugeiomap);
-
-void __init ioremap_huge_init(void)
-{
-       if (!ioremap_huge_disabled) {
-               if (arch_ioremap_p4d_supported())
-                       ioremap_p4d_capable = 1;
-               if (arch_ioremap_pud_supported())
-                       ioremap_pud_capable = 1;
-               if (arch_ioremap_pmd_supported())
-                       ioremap_pmd_capable = 1;
-       }
-}
-
-static inline int ioremap_p4d_enabled(void)
-{
-       return ioremap_p4d_capable;
-}
-
-static inline int ioremap_pud_enabled(void)
-{
-       return ioremap_pud_capable;
-}
-
-static inline int ioremap_pmd_enabled(void)
-{
-       return ioremap_pmd_capable;
-}
-
-#else  /* !CONFIG_HAVE_ARCH_HUGE_VMAP */
-static inline int ioremap_p4d_enabled(void) { return 0; }
-static inline int ioremap_pud_enabled(void) { return 0; }
-static inline int ioremap_pmd_enabled(void) { return 0; }
+#else /* CONFIG_HAVE_ARCH_HUGE_VMAP */
+static const bool iomap_max_page_shift = PAGE_SHIFT;
 #endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */
 
 static int vmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
@@ -82,9 +49,13 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
 }
 
 static int vmap_try_huge_pmd(pmd_t *pmd, unsigned long addr, unsigned long end,
-                       phys_addr_t phys_addr, pgprot_t prot)
+                       phys_addr_t phys_addr, pgprot_t prot,
+                       unsigned int max_page_shift)
 {
-       if (!ioremap_pmd_enabled())
+       if (max_page_shift < PMD_SHIFT)
+               return 0;
+
+       if (!arch_vmap_pmd_supported(prot))
                return 0;
 
        if ((end - addr) != PMD_SIZE)
@@ -104,7 +75,7 @@ static int vmap_try_huge_pmd(pmd_t *pmd, unsigned long addr, unsigned long end,
 
 static int vmap_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
                        phys_addr_t phys_addr, pgprot_t prot,
-                       pgtbl_mod_mask *mask)
+                       unsigned int max_page_shift, pgtbl_mod_mask *mask)
 {
        pmd_t *pmd;
        unsigned long next;
@@ -115,7 +86,8 @@ static int vmap_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
        do {
                next = pmd_addr_end(addr, end);
 
-               if (vmap_try_huge_pmd(pmd, addr, next, phys_addr, prot)) {
+               if (vmap_try_huge_pmd(pmd, addr, next, phys_addr, prot,
+                                       max_page_shift)) {
                        *mask |= PGTBL_PMD_MODIFIED;
                        continue;
                }
@@ -127,9 +99,13 @@ static int vmap_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
 }
 
 static int vmap_try_huge_pud(pud_t *pud, unsigned long addr, unsigned long end,
-                       phys_addr_t phys_addr, pgprot_t prot)
+                       phys_addr_t phys_addr, pgprot_t prot,
+                       unsigned int max_page_shift)
 {
-       if (!ioremap_pud_enabled())
+       if (max_page_shift < PUD_SHIFT)
+               return 0;
+
+       if (!arch_vmap_pud_supported(prot))
                return 0;
 
        if ((end - addr) != PUD_SIZE)
@@ -149,7 +125,7 @@ static int vmap_try_huge_pud(pud_t *pud, unsigned long addr, unsigned long end,
 
 static int vmap_pud_range(p4d_t *p4d, unsigned long addr, unsigned long end,
                        phys_addr_t phys_addr, pgprot_t prot,
-                       pgtbl_mod_mask *mask)
+                       unsigned int max_page_shift, pgtbl_mod_mask *mask)
 {
        pud_t *pud;
        unsigned long next;
@@ -160,21 +136,27 @@ static int vmap_pud_range(p4d_t *p4d, unsigned long addr, unsigned long end,
        do {
                next = pud_addr_end(addr, end);
 
-               if (vmap_try_huge_pud(pud, addr, next, phys_addr, prot)) {
+               if (vmap_try_huge_pud(pud, addr, next, phys_addr, prot,
+                                       max_page_shift)) {
                        *mask |= PGTBL_PUD_MODIFIED;
                        continue;
                }
 
-               if (vmap_pmd_range(pud, addr, next, phys_addr, prot, mask))
+               if (vmap_pmd_range(pud, addr, next, phys_addr, prot,
+                                       max_page_shift, mask))
                        return -ENOMEM;
        } while (pud++, phys_addr += (next - addr), addr = next, addr != end);
        return 0;
 }
 
 static int vmap_try_huge_p4d(p4d_t *p4d, unsigned long addr, unsigned long end,
-                       phys_addr_t phys_addr, pgprot_t prot)
+                       phys_addr_t phys_addr, pgprot_t prot,
+                       unsigned int max_page_shift)
 {
-       if (!ioremap_p4d_enabled())
+       if (max_page_shift < P4D_SHIFT)
+               return 0;
+
+       if (!arch_vmap_p4d_supported(prot))
                return 0;
 
        if ((end - addr) != P4D_SIZE)
@@ -194,7 +176,7 @@ static int vmap_try_huge_p4d(p4d_t *p4d, unsigned long addr, unsigned long end,
 
 static int vmap_p4d_range(pgd_t *pgd, unsigned long addr, unsigned long end,
                        phys_addr_t phys_addr, pgprot_t prot,
-                       pgtbl_mod_mask *mask)
+                       unsigned int max_page_shift, pgtbl_mod_mask *mask)
 {
        p4d_t *p4d;
        unsigned long next;
@@ -205,19 +187,22 @@ static int vmap_p4d_range(pgd_t *pgd, unsigned long addr, unsigned long end,
        do {
                next = p4d_addr_end(addr, end);
 
-               if (vmap_try_huge_p4d(p4d, addr, next, phys_addr, prot)) {
+               if (vmap_try_huge_p4d(p4d, addr, next, phys_addr, prot,
+                                       max_page_shift)) {
                        *mask |= PGTBL_P4D_MODIFIED;
                        continue;
                }
 
-               if (vmap_pud_range(p4d, addr, next, phys_addr, prot, mask))
+               if (vmap_pud_range(p4d, addr, next, phys_addr, prot,
+                                       max_page_shift, mask))
                        return -ENOMEM;
        } while (p4d++, phys_addr += (next - addr), addr = next, addr != end);
        return 0;
 }
 
 static int vmap_range(unsigned long addr, unsigned long end,
-                       phys_addr_t phys_addr, pgprot_t prot)
+                       phys_addr_t phys_addr, pgprot_t prot,
+                       unsigned int max_page_shift)
 {
        pgd_t *pgd;
        unsigned long start;
@@ -232,7 +217,8 @@ static int vmap_range(unsigned long addr, unsigned long end,
        pgd = pgd_offset_k(addr);
        do {
                next = pgd_addr_end(addr, end);
-               err = vmap_p4d_range(pgd, addr, next, phys_addr, prot, &mask);
+               err = vmap_p4d_range(pgd, addr, next, phys_addr, prot,
+                                       max_page_shift, &mask);
                if (err)
                        break;
        } while (pgd++, phys_addr += (next - addr), addr = next, addr != end);
@@ -248,7 +234,7 @@ static int vmap_range(unsigned long addr, unsigned long end,
 int ioremap_page_range(unsigned long addr,
                       unsigned long end, phys_addr_t phys_addr, pgprot_t prot)
 {
-       return vmap_range(addr, end, phys_addr, prot);
+       return vmap_range(addr, end, phys_addr, prot, iomap_max_page_shift);
 }
 
 #ifdef CONFIG_GENERIC_IOREMAP