Commit cb84c2b401d9cead5508cfed57b59b6d5feffdac

Authored by Guenter Roeck
Committed by Richard Kuo
1 parent b2776bf714

hexagon: Fix build failures in linux-next

hexagon:defconfig fails to build in linux-next since commit 332fd7c4fef5
("genirq: Generic chip: Change irq_reg_{readl,writel} arguments").

The primary build failure is

arch/hexagon/include/asm/cacheflush.h: In function 'copy_to_user_page':
arch/hexagon/include/asm/cacheflush.h:89:22: error: 'VM_EXEC' undeclared

This is the result of including of <linux/io.h> from <linux/irq.h>,
which is now necessary due to the use of readl and writel from irq.h.
This causes recursive inclusions in hexagon code; cacheflush.h is included
from mm.h prior to the definition of VM_EXEC.

Fix the problem by moving copy_to_user_page from the hexagon include file to
arch/hexagon/mm/cache.c, similar to other architectures. After this change,
several redefinitions of readl and writel are reported. Those are caused
by recursive inclusions of io.h and asm/cacheflush.h. Fix those problems by
reducing the number of files included from those files. Also, it was necessary
to stop including asm-generic/cacheflush.h from asm/cacheflush.h. Instead,
functionality originally provided by asm-generic/cacheflush.h is now coded
in asm/cacheflush.h directly.

Cc: Kevin Cernekee <cernekee@gmail.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
signed-off-by: Richard Kuo <rkuo@codeaurora.org>

Showing 5 changed files with 31 additions and 22 deletions Inline Diff

arch/hexagon/include/asm/cacheflush.h
1 /* 1 /*
2 * Cache flush operations for the Hexagon architecture 2 * Cache flush operations for the Hexagon architecture
3 * 3 *
4 * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 and 7 * it under the terms of the GNU General Public License version 2 and
8 * only version 2 as published by the Free Software Foundation. 8 * only version 2 as published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA. 18 * 02110-1301, USA.
19 */ 19 */
20 20
21 #ifndef _ASM_CACHEFLUSH_H 21 #ifndef _ASM_CACHEFLUSH_H
22 #define _ASM_CACHEFLUSH_H 22 #define _ASM_CACHEFLUSH_H
23 23
24 #include <linux/cache.h> 24 #include <linux/mm_types.h>
25 #include <linux/mm.h>
26 #include <asm/string.h>
27 #include <asm-generic/cacheflush.h>
28 25
29 /* Cache flushing: 26 /* Cache flushing:
30 * 27 *
31 * - flush_cache_all() flushes entire cache 28 * - flush_cache_all() flushes entire cache
32 * - flush_cache_mm(mm) flushes the specified mm context's cache lines 29 * - flush_cache_mm(mm) flushes the specified mm context's cache lines
33 * - flush_cache_page(mm, vmaddr, pfn) flushes a single page 30 * - flush_cache_page(mm, vmaddr, pfn) flushes a single page
34 * - flush_cache_range(vma, start, end) flushes a range of pages 31 * - flush_cache_range(vma, start, end) flushes a range of pages
35 * - flush_icache_range(start, end) flush a range of instructions 32 * - flush_icache_range(start, end) flush a range of instructions
36 * - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache 33 * - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache
37 * - flush_icache_page(vma, pg) flushes(invalidates) a page for icache 34 * - flush_icache_page(vma, pg) flushes(invalidates) a page for icache
38 * 35 *
39 * Need to doublecheck which one is really needed for ptrace stuff to work. 36 * Need to doublecheck which one is really needed for ptrace stuff to work.
40 */ 37 */
41 #define LINESIZE 32 38 #define LINESIZE 32
42 #define LINEBITS 5 39 #define LINEBITS 5
43 40
41 #define flush_cache_all() do { } while (0)
42 #define flush_cache_mm(mm) do { } while (0)
43 #define flush_cache_dup_mm(mm) do { } while (0)
44 #define flush_cache_range(vma, start, end) do { } while (0)
45 #define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
46 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
47 #define flush_dcache_page(page) do { } while (0)
48 #define flush_dcache_mmap_lock(mapping) do { } while (0)
49 #define flush_dcache_mmap_unlock(mapping) do { } while (0)
50 #define flush_icache_page(vma, pg) do { } while (0)
51 #define flush_icache_user_range(vma, pg, adr, len) do { } while (0)
52 #define flush_cache_vmap(start, end) do { } while (0)
53 #define flush_cache_vunmap(start, end) do { } while (0)
54
44 /* 55 /*
45 * Flush Dcache range through current map. 56 * Flush Dcache range through current map.
46 */ 57 */
47 extern void flush_dcache_range(unsigned long start, unsigned long end); 58 extern void flush_dcache_range(unsigned long start, unsigned long end);
48 59
49 /* 60 /*
50 * Flush Icache range through current map. 61 * Flush Icache range through current map.
51 */ 62 */
52 #undef flush_icache_range
53 extern void flush_icache_range(unsigned long start, unsigned long end); 63 extern void flush_icache_range(unsigned long start, unsigned long end);
54 64
55 /* 65 /*
56 * Memory-management related flushes are there to ensure in non-physically 66 * Memory-management related flushes are there to ensure in non-physically
57 * indexed cache schemes that stale lines belonging to a given ASID aren't 67 * indexed cache schemes that stale lines belonging to a given ASID aren't
58 * in the cache to confuse things. The prototype Hexagon Virtual Machine 68 * in the cache to confuse things. The prototype Hexagon Virtual Machine
59 * only uses a single ASID for all user-mode maps, which should 69 * only uses a single ASID for all user-mode maps, which should
60 * mean that they aren't necessary. A brute-force, flush-everything 70 * mean that they aren't necessary. A brute-force, flush-everything
61 * implementation, with the name xxxxx_hexagon() is present in 71 * implementation, with the name xxxxx_hexagon() is present in
62 * arch/hexagon/mm/cache.c, but let's not wire it up until we know 72 * arch/hexagon/mm/cache.c, but let's not wire it up until we know
63 * it is needed. 73 * it is needed.
64 */ 74 */
65 extern void flush_cache_all_hexagon(void); 75 extern void flush_cache_all_hexagon(void);
66 76
67 /* 77 /*
68 * This may or may not ever have to be non-null, depending on the 78 * This may or may not ever have to be non-null, depending on the
69 * virtual machine MMU. For a native kernel, it's definitiely a no-op 79 * virtual machine MMU. For a native kernel, it's definitiely a no-op
70 * 80 *
71 * This is also the place where deferred cache coherency stuff seems 81 * This is also the place where deferred cache coherency stuff seems
72 * to happen, classically... but instead we do it like ia64 and 82 * to happen, classically... but instead we do it like ia64 and
73 * clean the cache when the PTE is set. 83 * clean the cache when the PTE is set.
74 * 84 *
75 */ 85 */
76 static inline void update_mmu_cache(struct vm_area_struct *vma, 86 static inline void update_mmu_cache(struct vm_area_struct *vma,
77 unsigned long address, pte_t *ptep) 87 unsigned long address, pte_t *ptep)
78 { 88 {
79 /* generic_ptrace_pokedata doesn't wind up here, does it? */ 89 /* generic_ptrace_pokedata doesn't wind up here, does it? */
80 } 90 }
81 91
82 #undef copy_to_user_page 92 void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
83 static inline void copy_to_user_page(struct vm_area_struct *vma, 93 unsigned long vaddr, void *dst, void *src, int len);
84 struct page *page,
85 unsigned long vaddr,
86 void *dst, void *src, int len)
87 {
88 memcpy(dst, src, len);
arch/hexagon/include/asm/io.h
1 /* 1 /*
2 * IO definitions for the Hexagon architecture 2 * IO definitions for the Hexagon architecture
3 * 3 *
4 * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 and 7 * it under the terms of the GNU General Public License version 2 and
8 * only version 2 as published by the Free Software Foundation. 8 * only version 2 as published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA. 18 * 02110-1301, USA.
19 */ 19 */
20 20
21 #ifndef _ASM_IO_H 21 #ifndef _ASM_IO_H
22 #define _ASM_IO_H 22 #define _ASM_IO_H
23 23
24 #ifdef __KERNEL__ 24 #ifdef __KERNEL__
25 25
26 #include <linux/types.h> 26 #include <linux/types.h>
27 #include <linux/delay.h>
28 #include <linux/vmalloc.h>
29 #include <asm/string.h>
30 #include <asm/mem-layout.h>
31 #include <asm/iomap.h> 27 #include <asm/iomap.h>
32 #include <asm/page.h> 28 #include <asm/page.h>
33 #include <asm/cacheflush.h> 29 #include <asm/cacheflush.h>
34 #include <asm/tlbflush.h>
35 30
36 /* 31 /*
37 * We don't have PCI yet. 32 * We don't have PCI yet.
38 * _IO_BASE is pointing at what should be unused virtual space. 33 * _IO_BASE is pointing at what should be unused virtual space.
39 */ 34 */
40 #define IO_SPACE_LIMIT 0xffff 35 #define IO_SPACE_LIMIT 0xffff
41 #define _IO_BASE ((void __iomem *)0xfe000000) 36 #define _IO_BASE ((void __iomem *)0xfe000000)
42 37
43 #define IOMEM(x) ((void __force __iomem *)(x)) 38 #define IOMEM(x) ((void __force __iomem *)(x))
44 39
45 extern int remap_area_pages(unsigned long start, unsigned long phys_addr, 40 extern int remap_area_pages(unsigned long start, unsigned long phys_addr,
46 unsigned long end, unsigned long flags); 41 unsigned long end, unsigned long flags);
47 42
48 extern void __iounmap(const volatile void __iomem *addr); 43 extern void __iounmap(const volatile void __iomem *addr);
49 44
50 /* Defined in lib/io.c, needed for smc91x driver. */ 45 /* Defined in lib/io.c, needed for smc91x driver. */
51 extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen); 46 extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen);
52 extern void __raw_writesw(void __iomem *addr, const void *data, int wordlen); 47 extern void __raw_writesw(void __iomem *addr, const void *data, int wordlen);
53 48
54 extern void __raw_readsl(const void __iomem *addr, void *data, int wordlen); 49 extern void __raw_readsl(const void __iomem *addr, void *data, int wordlen);
55 extern void __raw_writesl(void __iomem *addr, const void *data, int wordlen); 50 extern void __raw_writesl(void __iomem *addr, const void *data, int wordlen);
56 51
57 #define readsw(p, d, l) __raw_readsw(p, d, l) 52 #define readsw(p, d, l) __raw_readsw(p, d, l)
58 #define writesw(p, d, l) __raw_writesw(p, d, l) 53 #define writesw(p, d, l) __raw_writesw(p, d, l)
59 54
60 #define readsl(p, d, l) __raw_readsl(p, d, l) 55 #define readsl(p, d, l) __raw_readsl(p, d, l)
61 #define writesl(p, d, l) __raw_writesl(p, d, l) 56 #define writesl(p, d, l) __raw_writesl(p, d, l)
62 57
63 /* 58 /*
64 * virt_to_phys - map virtual address to physical 59 * virt_to_phys - map virtual address to physical
65 * @address: address to map 60 * @address: address to map
66 */ 61 */
67 static inline unsigned long virt_to_phys(volatile void *address) 62 static inline unsigned long virt_to_phys(volatile void *address)
68 { 63 {
69 return __pa(address); 64 return __pa(address);
70 } 65 }
71 66
72 /* 67 /*
73 * phys_to_virt - map physical address to virtual 68 * phys_to_virt - map physical address to virtual
74 * @address: address to map 69 * @address: address to map
75 */ 70 */
76 static inline void *phys_to_virt(unsigned long address) 71 static inline void *phys_to_virt(unsigned long address)
77 { 72 {
78 return __va(address); 73 return __va(address);
79 } 74 }
80 75
81 /* 76 /*
82 * convert a physical pointer to a virtual kernel pointer for 77 * convert a physical pointer to a virtual kernel pointer for
83 * /dev/mem access. 78 * /dev/mem access.
84 */ 79 */
85 #define xlate_dev_kmem_ptr(p) __va(p) 80 #define xlate_dev_kmem_ptr(p) __va(p)
86 #define xlate_dev_mem_ptr(p) __va(p) 81 #define xlate_dev_mem_ptr(p) __va(p)
87 82
88 /* 83 /*
89 * IO port access primitives. Hexagon doesn't have special IO access 84 * IO port access primitives. Hexagon doesn't have special IO access
90 * instructions; all I/O is memory mapped. 85 * instructions; all I/O is memory mapped.
91 * 86 *
92 * in/out are used for "ports", but we don't have "port instructions", 87 * in/out are used for "ports", but we don't have "port instructions",
93 * so these are really just memory mapped too. 88 * so these are really just memory mapped too.
94 */ 89 */
95 90
96 /* 91 /*
97 * readb - read byte from memory mapped device 92 * readb - read byte from memory mapped device
98 * @addr: pointer to memory 93 * @addr: pointer to memory
99 * 94 *
100 * Operates on "I/O bus memory space" 95 * Operates on "I/O bus memory space"
101 */ 96 */
102 static inline u8 readb(const volatile void __iomem *addr) 97 static inline u8 readb(const volatile void __iomem *addr)
103 { 98 {
104 u8 val; 99 u8 val;
105 asm volatile( 100 asm volatile(
106 "%0 = memb(%1);" 101 "%0 = memb(%1);"
107 : "=&r" (val) 102 : "=&r" (val)
108 : "r" (addr) 103 : "r" (addr)
109 ); 104 );
110 return val; 105 return val;
111 } 106 }
112 107
113 static inline u16 readw(const volatile void __iomem *addr) 108 static inline u16 readw(const volatile void __iomem *addr)
114 { 109 {
115 u16 val; 110 u16 val;
116 asm volatile( 111 asm volatile(
117 "%0 = memh(%1);" 112 "%0 = memh(%1);"
118 : "=&r" (val) 113 : "=&r" (val)
119 : "r" (addr) 114 : "r" (addr)
120 ); 115 );
121 return val; 116 return val;
122 } 117 }
123 118
124 static inline u32 readl(const volatile void __iomem *addr) 119 static inline u32 readl(const volatile void __iomem *addr)
125 { 120 {
126 u32 val; 121 u32 val;
127 asm volatile( 122 asm volatile(
128 "%0 = memw(%1);" 123 "%0 = memw(%1);"
129 : "=&r" (val) 124 : "=&r" (val)
130 : "r" (addr) 125 : "r" (addr)
131 ); 126 );
132 return val; 127 return val;
133 } 128 }
134 129
135 /* 130 /*
136 * writeb - write a byte to a memory location 131 * writeb - write a byte to a memory location
137 * @data: data to write to 132 * @data: data to write to
138 * @addr: pointer to memory 133 * @addr: pointer to memory
139 * 134 *
140 */ 135 */
141 static inline void writeb(u8 data, volatile void __iomem *addr) 136 static inline void writeb(u8 data, volatile void __iomem *addr)
142 { 137 {
143 asm volatile( 138 asm volatile(
144 "memb(%0) = %1;" 139 "memb(%0) = %1;"
145 : 140 :
146 : "r" (addr), "r" (data) 141 : "r" (addr), "r" (data)
147 : "memory" 142 : "memory"
148 ); 143 );
149 } 144 }
150 145
151 static inline void writew(u16 data, volatile void __iomem *addr) 146 static inline void writew(u16 data, volatile void __iomem *addr)
152 { 147 {
153 asm volatile( 148 asm volatile(
154 "memh(%0) = %1;" 149 "memh(%0) = %1;"
155 : 150 :
156 : "r" (addr), "r" (data) 151 : "r" (addr), "r" (data)
157 : "memory" 152 : "memory"
158 ); 153 );
159 154
160 } 155 }
161 156
162 static inline void writel(u32 data, volatile void __iomem *addr) 157 static inline void writel(u32 data, volatile void __iomem *addr)
163 { 158 {
164 asm volatile( 159 asm volatile(
165 "memw(%0) = %1;" 160 "memw(%0) = %1;"
166 : 161 :
167 : "r" (addr), "r" (data) 162 : "r" (addr), "r" (data)
168 : "memory" 163 : "memory"
169 ); 164 );
170 } 165 }
171 166
172 #define __raw_writeb writeb 167 #define __raw_writeb writeb
173 #define __raw_writew writew 168 #define __raw_writew writew
174 #define __raw_writel writel 169 #define __raw_writel writel
175 170
176 #define __raw_readb readb 171 #define __raw_readb readb
177 #define __raw_readw readw 172 #define __raw_readw readw
178 #define __raw_readl readl 173 #define __raw_readl readl
179 174
180 /* 175 /*
181 * http://comments.gmane.org/gmane.linux.ports.arm.kernel/117626 176 * http://comments.gmane.org/gmane.linux.ports.arm.kernel/117626
182 */ 177 */
183 178
184 #define readb_relaxed __raw_readb 179 #define readb_relaxed __raw_readb
185 #define readw_relaxed __raw_readw 180 #define readw_relaxed __raw_readw
186 #define readl_relaxed __raw_readl 181 #define readl_relaxed __raw_readl
187 182
188 #define writeb_relaxed __raw_writeb 183 #define writeb_relaxed __raw_writeb
189 #define writew_relaxed __raw_writew 184 #define writew_relaxed __raw_writew
190 #define writel_relaxed __raw_writel 185 #define writel_relaxed __raw_writel
191 186
192 #define mmiowb() 187 #define mmiowb()
193 188
194 /* 189 /*
195 * Need an mtype somewhere in here, for cache type deals? 190 * Need an mtype somewhere in here, for cache type deals?
196 * This is probably too long for an inline. 191 * This is probably too long for an inline.
197 */ 192 */
198 void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size); 193 void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size);
199 194
200 static inline void __iomem *ioremap(unsigned long phys_addr, unsigned long size) 195 static inline void __iomem *ioremap(unsigned long phys_addr, unsigned long size)
201 { 196 {
202 return ioremap_nocache(phys_addr, size); 197 return ioremap_nocache(phys_addr, size);
203 } 198 }
204 199
205 static inline void iounmap(volatile void __iomem *addr) 200 static inline void iounmap(volatile void __iomem *addr)
206 { 201 {
207 __iounmap(addr); 202 __iounmap(addr);
208 } 203 }
209 204
210 #define __raw_writel writel 205 #define __raw_writel writel
211 206
212 static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, 207 static inline void memcpy_fromio(void *dst, const volatile void __iomem *src,
213 int count) 208 int count)
214 { 209 {
215 memcpy(dst, (void *) src, count); 210 memcpy(dst, (void *) src, count);
216 } 211 }
217 212
218 static inline void memcpy_toio(volatile void __iomem *dst, const void *src, 213 static inline void memcpy_toio(volatile void __iomem *dst, const void *src,
219 int count) 214 int count)
220 { 215 {
221 memcpy((void *) dst, src, count); 216 memcpy((void *) dst, src, count);
222 } 217 }
223 218
224 #define PCI_IO_ADDR (volatile void __iomem *) 219 #define PCI_IO_ADDR (volatile void __iomem *)
225 220
226 /* 221 /*
227 * inb - read byte from I/O port or something 222 * inb - read byte from I/O port or something
228 * @port: address in I/O space 223 * @port: address in I/O space
229 * 224 *
230 * Operates on "I/O bus I/O space" 225 * Operates on "I/O bus I/O space"
231 */ 226 */
232 static inline u8 inb(unsigned long port) 227 static inline u8 inb(unsigned long port)
233 { 228 {
234 return readb(_IO_BASE + (port & IO_SPACE_LIMIT)); 229 return readb(_IO_BASE + (port & IO_SPACE_LIMIT));
235 } 230 }
236 231
237 static inline u16 inw(unsigned long port) 232 static inline u16 inw(unsigned long port)
238 { 233 {
239 return readw(_IO_BASE + (port & IO_SPACE_LIMIT)); 234 return readw(_IO_BASE + (port & IO_SPACE_LIMIT));
240 } 235 }
241 236
242 static inline u32 inl(unsigned long port) 237 static inline u32 inl(unsigned long port)
243 { 238 {
244 return readl(_IO_BASE + (port & IO_SPACE_LIMIT)); 239 return readl(_IO_BASE + (port & IO_SPACE_LIMIT));
245 } 240 }
246 241
247 /* 242 /*
248 * outb - write a byte to a memory location 243 * outb - write a byte to a memory location
249 * @data: data to write to 244 * @data: data to write to
250 * @addr: address in I/O space 245 * @addr: address in I/O space
251 */ 246 */
252 static inline void outb(u8 data, unsigned long port) 247 static inline void outb(u8 data, unsigned long port)
253 { 248 {
254 writeb(data, _IO_BASE + (port & IO_SPACE_LIMIT)); 249 writeb(data, _IO_BASE + (port & IO_SPACE_LIMIT));
255 } 250 }
256 251
257 static inline void outw(u16 data, unsigned long port) 252 static inline void outw(u16 data, unsigned long port)
258 { 253 {
259 writew(data, _IO_BASE + (port & IO_SPACE_LIMIT)); 254 writew(data, _IO_BASE + (port & IO_SPACE_LIMIT));
260 } 255 }
261 256
262 static inline void outl(u32 data, unsigned long port) 257 static inline void outl(u32 data, unsigned long port)
263 { 258 {
264 writel(data, _IO_BASE + (port & IO_SPACE_LIMIT)); 259 writel(data, _IO_BASE + (port & IO_SPACE_LIMIT));
265 } 260 }
266 261
267 #define outb_p outb 262 #define outb_p outb
268 #define outw_p outw 263 #define outw_p outw
269 #define outl_p outl 264 #define outl_p outl
270 265
271 #define inb_p inb 266 #define inb_p inb
272 #define inw_p inw 267 #define inw_p inw
273 #define inl_p inl 268 #define inl_p inl
274 269
275 static inline void insb(unsigned long port, void *buffer, int count) 270 static inline void insb(unsigned long port, void *buffer, int count)
276 { 271 {
277 if (count) { 272 if (count) {
278 u8 *buf = buffer; 273 u8 *buf = buffer;
279 do { 274 do {
280 u8 x = inb(port); 275 u8 x = inb(port);
281 *buf++ = x; 276 *buf++ = x;
282 } while (--count); 277 } while (--count);
283 } 278 }
284 } 279 }
285 280
286 static inline void insw(unsigned long port, void *buffer, int count) 281 static inline void insw(unsigned long port, void *buffer, int count)
287 { 282 {
288 if (count) { 283 if (count) {
289 u16 *buf = buffer; 284 u16 *buf = buffer;
290 do { 285 do {
291 u16 x = inw(port); 286 u16 x = inw(port);
292 *buf++ = x; 287 *buf++ = x;
293 } while (--count); 288 } while (--count);
294 } 289 }
295 } 290 }
296 291
297 static inline void insl(unsigned long port, void *buffer, int count) 292 static inline void insl(unsigned long port, void *buffer, int count)
298 { 293 {
299 if (count) { 294 if (count) {
300 u32 *buf = buffer; 295 u32 *buf = buffer;
301 do { 296 do {
302 u32 x = inw(port); 297 u32 x = inw(port);
303 *buf++ = x; 298 *buf++ = x;
304 } while (--count); 299 } while (--count);
305 } 300 }
306 } 301 }
307 302
308 static inline void outsb(unsigned long port, const void *buffer, int count) 303 static inline void outsb(unsigned long port, const void *buffer, int count)
309 { 304 {
310 if (count) { 305 if (count) {
311 const u8 *buf = buffer; 306 const u8 *buf = buffer;
312 do { 307 do {
313 outb(*buf++, port); 308 outb(*buf++, port);
314 } while (--count); 309 } while (--count);
315 } 310 }
316 } 311 }
317 312
318 static inline void outsw(unsigned long port, const void *buffer, int count) 313 static inline void outsw(unsigned long port, const void *buffer, int count)
319 { 314 {
320 if (count) { 315 if (count) {
321 const u16 *buf = buffer; 316 const u16 *buf = buffer;
322 do { 317 do {
323 outw(*buf++, port); 318 outw(*buf++, port);
324 } while (--count); 319 } while (--count);
325 } 320 }
326 } 321 }
327 322
328 static inline void outsl(unsigned long port, const void *buffer, int count) 323 static inline void outsl(unsigned long port, const void *buffer, int count)
329 { 324 {
330 if (count) { 325 if (count) {
331 const u32 *buf = buffer; 326 const u32 *buf = buffer;
332 do { 327 do {
333 outl(*buf++, port); 328 outl(*buf++, port);
334 } while (--count); 329 } while (--count);
335 } 330 }
336 } 331 }
337 332
338 #define flush_write_buffers() do { } while (0) 333 #define flush_write_buffers() do { } while (0)
339 334
340 #endif /* __KERNEL__ */ 335 #endif /* __KERNEL__ */
341 336
342 #endif 337 #endif
343 338
arch/hexagon/kernel/setup.c
1 /* 1 /*
2 * Arch related setup for Hexagon 2 * Arch related setup for Hexagon
3 * 3 *
4 * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 and 7 * it under the terms of the GNU General Public License version 2 and
8 * only version 2 as published by the Free Software Foundation. 8 * only version 2 as published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA. 18 * 02110-1301, USA.
19 */ 19 */
20 20
21 #include <linux/init.h> 21 #include <linux/init.h>
22 #include <linux/delay.h>
22 #include <linux/bootmem.h> 23 #include <linux/bootmem.h>
23 #include <linux/mmzone.h> 24 #include <linux/mmzone.h>
24 #include <linux/mm.h> 25 #include <linux/mm.h>
25 #include <linux/seq_file.h> 26 #include <linux/seq_file.h>
26 #include <linux/console.h> 27 #include <linux/console.h>
27 #include <linux/of_fdt.h> 28 #include <linux/of_fdt.h>
28 #include <asm/io.h> 29 #include <asm/io.h>
29 #include <asm/sections.h> 30 #include <asm/sections.h>
30 #include <asm/setup.h> 31 #include <asm/setup.h>
31 #include <asm/processor.h> 32 #include <asm/processor.h>
32 #include <asm/hexagon_vm.h> 33 #include <asm/hexagon_vm.h>
33 #include <asm/vm_mmu.h> 34 #include <asm/vm_mmu.h>
34 #include <asm/time.h> 35 #include <asm/time.h>
35 36
36 char cmd_line[COMMAND_LINE_SIZE]; 37 char cmd_line[COMMAND_LINE_SIZE];
37 static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; 38 static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
38 39
39 int on_simulator; 40 int on_simulator;
40 41
41 void calibrate_delay(void) 42 void calibrate_delay(void)
42 { 43 {
43 loops_per_jiffy = thread_freq_mhz * 1000000 / HZ; 44 loops_per_jiffy = thread_freq_mhz * 1000000 / HZ;
44 } 45 }
45 46
46 /* 47 /*
47 * setup_arch - high level architectural setup routine 48 * setup_arch - high level architectural setup routine
48 * @cmdline_p: pointer to pointer to command-line arguments 49 * @cmdline_p: pointer to pointer to command-line arguments
49 */ 50 */
50 51
51 void __init setup_arch(char **cmdline_p) 52 void __init setup_arch(char **cmdline_p)
52 { 53 {
53 char *p = &external_cmdline_buffer; 54 char *p = &external_cmdline_buffer;
54 55
55 /* 56 /*
56 * These will eventually be pulled in via either some hypervisor 57 * These will eventually be pulled in via either some hypervisor
57 * or devicetree description. Hardwiring for now. 58 * or devicetree description. Hardwiring for now.
58 */ 59 */
59 pcycle_freq_mhz = 600; 60 pcycle_freq_mhz = 600;
60 thread_freq_mhz = 100; 61 thread_freq_mhz = 100;
61 sleep_clk_freq = 32000; 62 sleep_clk_freq = 32000;
62 63
63 /* 64 /*
64 * Set up event bindings to handle exceptions and interrupts. 65 * Set up event bindings to handle exceptions and interrupts.
65 */ 66 */
66 __vmsetvec(_K_VM_event_vector); 67 __vmsetvec(_K_VM_event_vector);
67 68
68 printk(KERN_INFO "PHYS_OFFSET=0x%08x\n", PHYS_OFFSET); 69 printk(KERN_INFO "PHYS_OFFSET=0x%08x\n", PHYS_OFFSET);
69 70
70 /* 71 /*
71 * Simulator has a few differences from the hardware. 72 * Simulator has a few differences from the hardware.
72 * For now, check uninitialized-but-mapped memory 73 * For now, check uninitialized-but-mapped memory
73 * prior to invoking setup_arch_memory(). 74 * prior to invoking setup_arch_memory().
74 */ 75 */
75 if (*(int *)((unsigned long)_end + 8) == 0x1f1f1f1f) 76 if (*(int *)((unsigned long)_end + 8) == 0x1f1f1f1f)
76 on_simulator = 1; 77 on_simulator = 1;
77 else 78 else
78 on_simulator = 0; 79 on_simulator = 0;
79 80
80 if (p[0] != '\0') 81 if (p[0] != '\0')
81 strlcpy(boot_command_line, p, COMMAND_LINE_SIZE); 82 strlcpy(boot_command_line, p, COMMAND_LINE_SIZE);
82 else 83 else
83 strlcpy(boot_command_line, default_command_line, 84 strlcpy(boot_command_line, default_command_line,
84 COMMAND_LINE_SIZE); 85 COMMAND_LINE_SIZE);
85 86
86 /* 87 /*
87 * boot_command_line and the value set up by setup_arch 88 * boot_command_line and the value set up by setup_arch
88 * are both picked up by the init code. If no reason to 89 * are both picked up by the init code. If no reason to
89 * make them different, pass the same pointer back. 90 * make them different, pass the same pointer back.
90 */ 91 */
91 strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE); 92 strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
92 *cmdline_p = cmd_line; 93 *cmdline_p = cmd_line;
93 94
94 parse_early_param(); 95 parse_early_param();
95 96
96 setup_arch_memory(); 97 setup_arch_memory();
97 98
98 #ifdef CONFIG_SMP 99 #ifdef CONFIG_SMP
99 smp_start_cpus(); 100 smp_start_cpus();
100 #endif 101 #endif
101 } 102 }
102 103
103 /* 104 /*
104 * Functions for dumping CPU info via /proc 105 * Functions for dumping CPU info via /proc
105 * Probably should move to kernel/proc.c or something. 106 * Probably should move to kernel/proc.c or something.
106 */ 107 */
107 static void *c_start(struct seq_file *m, loff_t *pos) 108 static void *c_start(struct seq_file *m, loff_t *pos)
108 { 109 {
109 return *pos < nr_cpu_ids ? (void *)((unsigned long) *pos + 1) : NULL; 110 return *pos < nr_cpu_ids ? (void *)((unsigned long) *pos + 1) : NULL;
110 } 111 }
111 112
112 static void *c_next(struct seq_file *m, void *v, loff_t *pos) 113 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
113 { 114 {
114 ++*pos; 115 ++*pos;
115 return c_start(m, pos); 116 return c_start(m, pos);
116 } 117 }
117 118
118 static void c_stop(struct seq_file *m, void *v) 119 static void c_stop(struct seq_file *m, void *v)
119 { 120 {
120 } 121 }
121 122
122 /* 123 /*
123 * Eventually this will dump information about 124 * Eventually this will dump information about
124 * CPU properties like ISA level, TLB size, etc. 125 * CPU properties like ISA level, TLB size, etc.
125 */ 126 */
126 static int show_cpuinfo(struct seq_file *m, void *v) 127 static int show_cpuinfo(struct seq_file *m, void *v)
127 { 128 {
128 int cpu = (unsigned long) v - 1; 129 int cpu = (unsigned long) v - 1;
129 130
130 #ifdef CONFIG_SMP 131 #ifdef CONFIG_SMP
131 if (!cpu_online(cpu)) 132 if (!cpu_online(cpu))
132 return 0; 133 return 0;
133 #endif 134 #endif
134 135
135 seq_printf(m, "processor\t: %d\n", cpu); 136 seq_printf(m, "processor\t: %d\n", cpu);
136 seq_printf(m, "model name\t: Hexagon Virtual Machine\n"); 137 seq_printf(m, "model name\t: Hexagon Virtual Machine\n");
137 seq_printf(m, "BogoMips\t: %lu.%02lu\n", 138 seq_printf(m, "BogoMips\t: %lu.%02lu\n",
138 (loops_per_jiffy * HZ) / 500000, 139 (loops_per_jiffy * HZ) / 500000,
139 ((loops_per_jiffy * HZ) / 5000) % 100); 140 ((loops_per_jiffy * HZ) / 5000) % 100);
140 seq_printf(m, "\n"); 141 seq_printf(m, "\n");
141 return 0; 142 return 0;
142 } 143 }
143 144
144 const struct seq_operations cpuinfo_op = { 145 const struct seq_operations cpuinfo_op = {
145 .start = &c_start, 146 .start = &c_start,
146 .next = &c_next, 147 .next = &c_next,
147 .stop = &c_stop, 148 .stop = &c_stop,
148 .show = &show_cpuinfo, 149 .show = &show_cpuinfo,
149 }; 150 };
150 151
arch/hexagon/mm/cache.c
1 /* 1 /*
2 * Cache management functions for Hexagon 2 * Cache management functions for Hexagon
3 * 3 *
4 * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 and 7 * it under the terms of the GNU General Public License version 2 and
8 * only version 2 as published by the Free Software Foundation. 8 * only version 2 as published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA. 18 * 02110-1301, USA.
19 */ 19 */
20 20
21 #include <linux/mm.h> 21 #include <linux/mm.h>
22 #include <asm/cacheflush.h> 22 #include <asm/cacheflush.h>
23 #include <asm/hexagon_vm.h> 23 #include <asm/hexagon_vm.h>
24 24
25 #define spanlines(start, end) \ 25 #define spanlines(start, end) \
26 (((end - (start & ~(LINESIZE - 1))) >> LINEBITS) + 1) 26 (((end - (start & ~(LINESIZE - 1))) >> LINEBITS) + 1)
27 27
28 void flush_dcache_range(unsigned long start, unsigned long end) 28 void flush_dcache_range(unsigned long start, unsigned long end)
29 { 29 {
30 unsigned long lines = spanlines(start, end-1); 30 unsigned long lines = spanlines(start, end-1);
31 unsigned long i, flags; 31 unsigned long i, flags;
32 32
33 start &= ~(LINESIZE - 1); 33 start &= ~(LINESIZE - 1);
34 34
35 local_irq_save(flags); 35 local_irq_save(flags);
36 36
37 for (i = 0; i < lines; i++) { 37 for (i = 0; i < lines; i++) {
38 __asm__ __volatile__ ( 38 __asm__ __volatile__ (
39 " dccleaninva(%0); " 39 " dccleaninva(%0); "
40 : 40 :
41 : "r" (start) 41 : "r" (start)
42 ); 42 );
43 start += LINESIZE; 43 start += LINESIZE;
44 } 44 }
45 local_irq_restore(flags); 45 local_irq_restore(flags);
46 } 46 }
47 47
48 void flush_icache_range(unsigned long start, unsigned long end) 48 void flush_icache_range(unsigned long start, unsigned long end)
49 { 49 {
50 unsigned long lines = spanlines(start, end-1); 50 unsigned long lines = spanlines(start, end-1);
51 unsigned long i, flags; 51 unsigned long i, flags;
52 52
53 start &= ~(LINESIZE - 1); 53 start &= ~(LINESIZE - 1);
54 54
55 local_irq_save(flags); 55 local_irq_save(flags);
56 56
57 for (i = 0; i < lines; i++) { 57 for (i = 0; i < lines; i++) {
58 __asm__ __volatile__ ( 58 __asm__ __volatile__ (
59 " dccleana(%0); " 59 " dccleana(%0); "
60 " icinva(%0); " 60 " icinva(%0); "
61 : 61 :
62 : "r" (start) 62 : "r" (start)
63 ); 63 );
64 start += LINESIZE; 64 start += LINESIZE;
65 } 65 }
66 __asm__ __volatile__ ( 66 __asm__ __volatile__ (
67 "isync" 67 "isync"
68 ); 68 );
69 local_irq_restore(flags); 69 local_irq_restore(flags);
70 } 70 }
71 EXPORT_SYMBOL(flush_icache_range); 71 EXPORT_SYMBOL(flush_icache_range);
72 72
73 void hexagon_clean_dcache_range(unsigned long start, unsigned long end) 73 void hexagon_clean_dcache_range(unsigned long start, unsigned long end)
74 { 74 {
75 unsigned long lines = spanlines(start, end-1); 75 unsigned long lines = spanlines(start, end-1);
76 unsigned long i, flags; 76 unsigned long i, flags;
77 77
78 start &= ~(LINESIZE - 1); 78 start &= ~(LINESIZE - 1);
79 79
80 local_irq_save(flags); 80 local_irq_save(flags);
81 81
82 for (i = 0; i < lines; i++) { 82 for (i = 0; i < lines; i++) {
83 __asm__ __volatile__ ( 83 __asm__ __volatile__ (
84 " dccleana(%0); " 84 " dccleana(%0); "
85 : 85 :
86 : "r" (start) 86 : "r" (start)
87 ); 87 );
88 start += LINESIZE; 88 start += LINESIZE;
89 } 89 }
90 local_irq_restore(flags); 90 local_irq_restore(flags);
91 } 91 }
92 92
93 void hexagon_inv_dcache_range(unsigned long start, unsigned long end) 93 void hexagon_inv_dcache_range(unsigned long start, unsigned long end)
94 { 94 {
95 unsigned long lines = spanlines(start, end-1); 95 unsigned long lines = spanlines(start, end-1);
96 unsigned long i, flags; 96 unsigned long i, flags;
97 97
98 start &= ~(LINESIZE - 1); 98 start &= ~(LINESIZE - 1);
99 99
100 local_irq_save(flags); 100 local_irq_save(flags);
101 101
102 for (i = 0; i < lines; i++) { 102 for (i = 0; i < lines; i++) {
103 __asm__ __volatile__ ( 103 __asm__ __volatile__ (
104 " dcinva(%0); " 104 " dcinva(%0); "
105 : 105 :
106 : "r" (start) 106 : "r" (start)
107 ); 107 );
108 start += LINESIZE; 108 start += LINESIZE;
109 } 109 }
110 local_irq_restore(flags); 110 local_irq_restore(flags);
111 } 111 }
112 112
113 113
114 114
115 115
116 /* 116 /*
117 * This is just really brutal and shouldn't be used anyways, 117 * This is just really brutal and shouldn't be used anyways,
118 * especially on V2. Left here just in case. 118 * especially on V2. Left here just in case.
119 */ 119 */
120 void flush_cache_all_hexagon(void) 120 void flush_cache_all_hexagon(void)
121 { 121 {
122 unsigned long flags; 122 unsigned long flags;
123 local_irq_save(flags); 123 local_irq_save(flags);
124 __vmcache_ickill(); 124 __vmcache_ickill();
125 __vmcache_dckill(); 125 __vmcache_dckill();
126 __vmcache_l2kill(); 126 __vmcache_l2kill();
127 local_irq_restore(flags); 127 local_irq_restore(flags);
128 mb(); 128 mb();
129 } 129 }
130
131 void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
132 unsigned long vaddr, void *dst, void *src, int len)
133 {
134 memcpy(dst, src, len);
135 if (vma->vm_flags & VM_EXEC) {
136 flush_icache_range((unsigned long) dst,
137 (unsigned long) dst + len);
138 }
139 }
130 140
arch/hexagon/mm/ioremap.c
1 /* 1 /*
2 * I/O remap functions for Hexagon 2 * I/O remap functions for Hexagon
3 * 3 *
4 * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 and 7 * it under the terms of the GNU General Public License version 2 and
8 * only version 2 as published by the Free Software Foundation. 8 * only version 2 as published by the Free Software Foundation.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA. 18 * 02110-1301, USA.
19 */ 19 */
20 20
21 #include <linux/io.h> 21 #include <linux/io.h>
22 #include <linux/vmalloc.h> 22 #include <linux/vmalloc.h>
23 #include <linux/mm.h>
23 24
24 void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size) 25 void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size)
25 { 26 {
26 unsigned long last_addr, addr; 27 unsigned long last_addr, addr;
27 unsigned long offset = phys_addr & ~PAGE_MASK; 28 unsigned long offset = phys_addr & ~PAGE_MASK;
28 struct vm_struct *area; 29 struct vm_struct *area;
29 30
30 pgprot_t prot = __pgprot(_PAGE_PRESENT|_PAGE_READ|_PAGE_WRITE 31 pgprot_t prot = __pgprot(_PAGE_PRESENT|_PAGE_READ|_PAGE_WRITE
31 |(__HEXAGON_C_DEV << 6)); 32 |(__HEXAGON_C_DEV << 6));
32 33
33 last_addr = phys_addr + size - 1; 34 last_addr = phys_addr + size - 1;
34 35
35 /* Wrapping not allowed */ 36 /* Wrapping not allowed */
36 if (!size || (last_addr < phys_addr)) 37 if (!size || (last_addr < phys_addr))
37 return NULL; 38 return NULL;
38 39
39 /* Rounds up to next page size, including whole-page offset */ 40 /* Rounds up to next page size, including whole-page offset */
40 size = PAGE_ALIGN(offset + size); 41 size = PAGE_ALIGN(offset + size);
41 42
42 area = get_vm_area(size, VM_IOREMAP); 43 area = get_vm_area(size, VM_IOREMAP);
43 addr = (unsigned long)area->addr; 44 addr = (unsigned long)area->addr;
44 45
45 if (ioremap_page_range(addr, addr+size, phys_addr, prot)) { 46 if (ioremap_page_range(addr, addr+size, phys_addr, prot)) {
46 vunmap((void *)addr); 47 vunmap((void *)addr);
47 return NULL; 48 return NULL;
48 } 49 }
49 50
50 return (void __iomem *) (offset + addr); 51 return (void __iomem *) (offset + addr);
51 } 52 }
52 53
53 void __iounmap(const volatile void __iomem *addr) 54 void __iounmap(const volatile void __iomem *addr)
54 { 55 {
55 vunmap((void *) ((unsigned long) addr & PAGE_MASK)); 56 vunmap((void *) ((unsigned long) addr & PAGE_MASK));
56 } 57 }
57 58