[ARM] Clean up ioremap code

Since we're keeping the ioremap code, we might as well keep it as
close to the standard kernel as possible.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by Russell King and committed by Russell King da2c12a2 ad1ae2fe

+40 -58
+40 -58
arch/arm/mm/ioremap.c
··· 38 */ 39 #define VM_ARM_SECTION_MAPPING 0x80000000 40 41 - static inline void 42 - remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, 43 - unsigned long phys_addr, pgprot_t prot) 44 { 45 - unsigned long end; 46 47 - address &= ~PMD_MASK; 48 - end = address + size; 49 - if (end > PMD_SIZE) 50 - end = PMD_SIZE; 51 - BUG_ON(address >= end); 52 do { 53 if (!pte_none(*pte)) 54 goto bad; 55 56 set_pte_ext(pte, pfn_pte(phys_addr >> PAGE_SHIFT, prot), 0); 57 - address += PAGE_SIZE; 58 phys_addr += PAGE_SIZE; 59 - pte++; 60 - } while (address && (address < end)); 61 - return; 62 63 bad: 64 - printk("remap_area_pte: page already exists\n"); 65 BUG(); 66 } 67 68 - static inline int 69 - remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, 70 - unsigned long phys_addr, unsigned long flags) 71 { 72 - unsigned long end; 73 - pgprot_t pgprot; 74 75 - address &= ~PGDIR_MASK; 76 - end = address + size; 77 78 - if (end > PGDIR_SIZE) 79 - end = PGDIR_SIZE; 80 - 81 - phys_addr -= address; 82 - BUG_ON(address >= end); 83 - 84 - pgprot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | flags); 85 do { 86 - pte_t * pte = pte_alloc_kernel(pmd, address); 87 - if (!pte) 88 - return -ENOMEM; 89 - remap_area_pte(pte, address, end - address, address + phys_addr, pgprot); 90 - address = (address + PMD_SIZE) & PMD_MASK; 91 - pmd++; 92 - } while (address && (address < end)); 93 - return 0; 94 } 95 96 - static int 97 - remap_area_pages(unsigned long start, unsigned long pfn, 98 - unsigned long size, unsigned long flags) 99 { 100 - unsigned long address = start; 101 - unsigned long end = start + size; 102 unsigned long phys_addr = __pfn_to_phys(pfn); 103 int err = 0; 104 - pgd_t * dir; 105 106 - phys_addr -= address; 107 - dir = pgd_offset(&init_mm, address); 108 - BUG_ON(address >= end); 109 do { 110 - pmd_t *pmd = pmd_alloc(&init_mm, dir, address); 111 - if (!pmd) { 112 - err = -ENOMEM; 113 break; 114 - } 115 - if (remap_area_pmd(pmd, address, end - address, 116 - phys_addr + address, flags)) { 117 - err = -ENOMEM; 118 - break; 119 - } 120 - 121 - address = (address + PGDIR_SIZE) & PGDIR_MASK; 122 - dir++; 123 - } while (address && (address < end)); 124 125 return err; 126 }
··· 38 */ 39 #define VM_ARM_SECTION_MAPPING 0x80000000 40 41 + static int remap_area_pte(pmd_t *pmd, unsigned long addr, unsigned long end, 42 + unsigned long phys_addr, pgprot_t prot) 43 { 44 + pte_t *pte; 45 46 + pte = pte_alloc_kernel(pmd, addr); 47 + if (!pte) 48 + return -ENOMEM; 49 + 50 do { 51 if (!pte_none(*pte)) 52 goto bad; 53 54 set_pte_ext(pte, pfn_pte(phys_addr >> PAGE_SHIFT, prot), 0); 55 phys_addr += PAGE_SIZE; 56 + } while (pte++, addr += PAGE_SIZE, addr != end); 57 + return 0; 58 59 bad: 60 + printk(KERN_CRIT "remap_area_pte: page already exists\n"); 61 BUG(); 62 } 63 64 + static inline int remap_area_pmd(pgd_t *pgd, unsigned long addr, 65 + unsigned long end, unsigned long phys_addr, 66 + pgprot_t prot) 67 { 68 + unsigned long next; 69 + pmd_t *pmd; 70 + int ret = 0; 71 72 + pmd = pmd_alloc(&init_mm, pgd, addr); 73 + if (!pmd) 74 + return -ENOMEM; 75 76 do { 77 + next = pmd_addr_end(addr, end); 78 + ret = remap_area_pte(pmd, addr, next, phys_addr, prot); 79 + if (ret) 80 + return ret; 81 + phys_addr += next - addr; 82 + } while (pmd++, addr = next, addr != end); 83 + return ret; 84 } 85 86 + static int remap_area_pages(unsigned long start, unsigned long pfn, 87 + unsigned long size, unsigned long flags) 88 { 89 + unsigned long addr = start; 90 + unsigned long next, end = start + size; 91 unsigned long phys_addr = __pfn_to_phys(pfn); 92 + pgprot_t prot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | 93 + L_PTE_DIRTY | L_PTE_WRITE | flags); 94 + pgd_t *pgd; 95 int err = 0; 96 97 + BUG_ON(addr >= end); 98 + pgd = pgd_offset_k(addr); 99 do { 100 + next = pgd_addr_end(addr, end); 101 + err = remap_area_pmd(pgd, addr, next, phys_addr, prot); 102 + if (err) 103 break; 104 + phys_addr += next - addr; 105 + } while (pgd++, addr = next, addr != end); 106 107 return err; 108 }