diff options
Diffstat (limited to 'arch/cris/mm/ioremap.c')
-rw-r--r-- | arch/cris/mm/ioremap.c | 88 |
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 | ||
19 | static 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 | |||
42 | static 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 | |||
65 | static 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 | } |