Commit 19188f5a authored by Russell King's avatar Russell King

[ARM] Update ioremap implementation.

Use flush_cache_vmap() after creating mappings.  Also use BUG_ON()
rather than if() BUG().
parent cac923d2
......@@ -28,8 +28,9 @@
#include <asm/io.h>
#include <asm/tlbflush.h>
static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
unsigned long phys_addr, pgprot_t pgprot)
static inline void
remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
unsigned long phys_addr, pgprot_t pgprot)
{
unsigned long end;
......@@ -37,22 +38,26 @@ static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned l
end = address + size;
if (end > PMD_SIZE)
end = PMD_SIZE;
if (address >= end)
BUG();
BUG_ON(address >= end);
do {
if (!pte_none(*pte)) {
printk("remap_area_pte: page already exists\n");
BUG();
}
if (!pte_none(*pte))
goto bad;
set_pte(pte, pfn_pte(phys_addr >> PAGE_SHIFT, pgprot));
address += PAGE_SIZE;
phys_addr += PAGE_SIZE;
pte++;
} while (address && (address < end));
return;
bad:
printk("remap_area_pte: page already exists\n");
BUG();
}
static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
unsigned long phys_addr, unsigned long flags)
static inline int
remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
unsigned long phys_addr, unsigned long flags)
{
unsigned long end;
pgprot_t pgprot;
......@@ -64,8 +69,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo
end = PGDIR_SIZE;
phys_addr -= address;
if (address >= end)
BUG();
BUG_ON(address >= end);
pgprot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | flags);
do {
......@@ -79,35 +83,38 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo
return 0;
}
static int remap_area_pages(unsigned long address, unsigned long phys_addr,
unsigned long size, unsigned long flags)
static int
remap_area_pages(unsigned long start, unsigned long phys_addr,
unsigned long size, unsigned long flags)
{
int error;
unsigned long address = start;
unsigned long end = start + size;
int err = 0;
pgd_t * dir;
unsigned long end = address + size;
phys_addr -= address;
dir = pgd_offset(&init_mm, address);
flush_cache_all();
if (address >= end)
BUG();
BUG_ON(address >= end);
spin_lock(&init_mm.page_table_lock);
do {
pmd_t *pmd;
pmd = pmd_alloc(&init_mm, dir, address);
error = -ENOMEM;
if (!pmd)
pmd_t *pmd = pmd_alloc(&init_mm, dir, address);
if (!pmd) {
err = -ENOMEM;
break;
}
if (remap_area_pmd(pmd, address, end - address,
phys_addr + address, flags))
phys_addr + address, flags)) {
err = -ENOMEM;
break;
error = 0;
}
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
spin_unlock(&init_mm.page_table_lock);
flush_tlb_all();
return error;
flush_cache_vmap(start, end);
return err;
}
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment