diff options
Diffstat (limited to 'arch/cris/mm/ioremap.c')
-rw-r--r-- | arch/cris/mm/ioremap.c | 58 |
1 files changed, 42 insertions, 16 deletions
diff --git a/arch/cris/mm/ioremap.c b/arch/cris/mm/ioremap.c index 6b9130bfb6c..ebba11e270f 100644 --- a/arch/cris/mm/ioremap.c +++ b/arch/cris/mm/ioremap.c | |||
@@ -14,9 +14,10 @@ | |||
14 | #include <asm/pgalloc.h> | 14 | #include <asm/pgalloc.h> |
15 | #include <asm/cacheflush.h> | 15 | #include <asm/cacheflush.h> |
16 | #include <asm/tlbflush.h> | 16 | #include <asm/tlbflush.h> |
17 | #include <asm/arch/memmap.h> | ||
17 | 18 | ||
18 | extern inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, | 19 | extern inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, |
19 | unsigned long phys_addr, unsigned long flags) | 20 | unsigned long phys_addr, pgprot_t prot) |
20 | { | 21 | { |
21 | unsigned long end; | 22 | unsigned long end; |
22 | 23 | ||
@@ -31,9 +32,7 @@ extern inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned l | |||
31 | printk("remap_area_pte: page already exists\n"); | 32 | printk("remap_area_pte: page already exists\n"); |
32 | BUG(); | 33 | BUG(); |
33 | } | 34 | } |
34 | set_pte(pte, mk_pte_phys(phys_addr, __pgprot(_PAGE_PRESENT | __READABLE | | 35 | set_pte(pte, mk_pte_phys(phys_addr, prot)); |
35 | __WRITEABLE | _PAGE_GLOBAL | | ||
36 | _PAGE_KERNEL | flags))); | ||
37 | address += PAGE_SIZE; | 36 | address += PAGE_SIZE; |
38 | phys_addr += PAGE_SIZE; | 37 | phys_addr += PAGE_SIZE; |
39 | pte++; | 38 | pte++; |
@@ -41,7 +40,7 @@ extern inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned l | |||
41 | } | 40 | } |
42 | 41 | ||
43 | static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, | 42 | static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, |
44 | unsigned long phys_addr, unsigned long flags) | 43 | unsigned long phys_addr, pgprot_t prot) |
45 | { | 44 | { |
46 | unsigned long end; | 45 | unsigned long end; |
47 | 46 | ||
@@ -56,7 +55,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo | |||
56 | pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address); | 55 | pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address); |
57 | if (!pte) | 56 | if (!pte) |
58 | return -ENOMEM; | 57 | return -ENOMEM; |
59 | remap_area_pte(pte, address, end - address, address + phys_addr, flags); | 58 | remap_area_pte(pte, address, end - address, address + phys_addr, prot); |
60 | address = (address + PMD_SIZE) & PMD_MASK; | 59 | address = (address + PMD_SIZE) & PMD_MASK; |
61 | pmd++; | 60 | pmd++; |
62 | } while (address && (address < end)); | 61 | } while (address && (address < end)); |
@@ -64,7 +63,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo | |||
64 | } | 63 | } |
65 | 64 | ||
66 | static int remap_area_pages(unsigned long address, unsigned long phys_addr, | 65 | static int remap_area_pages(unsigned long address, unsigned long phys_addr, |
67 | unsigned long size, unsigned long flags) | 66 | unsigned long size, pgprot_t prot) |
68 | { | 67 | { |
69 | int error; | 68 | int error; |
70 | pgd_t * dir; | 69 | pgd_t * dir; |
@@ -77,13 +76,19 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr, | |||
77 | BUG(); | 76 | BUG(); |
78 | spin_lock(&init_mm.page_table_lock); | 77 | spin_lock(&init_mm.page_table_lock); |
79 | do { | 78 | do { |
79 | pud_t *pud; | ||
80 | pmd_t *pmd; | 80 | pmd_t *pmd; |
81 | pmd = pmd_alloc(&init_mm, dir, address); | 81 | |
82 | error = -ENOMEM; | 82 | error = -ENOMEM; |
83 | pud = pud_alloc(&init_mm, dir, address); | ||
84 | if (!pud) | ||
85 | break; | ||
86 | pmd = pmd_alloc(&init_mm, pud, address); | ||
87 | |||
83 | if (!pmd) | 88 | if (!pmd) |
84 | break; | 89 | break; |
85 | if (remap_area_pmd(pmd, address, end - address, | 90 | if (remap_area_pmd(pmd, address, end - address, |
86 | phys_addr + address, flags)) | 91 | phys_addr + address, prot)) |
87 | break; | 92 | break; |
88 | error = 0; | 93 | error = 0; |
89 | address = (address + PGDIR_SIZE) & PGDIR_MASK; | 94 | address = (address + PGDIR_SIZE) & PGDIR_MASK; |
@@ -107,9 +112,9 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr, | |||
107 | * have to convert them into an offset in a page-aligned mapping, but the | 112 | * have to convert them into an offset in a page-aligned mapping, but the |
108 | * caller shouldn't need to know that small detail. | 113 | * caller shouldn't need to know that small detail. |
109 | */ | 114 | */ |
110 | void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) | 115 | void __iomem * __ioremap_prot(unsigned long phys_addr, unsigned long size, pgprot_t prot) |
111 | { | 116 | { |
112 | void * addr; | 117 | void __iomem * addr; |
113 | struct vm_struct * area; | 118 | struct vm_struct * area; |
114 | unsigned long offset, last_addr; | 119 | unsigned long offset, last_addr; |
115 | 120 | ||
@@ -131,15 +136,36 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag | |||
131 | area = get_vm_area(size, VM_IOREMAP); | 136 | area = get_vm_area(size, VM_IOREMAP); |
132 | if (!area) | 137 | if (!area) |
133 | return NULL; | 138 | return NULL; |
134 | addr = area->addr; | 139 | addr = (void __iomem *)area->addr; |
135 | if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) { | 140 | if (remap_area_pages((unsigned long) addr, phys_addr, size, prot)) { |
136 | vfree(addr); | 141 | vfree((void __force *)addr); |
137 | return NULL; | 142 | return NULL; |
138 | } | 143 | } |
139 | return (void *) (offset + (char *)addr); | 144 | return (void __iomem *) (offset + (char __iomem *)addr); |
145 | } | ||
146 | |||
147 | void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) | ||
148 | { | ||
149 | return __ioremap_prot(phys_addr, size, | ||
150 | __pgprot(_PAGE_PRESENT | __READABLE | | ||
151 | __WRITEABLE | _PAGE_GLOBAL | | ||
152 | _PAGE_KERNEL | flags)); | ||
153 | } | ||
154 | |||
155 | /** | ||
156 | * ioremap_nocache - map bus memory into CPU space | ||
157 | * @offset: bus address of the memory | ||
158 | * @size: size of the resource to map | ||
159 | * | ||
160 | * Must be freed with iounmap. | ||
161 | */ | ||
162 | |||
163 | void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size) | ||
164 | { | ||
165 | return __ioremap(phys_addr | MEM_NON_CACHEABLE, size, 0); | ||
140 | } | 166 | } |
141 | 167 | ||
142 | void iounmap(void *addr) | 168 | void iounmap(volatile void __iomem *addr) |
143 | { | 169 | { |
144 | if (addr > high_memory) | 170 | if (addr > high_memory) |
145 | return vfree((void *) (PAGE_MASK & (unsigned long) addr)); | 171 | return vfree((void *) (PAGE_MASK & (unsigned long) addr)); |