Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b29e9f5e64fb90d2e4be1c7ef8c925b56669c74a
Commit:     b29e9f5e64fb90d2e4be1c7ef8c925b56669c74a
Parent:     24e6c6996fb6e0e716c1dda1def1bb023a0fe43b
Author:     Russell King <[EMAIL PROTECTED]>
AuthorDate: Sat Apr 21 10:47:29 2007 +0100
Committer:  Russell King <[EMAIL PROTECTED]>
CommitDate: Sat Apr 21 20:36:00 2007 +0100

    [ARM] mm 5: Use mem_types table in ioremap
    
    We really want to be using the memory type table in ioremap, so we
    only have to do the CPU type fixups in one place.
    
    Signed-off-by: Russell King <[EMAIL PROTECTED]>
---
 arch/arm/mm/ioremap.c |   65 ++++++++++++++++++++----------------------------
 arch/arm/mm/mm.h      |    9 +++++++
 arch/arm/mm/mmu.c     |   14 ++++------
 3 files changed, 42 insertions(+), 46 deletions(-)

diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 800855b..b26b361 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -32,6 +32,9 @@
 #include <asm/tlbflush.h>
 #include <asm/sizes.h>
 
+#include <asm/mach/map.h>
+#include "mm.h"
+
 /*
  * Used by ioremap() and iounmap() code to mark (super)section-mapped
  * I/O regions in vm_struct->flags field.
@@ -39,8 +42,9 @@
 #define VM_ARM_SECTION_MAPPING 0x80000000
 
 static int remap_area_pte(pmd_t *pmd, unsigned long addr, unsigned long end,
-                         unsigned long phys_addr, pgprot_t prot)
+                         unsigned long phys_addr, const struct mem_type *type)
 {
+       pgprot_t prot = __pgprot(type->prot_pte);
        pte_t *pte;
 
        pte = pte_alloc_kernel(pmd, addr);
@@ -63,7 +67,7 @@ static int remap_area_pte(pmd_t *pmd, unsigned long addr, 
unsigned long end,
 
 static inline int remap_area_pmd(pgd_t *pgd, unsigned long addr,
                                 unsigned long end, unsigned long phys_addr,
-                                pgprot_t prot)
+                                const struct mem_type *type)
 {
        unsigned long next;
        pmd_t *pmd;
@@ -75,7 +79,7 @@ static inline int remap_area_pmd(pgd_t *pgd, unsigned long 
addr,
 
        do {
                next = pmd_addr_end(addr, end);
-               ret = remap_area_pte(pmd, addr, next, phys_addr, prot);
+               ret = remap_area_pte(pmd, addr, next, phys_addr, type);
                if (ret)
                        return ret;
                phys_addr += next - addr;
@@ -84,13 +88,11 @@ static inline int remap_area_pmd(pgd_t *pgd, unsigned long 
addr,
 }
 
 static int remap_area_pages(unsigned long start, unsigned long pfn,
-                           unsigned long size, unsigned long flags)
+                           size_t size, const struct mem_type *type)
 {
        unsigned long addr = start;
        unsigned long next, end = start + size;
        unsigned long phys_addr = __pfn_to_phys(pfn);
-       pgprot_t prot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
-                                L_PTE_DIRTY | L_PTE_WRITE | flags);
        pgd_t *pgd;
        int err = 0;
 
@@ -98,7 +100,7 @@ static int remap_area_pages(unsigned long start, unsigned 
long pfn,
        pgd = pgd_offset_k(addr);
        do {
                next = pgd_addr_end(addr, end);
-               err = remap_area_pmd(pgd, addr, next, phys_addr, prot);
+               err = remap_area_pmd(pgd, addr, next, phys_addr, type);
                if (err)
                        break;
                phys_addr += next - addr;
@@ -178,9 +180,9 @@ static void unmap_area_sections(unsigned long virt, 
unsigned long size)
 
 static int
 remap_area_sections(unsigned long virt, unsigned long pfn,
-                   unsigned long size, unsigned long flags)
+                   size_t size, const struct mem_type *type)
 {
-       unsigned long prot, addr = virt, end = virt + size;
+       unsigned long addr = virt, end = virt + size;
        pgd_t *pgd;
 
        /*
@@ -189,23 +191,13 @@ remap_area_sections(unsigned long virt, unsigned long pfn,
         */
        unmap_area_sections(virt, size);
 
-       prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_DOMAIN(DOMAIN_IO) |
-              (flags & (L_PTE_CACHEABLE | L_PTE_BUFFERABLE));
-
-       /*
-        * ARMv6 and above need XN set to prevent speculative prefetches
-        * hitting IO.
-        */
-       if (cpu_architecture() >= CPU_ARCH_ARMv6)
-               prot |= PMD_SECT_XN;
-
        pgd = pgd_offset_k(addr);
        do {
                pmd_t *pmd = pmd_offset(pgd, addr);
 
-               pmd[0] = __pmd(__pfn_to_phys(pfn) | prot);
+               pmd[0] = __pmd(__pfn_to_phys(pfn) | type->prot_sect);
                pfn += SZ_1M >> PAGE_SHIFT;
-               pmd[1] = __pmd(__pfn_to_phys(pfn) | prot);
+               pmd[1] = __pmd(__pfn_to_phys(pfn) | type->prot_sect);
                pfn += SZ_1M >> PAGE_SHIFT;
                flush_pmd_entry(pmd);
 
@@ -218,9 +210,9 @@ remap_area_sections(unsigned long virt, unsigned long pfn,
 
 static int
 remap_area_supersections(unsigned long virt, unsigned long pfn,
-                        unsigned long size, unsigned long flags)
+                        size_t size, const struct mem_type *type)
 {
-       unsigned long prot, addr = virt, end = virt + size;
+       unsigned long addr = virt, end = virt + size;
        pgd_t *pgd;
 
        /*
@@ -229,22 +221,12 @@ remap_area_supersections(unsigned long virt, unsigned 
long pfn,
         */
        unmap_area_sections(virt, size);
 
-       prot = PMD_TYPE_SECT | PMD_SECT_SUPER | PMD_SECT_AP_WRITE |
-                       PMD_DOMAIN(DOMAIN_IO) |
-                       (flags & (L_PTE_CACHEABLE | L_PTE_BUFFERABLE));
-
-       /*
-        * ARMv6 and above need XN set to prevent speculative prefetches
-        * hitting IO.
-        */
-       if (cpu_architecture() >= CPU_ARCH_ARMv6)
-               prot |= PMD_SECT_XN;
-
        pgd = pgd_offset_k(virt);
        do {
                unsigned long super_pmd_val, i;
 
-               super_pmd_val = __pfn_to_phys(pfn) | prot;
+               super_pmd_val = __pfn_to_phys(pfn) | type->prot_sect |
+                               PMD_SECT_SUPER;
                super_pmd_val |= ((pfn >> (32 - PAGE_SHIFT)) & 0xf) << 20;
 
                for (i = 0; i < 8; i++) {
@@ -282,6 +264,8 @@ void __iomem *
 __ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
              unsigned long flags)
 {
+       const struct mem_type *type;
+       struct mem_type t;
        int err;
        unsigned long addr;
        struct vm_struct * area;
@@ -292,6 +276,11 @@ __ioremap_pfn(unsigned long pfn, unsigned long offset, 
size_t size,
        if (pfn >= 0x100000 && (__pfn_to_phys(pfn) & ~SUPERSECTION_MASK))
                return NULL;
 
+       t = *get_mem_type(MT_DEVICE);
+       t.prot_sect |= flags;
+       t.prot_pte |= flags;
+       type = &t;
+
        size = PAGE_ALIGN(size);
 
        area = get_vm_area(size, VM_IOREMAP);
@@ -305,13 +294,13 @@ __ioremap_pfn(unsigned long pfn, unsigned long offset, 
size_t size,
               cpu_is_xsc3()) && pfn >= 0x100000 &&
               !((__pfn_to_phys(pfn) | size | addr) & ~SUPERSECTION_MASK)) {
                area->flags |= VM_ARM_SECTION_MAPPING;
-               err = remap_area_supersections(addr, pfn, size, flags);
+               err = remap_area_supersections(addr, pfn, size, type);
        } else if (!((__pfn_to_phys(pfn) | size | addr) & ~PMD_MASK)) {
                area->flags |= VM_ARM_SECTION_MAPPING;
-               err = remap_area_sections(addr, pfn, size, flags);
+               err = remap_area_sections(addr, pfn, size, type);
        } else
 #endif
-               err = remap_area_pages(addr, pfn, size, flags);
+               err = remap_area_pages(addr, pfn, size, type);
 
        if (err) {
                vunmap((void *)addr);
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index a44e309..66f8612 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -16,6 +16,15 @@ static inline pmd_t *pmd_off_k(unsigned long virt)
        return pmd_off(pgd_offset_k(virt), virt);
 }
 
+struct mem_type {
+       unsigned int prot_pte;
+       unsigned int prot_l1;
+       unsigned int prot_sect;
+       unsigned int domain;
+};
+
+const struct mem_type *get_mem_type(unsigned int type);
+
 #endif
 
 struct map_desc;
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 5821e67..6cb80b4 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -176,14 +176,7 @@ void adjust_cr(unsigned long mask, unsigned long set)
 }
 #endif
 
-struct mem_type {
-       unsigned int    prot_pte;
-       unsigned int    prot_l1;
-       unsigned int    prot_sect;
-       unsigned int    domain;
-};
-
-static struct mem_type mem_types[] __initdata = {
+static struct mem_type mem_types[] = {
        [MT_DEVICE] = {
                .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
                                L_PTE_WRITE,
@@ -237,6 +230,11 @@ static struct mem_type mem_types[] __initdata = {
        }
 };
 
+const struct mem_type *get_mem_type(unsigned int type)
+{
+       return type < ARRAY_SIZE(mem_types) ? &mem_types[type] : NULL;
+}
+
 /*
  * Adjust the PMD section entries according to the CPU in use.
  */
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to