aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHaavard Skinnemoen <hskinnemoen@atmel.com>2006-10-01 02:29:15 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-01 03:39:31 -0400
commit801f92ad5a0c630646f6746f3ed1663fcab185d1 (patch)
tree4e8250fc77717c50e2d58a224545299489b98eb9
parentdb71daabad0821996483dfe309c4bc81d6755a70 (diff)
[PATCH] Generic ioremap_page_range: alpha conversion
Convert Alpha to use generic ioremap_page_range() by turning __alpha_remap_area_pages() into an inline wrapper around ioremap_page_range(). Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com> Cc: Richard Henderson <rth@twiddle.net> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/alpha/kernel/proto.h15
-rw-r--r--arch/alpha/mm/Makefile2
-rw-r--r--arch/alpha/mm/remap.c86
3 files changed, 13 insertions, 90 deletions
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
index 2a6e3da8144f..21f71287b6f5 100644
--- a/arch/alpha/kernel/proto.h
+++ b/arch/alpha/kernel/proto.h
@@ -1,5 +1,7 @@
1#include <linux/interrupt.h> 1#include <linux/interrupt.h>
2#include <linux/io.h>
2 3
4#include <asm/pgtable.h>
3 5
4/* Prototypes of functions used across modules here in this directory. */ 6/* Prototypes of functions used across modules here in this directory. */
5 7
@@ -181,9 +183,16 @@ extern void titan_dispatch_irqs(u64, struct pt_regs *);
181extern void switch_to_system_map(void); 183extern void switch_to_system_map(void);
182extern void srm_paging_stop(void); 184extern void srm_paging_stop(void);
183 185
184/* ../mm/remap.c */ 186static inline int
185extern int __alpha_remap_area_pages(unsigned long, unsigned long, 187__alpha_remap_area_pages(unsigned long address, unsigned long phys_addr,
186 unsigned long, unsigned long); 188 unsigned long size, unsigned long flags)
189{
190 pgprot_t prot;
191
192 prot = __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE
193 | _PAGE_KWE | flags);
194 return ioremap_page_range(address, address + size, phys_addr, prot);
195}
187 196
188/* irq.c */ 197/* irq.c */
189 198
diff --git a/arch/alpha/mm/Makefile b/arch/alpha/mm/Makefile
index 6edd9a09ea4f..09399c5386cb 100644
--- a/arch/alpha/mm/Makefile
+++ b/arch/alpha/mm/Makefile
@@ -4,6 +4,6 @@
4 4
5EXTRA_CFLAGS := -Werror 5EXTRA_CFLAGS := -Werror
6 6
7obj-y := init.o fault.o extable.o remap.o 7obj-y := init.o fault.o extable.o
8 8
9obj-$(CONFIG_DISCONTIGMEM) += numa.o 9obj-$(CONFIG_DISCONTIGMEM) += numa.o
diff --git a/arch/alpha/mm/remap.c b/arch/alpha/mm/remap.c
deleted file mode 100644
index a78356c3ead5..000000000000
--- a/arch/alpha/mm/remap.c
+++ /dev/null
@@ -1,86 +0,0 @@
1#include <linux/vmalloc.h>
2#include <asm/pgalloc.h>
3#include <asm/cacheflush.h>
4
5static inline void
6remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
7 unsigned long phys_addr, unsigned long flags)
8{
9 unsigned long end;
10 unsigned long pfn;
11
12 address &= ~PMD_MASK;
13 end = address + size;
14 if (end > PMD_SIZE)
15 end = PMD_SIZE;
16 if (address >= end)
17 BUG();
18 pfn = phys_addr >> PAGE_SHIFT;
19 do {
20 if (!pte_none(*pte)) {
21 printk("remap_area_pte: page already exists\n");
22 BUG();
23 }
24 set_pte(pte, pfn_pte(pfn,
25 __pgprot(_PAGE_VALID | _PAGE_ASM |
26 _PAGE_KRE | _PAGE_KWE | flags)));
27 address += PAGE_SIZE;
28 pfn++;
29 pte++;
30 } while (address && (address < end));
31}
32
33static inline int
34remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
35 unsigned long phys_addr, unsigned long flags)
36{
37 unsigned long end;
38
39 address &= ~PGDIR_MASK;
40 end = address + size;
41 if (end > PGDIR_SIZE)
42 end = PGDIR_SIZE;
43 phys_addr -= address;
44 if (address >= end)
45 BUG();
46 do {
47 pte_t * pte = pte_alloc_kernel(pmd, address);
48 if (!pte)
49 return -ENOMEM;
50 remap_area_pte(pte, address, end - address,
51 address + phys_addr, flags);
52 address = (address + PMD_SIZE) & PMD_MASK;
53 pmd++;
54 } while (address && (address < end));
55 return 0;
56}
57
58int
59__alpha_remap_area_pages(unsigned long address, unsigned long phys_addr,
60 unsigned long size, unsigned long flags)
61{
62 pgd_t * dir;
63 int error = 0;
64 unsigned long end = address + size;
65
66 phys_addr -= address;
67 dir = pgd_offset(&init_mm, address);
68 flush_cache_all();
69 if (address >= end)
70 BUG();
71 do {
72 pmd_t *pmd;
73 pmd = pmd_alloc(&init_mm, dir, address);
74 error = -ENOMEM;
75 if (!pmd)
76 break;
77 if (remap_area_pmd(pmd, address, end - address,
78 phys_addr + address, flags))
79 break;
80 error = 0;
81 address = (address + PGDIR_SIZE) & PGDIR_MASK;
82 dir++;
83 } while (address && (address < end));
84 return error;
85}
86