aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r--arch/sh/kernel/io.c41
-rw-r--r--arch/sh/kernel/io_generic.c192
2 files changed, 115 insertions, 118 deletions
diff --git a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c
index d9932f25993b..71c9fde2fd90 100644
--- a/arch/sh/kernel/io.c
+++ b/arch/sh/kernel/io.c
@@ -2,58 +2,73 @@
2 * linux/arch/sh/kernel/io.c 2 * linux/arch/sh/kernel/io.c
3 * 3 *
4 * Copyright (C) 2000 Stuart Menefy 4 * Copyright (C) 2000 Stuart Menefy
5 * Copyright (C) 2005 Paul Mundt
5 * 6 *
6 * Provide real functions which expand to whatever the header file defined. 7 * Provide real functions which expand to whatever the header file defined.
7 * Also definitions of machine independent IO functions. 8 * Also definitions of machine independent IO functions.
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive
12 * for more details.
8 */ 13 */
9
10#include <asm/io.h>
11#include <linux/module.h> 14#include <linux/module.h>
15#include <asm/machvec.h>
16#include <asm/io.h>
12 17
13/* 18/*
14 * Copy data from IO memory space to "real" memory space. 19 * Copy data from IO memory space to "real" memory space.
15 * This needs to be optimized. 20 * This needs to be optimized.
16 */ 21 */
17void memcpy_fromio(void * to, unsigned long from, unsigned long count) 22void memcpy_fromio(void *to, volatile void __iomem *from, unsigned long count)
18{ 23{
19 char *p = to; 24 char *p = to;
20 while (count) { 25 while (count) {
21 count--; 26 count--;
22 *p = readb(from); 27 *p = readb((void __iomem *)from);
23 p++; 28 p++;
24 from++; 29 from++;
25 } 30 }
26} 31}
27 32EXPORT_SYMBOL(memcpy_fromio);
33
28/* 34/*
29 * Copy data from "real" memory space to IO memory space. 35 * Copy data from "real" memory space to IO memory space.
30 * This needs to be optimized. 36 * This needs to be optimized.
31 */ 37 */
32void memcpy_toio(unsigned long to, const void * from, unsigned long count) 38void memcpy_toio(volatile void __iomem *to, const void *from, unsigned long count)
33{ 39{
34 const char *p = from; 40 const char *p = from;
35 while (count) { 41 while (count) {
36 count--; 42 count--;
37 writeb(*p, to); 43 writeb(*p, (void __iomem *)to);
38 p++; 44 p++;
39 to++; 45 to++;
40 } 46 }
41} 47}
42 48EXPORT_SYMBOL(memcpy_toio);
49
43/* 50/*
44 * "memset" on IO memory space. 51 * "memset" on IO memory space.
45 * This needs to be optimized. 52 * This needs to be optimized.
46 */ 53 */
47void memset_io(unsigned long dst, int c, unsigned long count) 54void memset_io(volatile void __iomem *dst, int c, unsigned long count)
48{ 55{
49 while (count) { 56 while (count) {
50 count--; 57 count--;
51 writeb(c, dst); 58 writeb(c, (void __iomem *)dst);
52 dst++; 59 dst++;
53 } 60 }
54} 61}
55
56EXPORT_SYMBOL(memcpy_fromio);
57EXPORT_SYMBOL(memcpy_toio);
58EXPORT_SYMBOL(memset_io); 62EXPORT_SYMBOL(memset_io);
59 63
64void __iomem *ioport_map(unsigned long port, unsigned int nr)
65{
66 return sh_mv.mv_ioport_map(port, nr);
67}
68EXPORT_SYMBOL(ioport_map);
69
70void ioport_unmap(void __iomem *addr)
71{
72 sh_mv.mv_ioport_unmap(addr);
73}
74EXPORT_SYMBOL(ioport_unmap);
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
index a911b0149d1f..28ec7487de8c 100644
--- a/arch/sh/kernel/io_generic.c
+++ b/arch/sh/kernel/io_generic.c
@@ -3,6 +3,7 @@
3 * linux/arch/sh/kernel/io_generic.c 3 * linux/arch/sh/kernel/io_generic.c
4 * 4 *
5 * Copyright (C) 2000 Niibe Yutaka 5 * Copyright (C) 2000 Niibe Yutaka
6 * Copyright (C) 2005 Paul Mundt
6 * 7 *
7 * Generic I/O routine. These can be used where a machine specific version 8 * Generic I/O routine. These can be used where a machine specific version
8 * is not required. 9 * is not required.
@@ -10,21 +11,20 @@
10 * This file is subject to the terms and conditions of the GNU General Public 11 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive 12 * License. See the file "COPYING" in the main directory of this archive
12 * for more details. 13 * for more details.
13 *
14 */ 14 */
15 15#include <linux/module.h>
16#include <asm/io.h> 16#include <asm/io.h>
17#include <asm/machvec.h> 17#include <asm/machvec.h>
18#include <linux/module.h>
19 18
20#if defined(CONFIG_CPU_SH3) 19#ifdef CONFIG_CPU_SH3
20/* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a
21 * workaround. */
21/* I'm not sure SH7709 has this kind of bug */ 22/* I'm not sure SH7709 has this kind of bug */
22#define SH3_PCMCIA_BUG_WORKAROUND 1 23#define dummy_read() ctrl_inb(0xba000000)
23#define DUMMY_READ_AREA6 0xba000000 24#else
25#define dummy_read()
24#endif 26#endif
25 27
26#define PORT2ADDR(x) (sh_mv.mv_isa_port2addr(x))
27
28unsigned long generic_io_base; 28unsigned long generic_io_base;
29 29
30static inline void delay(void) 30static inline void delay(void)
@@ -32,40 +32,40 @@ static inline void delay(void)
32 ctrl_inw(0xa0000000); 32 ctrl_inw(0xa0000000);
33} 33}
34 34
35unsigned char generic_inb(unsigned long port) 35u8 generic_inb(unsigned long port)
36{ 36{
37 return *(volatile unsigned char*)PORT2ADDR(port); 37 return ctrl_inb((unsigned long __force)ioport_map(port, 1));
38} 38}
39 39
40unsigned short generic_inw(unsigned long port) 40u16 generic_inw(unsigned long port)
41{ 41{
42 return *(volatile unsigned short*)PORT2ADDR(port); 42 return ctrl_inw((unsigned long __force)ioport_map(port, 2));
43} 43}
44 44
45unsigned int generic_inl(unsigned long port) 45u32 generic_inl(unsigned long port)
46{ 46{
47 return *(volatile unsigned long*)PORT2ADDR(port); 47 return ctrl_inl((unsigned long __force)ioport_map(port, 4));
48} 48}
49 49
50unsigned char generic_inb_p(unsigned long port) 50u8 generic_inb_p(unsigned long port)
51{ 51{
52 unsigned long v = *(volatile unsigned char*)PORT2ADDR(port); 52 unsigned long v = generic_inb(port);
53 53
54 delay(); 54 delay();
55 return v; 55 return v;
56} 56}
57 57
58unsigned short generic_inw_p(unsigned long port) 58u16 generic_inw_p(unsigned long port)
59{ 59{
60 unsigned long v = *(volatile unsigned short*)PORT2ADDR(port); 60 unsigned long v = generic_inw(port);
61 61
62 delay(); 62 delay();
63 return v; 63 return v;
64} 64}
65 65
66unsigned int generic_inl_p(unsigned long port) 66u32 generic_inl_p(unsigned long port)
67{ 67{
68 unsigned long v = *(volatile unsigned long*)PORT2ADDR(port); 68 unsigned long v = generic_inl(port);
69 69
70 delay(); 70 delay();
71 return v; 71 return v;
@@ -77,75 +77,70 @@ unsigned int generic_inl_p(unsigned long port)
77 * convert the port address to real address once. 77 * convert the port address to real address once.
78 */ 78 */
79 79
80void generic_insb(unsigned long port, void *buffer, unsigned long count) 80void generic_insb(unsigned long port, void *dst, unsigned long count)
81{ 81{
82 volatile unsigned char *port_addr; 82 volatile u8 *port_addr;
83 unsigned char *buf=buffer; 83 u8 *buf = dst;
84
85 port_addr = (volatile unsigned char *)PORT2ADDR(port);
86 84
87 while(count--) 85 port_addr = (volatile u8 *)ioport_map(port, 1);
88 *buf++ = *port_addr; 86 while (count--)
87 *buf++ = *port_addr;
89} 88}
90 89
91void generic_insw(unsigned long port, void *buffer, unsigned long count) 90void generic_insw(unsigned long port, void *dst, unsigned long count)
92{ 91{
93 volatile unsigned short *port_addr; 92 volatile u16 *port_addr;
94 unsigned short *buf=buffer; 93 u16 *buf = dst;
95 94
96 port_addr = (volatile unsigned short *)PORT2ADDR(port); 95 port_addr = (volatile u16 *)ioport_map(port, 2);
96 while (count--)
97 *buf++ = *port_addr;
97 98
98 while(count--) 99 dummy_read();
99 *buf++ = *port_addr;
100#ifdef SH3_PCMCIA_BUG_WORKAROUND
101 ctrl_inb (DUMMY_READ_AREA6);
102#endif
103} 100}
104 101
105void generic_insl(unsigned long port, void *buffer, unsigned long count) 102void generic_insl(unsigned long port, void *dst, unsigned long count)
106{ 103{
107 volatile unsigned long *port_addr; 104 volatile u32 *port_addr;
108 unsigned long *buf=buffer; 105 u32 *buf = dst;
109 106
110 port_addr = (volatile unsigned long *)PORT2ADDR(port); 107 port_addr = (volatile u32 *)ioport_map(port, 4);
108 while (count--)
109 *buf++ = *port_addr;
111 110
112 while(count--) 111 dummy_read();
113 *buf++ = *port_addr;
114#ifdef SH3_PCMCIA_BUG_WORKAROUND
115 ctrl_inb (DUMMY_READ_AREA6);
116#endif
117} 112}
118 113
119void generic_outb(unsigned char b, unsigned long port) 114void generic_outb(u8 b, unsigned long port)
120{ 115{
121 *(volatile unsigned char*)PORT2ADDR(port) = b; 116 ctrl_outb(b, (unsigned long __force)ioport_map(port, 1));
122} 117}
123 118
124void generic_outw(unsigned short b, unsigned long port) 119void generic_outw(u16 b, unsigned long port)
125{ 120{
126 *(volatile unsigned short*)PORT2ADDR(port) = b; 121 ctrl_outw(b, (unsigned long __force)ioport_map(port, 2));
127} 122}
128 123
129void generic_outl(unsigned int b, unsigned long port) 124void generic_outl(u32 b, unsigned long port)
130{ 125{
131 *(volatile unsigned long*)PORT2ADDR(port) = b; 126 ctrl_outl(b, (unsigned long __force)ioport_map(port, 4));
132} 127}
133 128
134void generic_outb_p(unsigned char b, unsigned long port) 129void generic_outb_p(u8 b, unsigned long port)
135{ 130{
136 *(volatile unsigned char*)PORT2ADDR(port) = b; 131 generic_outb(b, port);
137 delay(); 132 delay();
138} 133}
139 134
140void generic_outw_p(unsigned short b, unsigned long port) 135void generic_outw_p(u16 b, unsigned long port)
141{ 136{
142 *(volatile unsigned short*)PORT2ADDR(port) = b; 137 generic_outw(b, port);
143 delay(); 138 delay();
144} 139}
145 140
146void generic_outl_p(unsigned int b, unsigned long port) 141void generic_outl_p(u32 b, unsigned long port)
147{ 142{
148 *(volatile unsigned long*)PORT2ADDR(port) = b; 143 generic_outl(b, port);
149 delay(); 144 delay();
150} 145}
151 146
@@ -154,90 +149,77 @@ void generic_outl_p(unsigned int b, unsigned long port)
154 * address. However as the port address doesn't change we only need to 149 * address. However as the port address doesn't change we only need to
155 * convert the port address to real address once. 150 * convert the port address to real address once.
156 */ 151 */
157 152void generic_outsb(unsigned long port, const void *src, unsigned long count)
158void generic_outsb(unsigned long port, const void *buffer, unsigned long count)
159{ 153{
160 volatile unsigned char *port_addr; 154 volatile u8 *port_addr;
161 const unsigned char *buf=buffer; 155 const u8 *buf = src;
162 156
163 port_addr = (volatile unsigned char *)PORT2ADDR(port); 157 port_addr = (volatile u8 __force *)ioport_map(port, 1);
164 158
165 while(count--) 159 while (count--)
166 *port_addr = *buf++; 160 *port_addr = *buf++;
167} 161}
168 162
169void generic_outsw(unsigned long port, const void *buffer, unsigned long count) 163void generic_outsw(unsigned long port, const void *src, unsigned long count)
170{ 164{
171 volatile unsigned short *port_addr; 165 volatile u16 *port_addr;
172 const unsigned short *buf=buffer; 166 const u16 *buf = src;
173 167
174 port_addr = (volatile unsigned short *)PORT2ADDR(port); 168 port_addr = (volatile u16 __force *)ioport_map(port, 2);
175 169
176 while(count--) 170 while (count--)
177 *port_addr = *buf++; 171 *port_addr = *buf++;
178 172
179#ifdef SH3_PCMCIA_BUG_WORKAROUND 173 dummy_read();
180 ctrl_inb (DUMMY_READ_AREA6);
181#endif
182} 174}
183 175
184void generic_outsl(unsigned long port, const void *buffer, unsigned long count) 176void generic_outsl(unsigned long port, const void *src, unsigned long count)
185{ 177{
186 volatile unsigned long *port_addr; 178 volatile u32 *port_addr;
187 const unsigned long *buf=buffer; 179 const u32 *buf = src;
188 180
189 port_addr = (volatile unsigned long *)PORT2ADDR(port); 181 port_addr = (volatile u32 __force *)ioport_map(port, 4);
182 while (count--)
183 *port_addr = *buf++;
190 184
191 while(count--) 185 dummy_read();
192 *port_addr = *buf++;
193
194#ifdef SH3_PCMCIA_BUG_WORKAROUND
195 ctrl_inb (DUMMY_READ_AREA6);
196#endif
197}
198
199unsigned char generic_readb(unsigned long addr)
200{
201 return *(volatile unsigned char*)addr;
202} 186}
203 187
204unsigned short generic_readw(unsigned long addr) 188u8 generic_readb(void __iomem *addr)
205{ 189{
206 return *(volatile unsigned short*)addr; 190 return ctrl_inb((unsigned long __force)addr);
207} 191}
208 192
209unsigned int generic_readl(unsigned long addr) 193u16 generic_readw(void __iomem *addr)
210{ 194{
211 return *(volatile unsigned long*)addr; 195 return ctrl_inw((unsigned long __force)addr);
212} 196}
213 197
214void generic_writeb(unsigned char b, unsigned long addr) 198u32 generic_readl(void __iomem *addr)
215{ 199{
216 *(volatile unsigned char*)addr = b; 200 return ctrl_inl((unsigned long __force)addr);
217} 201}
218 202
219void generic_writew(unsigned short b, unsigned long addr) 203void generic_writeb(u8 b, void __iomem *addr)
220{ 204{
221 *(volatile unsigned short*)addr = b; 205 ctrl_outb(b, (unsigned long __force)addr);
222} 206}
223 207
224void generic_writel(unsigned int b, unsigned long addr) 208void generic_writew(u16 b, void __iomem *addr)
225{ 209{
226 *(volatile unsigned long*)addr = b; 210 ctrl_outw(b, (unsigned long __force)addr);
227} 211}
228 212
229void * generic_ioremap(unsigned long offset, unsigned long size) 213void generic_writel(u32 b, void __iomem *addr)
230{ 214{
231 return (void *) P2SEGADDR(offset); 215 ctrl_outl(b, (unsigned long __force)addr);
232} 216}
233EXPORT_SYMBOL(generic_ioremap);
234 217
235void generic_iounmap(void *addr) 218void __iomem *generic_ioport_map(unsigned long addr, unsigned int size)
236{ 219{
220 return (void __iomem *)(addr + generic_io_base);
237} 221}
238EXPORT_SYMBOL(generic_iounmap);
239 222
240unsigned long generic_isa_port2addr(unsigned long offset) 223void generic_ioport_unmap(void __iomem *addr)
241{ 224{
242 return offset + generic_io_base;
243} 225}