aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm/ioremap.c
diff options
context:
space:
mode:
authorHaavard Skinnemoen <hskinnemoen@atmel.com>2006-12-08 05:38:04 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-08 11:28:52 -0500
commit8e087929df884dbb13e383d49d192bdd6928ecbf (patch)
tree5075bb300ff6f90682b48bb14d92d2c766fa5154 /arch/mips/mm/ioremap.c
parent62dfb5541a025b47df9405ff0219c7829a97d83b (diff)
[PATCH] Generic ioremap_page_range: mips conversion
Convert MIPS to use generic ioremap_page_range() [yoichi_yuasa@tripeaks.co.jp: build fix] Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com> Cc: Ralf Baechle <ralf@linux-mips.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/mips/mm/ioremap.c')
-rw-r--r--arch/mips/mm/ioremap.c96
1 files changed, 8 insertions, 88 deletions
diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c
index cea7d0ea36e4..fc2c96f0a1fd 100644
--- a/arch/mips/mm/ioremap.c
+++ b/arch/mips/mm/ioremap.c
@@ -6,98 +6,13 @@
6 * (C) Copyright 1995 1996 Linus Torvalds 6 * (C) Copyright 1995 1996 Linus Torvalds
7 * (C) Copyright 2001, 2002 Ralf Baechle 7 * (C) Copyright 2001, 2002 Ralf Baechle
8 */ 8 */
9#include <linux/mm.h>
9#include <linux/module.h> 10#include <linux/module.h>
10#include <asm/addrspace.h> 11#include <asm/addrspace.h>
11#include <asm/byteorder.h> 12#include <asm/byteorder.h>
12 13
13#include <linux/vmalloc.h> 14#include <linux/vmalloc.h>
14#include <asm/cacheflush.h> 15#include <linux/io.h>
15#include <asm/io.h>
16#include <asm/tlbflush.h>
17
18static inline void remap_area_pte(pte_t * pte, unsigned long address,
19 phys_t size, phys_t phys_addr, unsigned long flags)
20{
21 phys_t end;
22 unsigned long pfn;
23 pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE
24 | __WRITEABLE | flags);
25
26 address &= ~PMD_MASK;
27 end = address + size;
28 if (end > PMD_SIZE)
29 end = PMD_SIZE;
30 if (address >= end)
31 BUG();
32 pfn = phys_addr >> PAGE_SHIFT;
33 do {
34 if (!pte_none(*pte)) {
35 printk("remap_area_pte: page already exists\n");
36 BUG();
37 }
38 set_pte(pte, pfn_pte(pfn, pgprot));
39 address += PAGE_SIZE;
40 pfn++;
41 pte++;
42 } while (address && (address < end));
43}
44
45static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
46 phys_t size, phys_t phys_addr, unsigned long flags)
47{
48 phys_t end;
49
50 address &= ~PGDIR_MASK;
51 end = address + size;
52 if (end > PGDIR_SIZE)
53 end = PGDIR_SIZE;
54 phys_addr -= address;
55 if (address >= end)
56 BUG();
57 do {
58 pte_t * pte = pte_alloc_kernel(pmd, address);
59 if (!pte)
60 return -ENOMEM;
61 remap_area_pte(pte, address, end - address, address + phys_addr, flags);
62 address = (address + PMD_SIZE) & PMD_MASK;
63 pmd++;
64 } while (address && (address < end));
65 return 0;
66}
67
68static int remap_area_pages(unsigned long address, phys_t phys_addr,
69 phys_t size, unsigned long flags)
70{
71 int error;
72 pgd_t * dir;
73 unsigned long end = address + size;
74
75 phys_addr -= address;
76 dir = pgd_offset(&init_mm, address);
77 flush_cache_all();
78 if (address >= end)
79 BUG();
80 do {
81 pud_t *pud;
82 pmd_t *pmd;
83
84 error = -ENOMEM;
85 pud = pud_alloc(&init_mm, dir, address);
86 if (!pud)
87 break;
88 pmd = pmd_alloc(&init_mm, pud, address);
89 if (!pmd)
90 break;
91 if (remap_area_pmd(pmd, address, end - address,
92 phys_addr + address, flags))
93 break;
94 error = 0;
95 address = (address + PGDIR_SIZE) & PGDIR_MASK;
96 dir++;
97 } while (address && (address < end));
98 flush_tlb_all();
99 return error;
100}
101 16
102/* 17/*
103 * Generic mapping function (not visible outside): 18 * Generic mapping function (not visible outside):
@@ -121,6 +36,7 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
121 unsigned long offset; 36 unsigned long offset;
122 phys_t last_addr; 37 phys_t last_addr;
123 void * addr; 38 void * addr;
39 pgprot_t pgprot;
124 40
125 phys_addr = fixup_bigphys_addr(phys_addr, size); 41 phys_addr = fixup_bigphys_addr(phys_addr, size);
126 42
@@ -152,6 +68,9 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
152 return NULL; 68 return NULL;
153 } 69 }
154 70
71 pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE
72 | __WRITEABLE | flags);
73
155 /* 74 /*
156 * Mappings have to be page-aligned 75 * Mappings have to be page-aligned
157 */ 76 */
@@ -166,7 +85,8 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
166 if (!area) 85 if (!area)
167 return NULL; 86 return NULL;
168 addr = area->addr; 87 addr = area->addr;
169 if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) { 88 if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
89 phys_addr, pgprot)) {
170 vunmap(addr); 90 vunmap(addr);
171 return NULL; 91 return NULL;
172 } 92 }