aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris/mm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/cris/mm')
-rw-r--r--arch/cris/mm/ioremap.c88
1 files changed, 3 insertions, 85 deletions
diff --git a/arch/cris/mm/ioremap.c b/arch/cris/mm/ioremap.c
index 1780df3ed9e5..8b0b9348b574 100644
--- a/arch/cris/mm/ioremap.c
+++ b/arch/cris/mm/ioremap.c
@@ -10,93 +10,10 @@
10 */ 10 */
11 11
12#include <linux/vmalloc.h> 12#include <linux/vmalloc.h>
13#include <asm/io.h> 13#include <linux/io.h>
14#include <asm/pgalloc.h> 14#include <asm/pgalloc.h>
15#include <asm/cacheflush.h>
16#include <asm/tlbflush.h>
17#include <asm/arch/memmap.h> 15#include <asm/arch/memmap.h>
18 16
19static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
20 unsigned long phys_addr, pgprot_t prot)
21{
22 unsigned long end;
23
24 address &= ~PMD_MASK;
25 end = address + size;
26 if (end > PMD_SIZE)
27 end = PMD_SIZE;
28 if (address >= end)
29 BUG();
30 do {
31 if (!pte_none(*pte)) {
32 printk("remap_area_pte: page already exists\n");
33 BUG();
34 }
35 set_pte(pte, mk_pte_phys(phys_addr, prot));
36 address += PAGE_SIZE;
37 phys_addr += PAGE_SIZE;
38 pte++;
39 } while (address && (address < end));
40}
41
42static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
43 unsigned long phys_addr, pgprot_t prot)
44{
45 unsigned long end;
46
47 address &= ~PGDIR_MASK;
48 end = address + size;
49 if (end > PGDIR_SIZE)
50 end = PGDIR_SIZE;
51 phys_addr -= address;
52 if (address >= end)
53 BUG();
54 do {
55 pte_t * pte = pte_alloc_kernel(pmd, address);
56 if (!pte)
57 return -ENOMEM;
58 remap_area_pte(pte, address, end - address, address + phys_addr, prot);
59 address = (address + PMD_SIZE) & PMD_MASK;
60 pmd++;
61 } while (address && (address < end));
62 return 0;
63}
64
65static int remap_area_pages(unsigned long address, unsigned long phys_addr,
66 unsigned long size, pgprot_t prot)
67{
68 int error;
69 pgd_t * dir;
70 unsigned long end = address + size;
71
72 phys_addr -= address;
73 dir = pgd_offset(&init_mm, address);
74 flush_cache_all();
75 if (address >= end)
76 BUG();
77 do {
78 pud_t *pud;
79 pmd_t *pmd;
80
81 error = -ENOMEM;
82 pud = pud_alloc(&init_mm, dir, address);
83 if (!pud)
84 break;
85 pmd = pmd_alloc(&init_mm, pud, address);
86
87 if (!pmd)
88 break;
89 if (remap_area_pmd(pmd, address, end - address,
90 phys_addr + address, prot))
91 break;
92 error = 0;
93 address = (address + PGDIR_SIZE) & PGDIR_MASK;
94 dir++;
95 } while (address && (address < end));
96 flush_tlb_all();
97 return error;
98}
99
100/* 17/*
101 * Generic mapping function (not visible outside): 18 * Generic mapping function (not visible outside):
102 */ 19 */
@@ -135,7 +52,8 @@ void __iomem * __ioremap_prot(unsigned long phys_addr, unsigned long size, pgpro
135 if (!area) 52 if (!area)
136 return NULL; 53 return NULL;
137 addr = (void __iomem *)area->addr; 54 addr = (void __iomem *)area->addr;
138 if (remap_area_pages((unsigned long) addr, phys_addr, size, prot)) { 55 if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
56 phys_addr, prot)) {
139 vfree((void __force *)addr); 57 vfree((void __force *)addr);
140 return NULL; 58 return NULL;
141 } 59 }