Loading arch/avr32/mm/ioremap.c +6 −114 Original line number Diff line number Diff line Loading @@ -7,119 +7,11 @@ */ #include <linux/vmalloc.h> #include <linux/module.h> #include <linux/io.h> #include <asm/io.h> #include <asm/pgtable.h> #include <asm/cacheflush.h> #include <asm/tlbflush.h> #include <asm/addrspace.h> static inline int remap_area_pte(pte_t *pte, unsigned long address, unsigned long end, unsigned long phys_addr, pgprot_t prot) { unsigned long pfn; pfn = phys_addr >> PAGE_SHIFT; do { WARN_ON(!pte_none(*pte)); set_pte(pte, pfn_pte(pfn, prot)); address += PAGE_SIZE; pfn++; pte++; } while (address && (address < end)); return 0; } static inline int remap_area_pmd(pmd_t *pmd, unsigned long address, unsigned long end, unsigned long phys_addr, pgprot_t prot) { unsigned long next; phys_addr -= address; do { pte_t *pte = pte_alloc_kernel(pmd, address); if (!pte) return -ENOMEM; next = (address + PMD_SIZE) & PMD_MASK; if (remap_area_pte(pte, address, next, address + phys_addr, prot)) return -ENOMEM; address = next; pmd++; } while (address && (address < end)); return 0; } static int remap_area_pud(pud_t *pud, unsigned long address, unsigned long end, unsigned long phys_addr, pgprot_t prot) { unsigned long next; phys_addr -= address; do { pmd_t *pmd = pmd_alloc(&init_mm, pud, address); if (!pmd) return -ENOMEM; next = (address + PUD_SIZE) & PUD_MASK; if (remap_area_pmd(pmd, address, next, phys_addr + address, prot)) return -ENOMEM; address = next; pud++; } while (address && address < end); return 0; } static int remap_area_pages(unsigned long address, unsigned long phys_addr, size_t size, pgprot_t prot) { unsigned long end = address + size; unsigned long next; pgd_t *pgd; int err = 0; phys_addr -= address; pgd = pgd_offset_k(address); flush_cache_all(); BUG_ON(address >= end); spin_lock(&init_mm.page_table_lock); do { pud_t *pud = pud_alloc(&init_mm, pgd, address); err = -ENOMEM; if (!pud) break; next = (address + PGDIR_SIZE) & PGDIR_MASK; if (next < address || next > end) next = end; err = remap_area_pud(pud, address, next, phys_addr + address, prot); if (err) break; address = next; pgd++; } while (address && (address < end)); spin_unlock(&init_mm.page_table_lock); flush_tlb_all(); return err; } /* * Re-map an arbitrary physical address space into the kernel virtual * address space. Needed when the kernel wants to access physical Loading @@ -128,7 +20,7 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr, void __iomem *__ioremap(unsigned long phys_addr, size_t size, unsigned long flags) { void *addr; unsigned long addr; struct vm_struct *area; unsigned long offset, last_addr; pgprot_t prot; Loading Loading @@ -159,7 +51,7 @@ void __iomem *__ioremap(unsigned long phys_addr, size_t size, phys_addr &= PAGE_MASK; size = PAGE_ALIGN(last_addr + 1) - phys_addr; prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY prot = __pgprot(_PAGE_PRESENT | _PAGE_GLOBAL | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_TYPE_SMALL | flags); /* Loading @@ -169,9 +61,9 @@ void __iomem *__ioremap(unsigned long phys_addr, size_t size, if (!area) return NULL; area->phys_addr = phys_addr; addr = area->addr; if (remap_area_pages((unsigned long)addr, phys_addr, size, prot)) { vunmap(addr); addr = (unsigned long )area->addr; if (ioremap_page_range(addr, addr + size, phys_addr, prot)) { vunmap((void *)addr); return NULL; } Loading Loading
arch/avr32/mm/ioremap.c +6 −114 Original line number Diff line number Diff line Loading @@ -7,119 +7,11 @@ */ #include <linux/vmalloc.h> #include <linux/module.h> #include <linux/io.h> #include <asm/io.h> #include <asm/pgtable.h> #include <asm/cacheflush.h> #include <asm/tlbflush.h> #include <asm/addrspace.h> static inline int remap_area_pte(pte_t *pte, unsigned long address, unsigned long end, unsigned long phys_addr, pgprot_t prot) { unsigned long pfn; pfn = phys_addr >> PAGE_SHIFT; do { WARN_ON(!pte_none(*pte)); set_pte(pte, pfn_pte(pfn, prot)); address += PAGE_SIZE; pfn++; pte++; } while (address && (address < end)); return 0; } static inline int remap_area_pmd(pmd_t *pmd, unsigned long address, unsigned long end, unsigned long phys_addr, pgprot_t prot) { unsigned long next; phys_addr -= address; do { pte_t *pte = pte_alloc_kernel(pmd, address); if (!pte) return -ENOMEM; next = (address + PMD_SIZE) & PMD_MASK; if (remap_area_pte(pte, address, next, address + phys_addr, prot)) return -ENOMEM; address = next; pmd++; } while (address && (address < end)); return 0; } static int remap_area_pud(pud_t *pud, unsigned long address, unsigned long end, unsigned long phys_addr, pgprot_t prot) { unsigned long next; phys_addr -= address; do { pmd_t *pmd = pmd_alloc(&init_mm, pud, address); if (!pmd) return -ENOMEM; next = (address + PUD_SIZE) & PUD_MASK; if (remap_area_pmd(pmd, address, next, phys_addr + address, prot)) return -ENOMEM; address = next; pud++; } while (address && address < end); return 0; } static int remap_area_pages(unsigned long address, unsigned long phys_addr, size_t size, pgprot_t prot) { unsigned long end = address + size; unsigned long next; pgd_t *pgd; int err = 0; phys_addr -= address; pgd = pgd_offset_k(address); flush_cache_all(); BUG_ON(address >= end); spin_lock(&init_mm.page_table_lock); do { pud_t *pud = pud_alloc(&init_mm, pgd, address); err = -ENOMEM; if (!pud) break; next = (address + PGDIR_SIZE) & PGDIR_MASK; if (next < address || next > end) next = end; err = remap_area_pud(pud, address, next, phys_addr + address, prot); if (err) break; address = next; pgd++; } while (address && (address < end)); spin_unlock(&init_mm.page_table_lock); flush_tlb_all(); return err; } /* * Re-map an arbitrary physical address space into the kernel virtual * address space. Needed when the kernel wants to access physical Loading @@ -128,7 +20,7 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr, void __iomem *__ioremap(unsigned long phys_addr, size_t size, unsigned long flags) { void *addr; unsigned long addr; struct vm_struct *area; unsigned long offset, last_addr; pgprot_t prot; Loading Loading @@ -159,7 +51,7 @@ void __iomem *__ioremap(unsigned long phys_addr, size_t size, phys_addr &= PAGE_MASK; size = PAGE_ALIGN(last_addr + 1) - phys_addr; prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY prot = __pgprot(_PAGE_PRESENT | _PAGE_GLOBAL | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_TYPE_SMALL | flags); /* Loading @@ -169,9 +61,9 @@ void __iomem *__ioremap(unsigned long phys_addr, size_t size, if (!area) return NULL; area->phys_addr = phys_addr; addr = area->addr; if (remap_area_pages((unsigned long)addr, phys_addr, size, prot)) { vunmap(addr); addr = (unsigned long )area->addr; if (ioremap_page_range(addr, addr + size, phys_addr, prot)) { vunmap((void *)addr); return NULL; } Loading