aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-11-01 09:49:04 -0400
committerPaul Mundt <lethal@linux-sh.org>2010-11-01 09:49:04 -0400
commit37b7a97884ba64bf7d403351ac2a9476ab4f1bba (patch)
tree1c738f6b97c9f82b96c8ae836ab38f34faa4c1d7
parente2781ac2a63011dd883e94c07eb086e6f2a5f521 (diff)
sh: machvec IO death.
This takes a bit of a sledgehammer to the machvec I/O routines. The iomem case requires no special casing and so can just be dropped outright. This only leaves the ioport casing for PCI and SuperIO mangling. With the SuperIO case going through the standard ioport mapping, it's possible to replace everything with generic routines. With this done the standard I/O routines are tidied up and NO_IOPORT now gets default-enabled for the vast majority of boards. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r--arch/sh/Kconfig3
-rw-r--r--arch/sh/boards/board-secureedge5410.c2
-rw-r--r--arch/sh/drivers/pci/pci.c3
-rw-r--r--arch/sh/include/asm/io.h345
-rw-r--r--arch/sh/include/asm/io_generic.h25
-rw-r--r--arch/sh/include/asm/machvec.h21
-rw-r--r--arch/sh/kernel/Makefile6
-rw-r--r--arch/sh/kernel/io_generic.c180
-rw-r--r--arch/sh/kernel/iomap.c165
-rw-r--r--arch/sh/kernel/ioport.c43
-rw-r--r--arch/sh/kernel/machvec.c22
11 files changed, 396 insertions, 419 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 5c075f562eba..32cd5f131e42 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -161,7 +161,8 @@ config ARCH_HAS_CPU_IDLE_WAIT
161 def_bool y 161 def_bool y
162 162
163config NO_IOPORT 163config NO_IOPORT
164 bool 164 def_bool !PCI
165 depends on !SH_CAYMAN && !SH_SH4202_MICRODEV
165 166
166config IO_TRAPPED 167config IO_TRAPPED
167 bool 168 bool
diff --git a/arch/sh/boards/board-secureedge5410.c b/arch/sh/boards/board-secureedge5410.c
index 32f875e8493d..f968f17891a4 100644
--- a/arch/sh/boards/board-secureedge5410.c
+++ b/arch/sh/boards/board-secureedge5410.c
@@ -29,8 +29,6 @@ unsigned short secureedge5410_ioport;
29 */ 29 */
30static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id) 30static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id)
31{ 31{
32 ctrl_delay(); /* dummy read */
33
34 printk("SnapGear: erase switch interrupt!\n"); 32 printk("SnapGear: erase switch interrupt!\n");
35 33
36 return IRQ_HANDLED; 34 return IRQ_HANDLED;
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index 60ee09a4e121..a09c77dd09db 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -382,14 +382,13 @@ static void __iomem *ioport_map_pci(struct pci_dev *dev,
382 struct pci_channel *chan = dev->sysdata; 382 struct pci_channel *chan = dev->sysdata;
383 383
384 if (unlikely(!chan->io_map_base)) { 384 if (unlikely(!chan->io_map_base)) {
385 chan->io_map_base = generic_io_base; 385 chan->io_map_base = sh_io_port_base;
386 386
387 if (pci_domains_supported) 387 if (pci_domains_supported)
388 panic("To avoid data corruption io_map_base MUST be " 388 panic("To avoid data corruption io_map_base MUST be "
389 "set with multiple PCI domains."); 389 "set with multiple PCI domains.");
390 } 390 }
391 391
392
393 return (void __iomem *)(chan->io_map_base + port); 392 return (void __iomem *)(chan->io_map_base + port);
394} 393}
395 394
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index b237d525d592..89ab2c57a4c2 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -1,5 +1,6 @@
1#ifndef __ASM_SH_IO_H 1#ifndef __ASM_SH_IO_H
2#define __ASM_SH_IO_H 2#define __ASM_SH_IO_H
3
3/* 4/*
4 * Convention: 5 * Convention:
5 * read{b,w,l,q}/write{b,w,l,q} are for PCI, 6 * read{b,w,l,q}/write{b,w,l,q} are for PCI,
@@ -15,12 +16,6 @@
15 * SuperH specific I/O (raw I/O to on-chip CPU peripherals). In practice 16 * SuperH specific I/O (raw I/O to on-chip CPU peripherals). In practice
16 * these have the same semantics as the __raw variants, and as such, all 17 * these have the same semantics as the __raw variants, and as such, all
17 * new code should be using the __raw versions. 18 * new code should be using the __raw versions.
18 *
19 * All ISA I/O routines are wrapped through the machine vector. If a
20 * board does not provide overrides, a generic set that are copied in
21 * from the default machine vector are used instead. These are largely
22 * for old compat code for I/O offseting to SuperIOs, all of which are
23 * better handled through the machvec ioport mapping routines these days.
24 */ 19 */
25#include <linux/errno.h> 20#include <linux/errno.h>
26#include <asm/cache.h> 21#include <asm/cache.h>
@@ -31,39 +26,10 @@
31#include <asm-generic/iomap.h> 26#include <asm-generic/iomap.h>
32 27
33#ifdef __KERNEL__ 28#ifdef __KERNEL__
34/* 29#define __IO_PREFIX generic
35 * Depending on which platform we are running on, we need different
36 * I/O functions.
37 */
38#define __IO_PREFIX generic
39#include <asm/io_generic.h> 30#include <asm/io_generic.h>
40#include <asm/io_trapped.h> 31#include <asm/io_trapped.h>
41 32
42#ifdef CONFIG_HAS_IOPORT
43
44#define inb(p) sh_mv.mv_inb((p))
45#define inw(p) sh_mv.mv_inw((p))
46#define inl(p) sh_mv.mv_inl((p))
47#define outb(x,p) sh_mv.mv_outb((x),(p))
48#define outw(x,p) sh_mv.mv_outw((x),(p))
49#define outl(x,p) sh_mv.mv_outl((x),(p))
50
51#define inb_p(p) sh_mv.mv_inb_p((p))
52#define inw_p(p) sh_mv.mv_inw_p((p))
53#define inl_p(p) sh_mv.mv_inl_p((p))
54#define outb_p(x,p) sh_mv.mv_outb_p((x),(p))
55#define outw_p(x,p) sh_mv.mv_outw_p((x),(p))
56#define outl_p(x,p) sh_mv.mv_outl_p((x),(p))
57
58#define insb(p,b,c) sh_mv.mv_insb((p), (b), (c))
59#define insw(p,b,c) sh_mv.mv_insw((p), (b), (c))
60#define insl(p,b,c) sh_mv.mv_insl((p), (b), (c))
61#define outsb(p,b,c) sh_mv.mv_outsb((p), (b), (c))
62#define outsw(p,b,c) sh_mv.mv_outsw((p), (b), (c))
63#define outsl(p,b,c) sh_mv.mv_outsl((p), (b), (c))
64
65#endif
66
67#define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile u8 __force *)(a) = (v)) 33#define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile u8 __force *)(a) = (v))
68#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile u16 __force *)(a) = (v)) 34#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile u16 __force *)(a) = (v))
69#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile u32 __force *)(a) = (v)) 35#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile u32 __force *)(a) = (v))
@@ -74,68 +40,39 @@
74#define __raw_readl(a) (__chk_io_ptr(a), *(volatile u32 __force *)(a)) 40#define __raw_readl(a) (__chk_io_ptr(a), *(volatile u32 __force *)(a))
75#define __raw_readq(a) (__chk_io_ptr(a), *(volatile u64 __force *)(a)) 41#define __raw_readq(a) (__chk_io_ptr(a), *(volatile u64 __force *)(a))
76 42
77#define readb(a) ({ u8 r_ = __raw_readb(a); mb(); r_; }) 43#define readb_relaxed(c) ({ u8 __v = __raw_readb(c); __v; })
78#define readw(a) ({ u16 r_ = __raw_readw(a); mb(); r_; }) 44#define readw_relaxed(c) ({ u16 __v = le16_to_cpu((__force __le16) \
79#define readl(a) ({ u32 r_ = __raw_readl(a); mb(); r_; }) 45 __raw_readw(c)); __v; })
80#define readq(a) ({ u64 r_ = __raw_readq(a); mb(); r_; }) 46#define readl_relaxed(c) ({ u32 __v = le32_to_cpu((__force __le32) \
81 47 __raw_readl(c)); __v; })
82#define writeb(v,a) ({ __raw_writeb((v),(a)); mb(); }) 48#define readq_relaxed(c) ({ u64 __v = le64_to_cpu((__force __le64) \
83#define writew(v,a) ({ __raw_writew((v),(a)); mb(); }) 49 __raw_readq(c)); __v; })
84#define writel(v,a) ({ __raw_writel((v),(a)); mb(); }) 50
85#define writeq(v,a) ({ __raw_writeq((v),(a)); mb(); }) 51#define writeb_relaxed(v,c) ((void)__raw_writeb(v,c))
86 52#define writew_relaxed(v,c) ((void)__raw_writew((__force u16) \
87/* 53 cpu_to_le16(v),c))
88 * Legacy SuperH on-chip I/O functions 54#define writel_relaxed(v,c) ((void)__raw_writel((__force u32) \
89 * 55 cpu_to_le32(v),c))
90 * These are all deprecated, all new (and especially cross-platform) code 56#define writeq_relaxed(v,c) ((void)__raw_writeq((__force u64) \
91 * should be using the __raw_xxx() routines directly. 57 cpu_to_le64(v),c))
92 */ 58
93static inline u8 __deprecated ctrl_inb(unsigned long addr) 59#define readb(a) ({ u8 r_ = readb_relaxed(a); rmb(); r_; })
94{ 60#define readw(a) ({ u16 r_ = readw_relaxed(a); rmb(); r_; })
95 return __raw_readb(addr); 61#define readl(a) ({ u32 r_ = readl_relaxed(a); rmb(); r_; })
96} 62#define readq(a) ({ u64 r_ = readq_relaxed(a); rmb(); r_; })
97 63
98static inline u16 __deprecated ctrl_inw(unsigned long addr) 64#define writeb(v,a) ({ wmb(); writeb_relaxed((v),(a)); })
99{ 65#define writew(v,a) ({ wmb(); writew_relaxed((v),(a)); })
100 return __raw_readw(addr); 66#define writel(v,a) ({ wmb(); writel_relaxed((v),(a)); })
101} 67#define writeq(v,a) ({ wmb(); writeq_relaxed((v),(a)); })
102 68
103static inline u32 __deprecated ctrl_inl(unsigned long addr) 69#define readsb(p,d,l) __raw_readsb(p,d,l)
104{ 70#define readsw(p,d,l) __raw_readsw(p,d,l)
105 return __raw_readl(addr); 71#define readsl(p,d,l) __raw_readsl(p,d,l)
106} 72
107 73#define writesb(p,d,l) __raw_writesb(p,d,l)
108static inline u64 __deprecated ctrl_inq(unsigned long addr) 74#define writesw(p,d,l) __raw_writesw(p,d,l)
109{ 75#define writesl(p,d,l) __raw_writesl(p,d,l)
110 return __raw_readq(addr);
111}
112
113static inline void __deprecated ctrl_outb(u8 v, unsigned long addr)
114{
115 __raw_writeb(v, addr);
116}
117
118static inline void __deprecated ctrl_outw(u16 v, unsigned long addr)
119{
120 __raw_writew(v, addr);
121}
122
123static inline void __deprecated ctrl_outl(u32 v, unsigned long addr)
124{
125 __raw_writel(v, addr);
126}
127
128static inline void __deprecated ctrl_outq(u64 v, unsigned long addr)
129{
130 __raw_writeq(v, addr);
131}
132
133extern unsigned long generic_io_base;
134
135static inline void ctrl_delay(void)
136{
137 __raw_readw(generic_io_base);
138}
139 76
140#define __BUILD_UNCACHED_IO(bwlq, type) \ 77#define __BUILD_UNCACHED_IO(bwlq, type) \
141static inline type read##bwlq##_uncached(unsigned long addr) \ 78static inline type read##bwlq##_uncached(unsigned long addr) \
@@ -159,10 +96,11 @@ __BUILD_UNCACHED_IO(w, u16)
159__BUILD_UNCACHED_IO(l, u32) 96__BUILD_UNCACHED_IO(l, u32)
160__BUILD_UNCACHED_IO(q, u64) 97__BUILD_UNCACHED_IO(q, u64)
161 98
162#define __BUILD_MEMORY_STRING(bwlq, type) \ 99#define __BUILD_MEMORY_STRING(pfx, bwlq, type) \
163 \ 100 \
164static inline void __raw_writes##bwlq(volatile void __iomem *mem, \ 101static inline void \
165 const void *addr, unsigned int count) \ 102pfx##writes##bwlq(volatile void __iomem *mem, const void *addr, \
103 unsigned int count) \
166{ \ 104{ \
167 const volatile type *__addr = addr; \ 105 const volatile type *__addr = addr; \
168 \ 106 \
@@ -172,8 +110,8 @@ static inline void __raw_writes##bwlq(volatile void __iomem *mem, \
172 } \ 110 } \
173} \ 111} \
174 \ 112 \
175static inline void __raw_reads##bwlq(volatile void __iomem *mem, \ 113static inline void pfx##reads##bwlq(volatile void __iomem *mem, \
176 void *addr, unsigned int count) \ 114 void *addr, unsigned int count) \
177{ \ 115{ \
178 volatile type *__addr = addr; \ 116 volatile type *__addr = addr; \
179 \ 117 \
@@ -183,85 +121,166 @@ static inline void __raw_reads##bwlq(volatile void __iomem *mem, \
183 } \ 121 } \
184} 122}
185 123
186__BUILD_MEMORY_STRING(b, u8) 124__BUILD_MEMORY_STRING(__raw_, b, u8)
187__BUILD_MEMORY_STRING(w, u16) 125__BUILD_MEMORY_STRING(__raw_, w, u16)
188 126
189#ifdef CONFIG_SUPERH32 127#ifdef CONFIG_SUPERH32
190void __raw_writesl(void __iomem *addr, const void *data, int longlen); 128void __raw_writesl(void __iomem *addr, const void *data, int longlen);
191void __raw_readsl(const void __iomem *addr, void *data, int longlen); 129void __raw_readsl(const void __iomem *addr, void *data, int longlen);
192#else 130#else
193__BUILD_MEMORY_STRING(l, u32) 131__BUILD_MEMORY_STRING(__raw_, l, u32)
194#endif 132#endif
195 133
196__BUILD_MEMORY_STRING(q, u64) 134__BUILD_MEMORY_STRING(__raw_, q, u64)
197 135
198#define writesb __raw_writesb 136#ifdef CONFIG_HAS_IOPORT
199#define writesw __raw_writesw 137
200#define writesl __raw_writesl 138/*
201 139 * Slowdown I/O port space accesses for antique hardware.
202#define readsb __raw_readsb 140 */
203#define readsw __raw_readsw 141#undef CONF_SLOWDOWN_IO
204#define readsl __raw_readsl 142
205 143/*
206#define readb_relaxed(a) readb(a) 144 * On SuperH I/O ports are memory mapped, so we access them using normal
207#define readw_relaxed(a) readw(a) 145 * load/store instructions. sh_io_port_base is the virtual address to
208#define readl_relaxed(a) readl(a) 146 * which all ports are being mapped.
209#define readq_relaxed(a) readq(a) 147 */
210 148extern const unsigned long sh_io_port_base;
211#ifndef CONFIG_GENERIC_IOMAP 149
212/* Simple MMIO */ 150static inline void __set_io_port_base(unsigned long pbase)
213#define ioread8(a) __raw_readb(a) 151{
214#define ioread16(a) __raw_readw(a) 152 *(unsigned long *)&sh_io_port_base = pbase;
215#define ioread16be(a) be16_to_cpu(__raw_readw((a))) 153 barrier();
216#define ioread32(a) __raw_readl(a) 154}
217#define ioread32be(a) be32_to_cpu(__raw_readl((a))) 155
218 156#ifdef CONFIG_GENERIC_IOMAP
219#define iowrite8(v,a) __raw_writeb((v),(a)) 157#define __ioport_map ioport_map
220#define iowrite16(v,a) __raw_writew((v),(a)) 158#else
221#define iowrite16be(v,a) __raw_writew(cpu_to_be16((v)),(a)) 159extern void __iomem *__ioport_map(unsigned long addr, unsigned int size);
222#define iowrite32(v,a) __raw_writel((v),(a))
223#define iowrite32be(v,a) __raw_writel(cpu_to_be32((v)),(a))
224
225#define ioread8_rep(a, d, c) __raw_readsb((a), (d), (c))
226#define ioread16_rep(a, d, c) __raw_readsw((a), (d), (c))
227#define ioread32_rep(a, d, c) __raw_readsl((a), (d), (c))
228
229#define iowrite8_rep(a, s, c) __raw_writesb((a), (s), (c))
230#define iowrite16_rep(a, s, c) __raw_writesw((a), (s), (c))
231#define iowrite32_rep(a, s, c) __raw_writesl((a), (s), (c))
232#endif 160#endif
233 161
234#define mmio_insb(p,d,c) __raw_readsb(p,d,c) 162#ifdef CONF_SLOWDOWN_IO
235#define mmio_insw(p,d,c) __raw_readsw(p,d,c) 163#define SLOW_DOWN_IO __raw_readw(sh_io_port_base)
236#define mmio_insl(p,d,c) __raw_readsl(p,d,c) 164#else
165#define SLOW_DOWN_IO
166#endif
237 167
238#define mmio_outsb(p,s,c) __raw_writesb(p,s,c) 168#define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p, slow) \
239#define mmio_outsw(p,s,c) __raw_writesw(p,s,c) 169 \
240#define mmio_outsl(p,s,c) __raw_writesl(p,s,c) 170static inline void pfx##out##bwlq##p(type val, unsigned long port) \
171{ \
172 volatile type *__addr; \
173 \
174 __addr = __ioport_map(port, sizeof(type)); \
175 *__addr = val; \
176 slow; \
177} \
178 \
179static inline type pfx##in##bwlq##p(unsigned long port) \
180{ \
181 volatile type *__addr; \
182 type __val; \
183 \
184 __addr = __ioport_map(port, sizeof(type)); \
185 __val = *__addr; \
186 slow; \
187 \
188 return __val; \
189}
241 190
242/* synco on SH-4A, otherwise a nop */ 191#define __BUILD_IOPORT_PFX(bus, bwlq, type) \
243#define mmiowb() wmb() 192 __BUILD_IOPORT_SINGLE(bus, bwlq, type, ,) \
193 __BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
244 194
245#define IO_SPACE_LIMIT 0xffffffff 195#define BUILDIO_IOPORT(bwlq, type) \
196 __BUILD_IOPORT_PFX(, bwlq, type)
246 197
247#ifdef CONFIG_HAS_IOPORT 198BUILDIO_IOPORT(b, u8)
199BUILDIO_IOPORT(w, u16)
200BUILDIO_IOPORT(l, u32)
201BUILDIO_IOPORT(q, u64)
202
203#define __BUILD_IOPORT_STRING(bwlq, type) \
204 \
205static inline void outs##bwlq(unsigned long port, const void *addr, \
206 unsigned int count) \
207{ \
208 const volatile type *__addr = addr; \
209 \
210 while (count--) { \
211 out##bwlq(*__addr, port); \
212 __addr++; \
213 } \
214} \
215 \
216static inline void ins##bwlq(unsigned long port, void *addr, \
217 unsigned int count) \
218{ \
219 volatile type *__addr = addr; \
220 \
221 while (count--) { \
222 *__addr = in##bwlq(port); \
223 __addr++; \
224 } \
225}
226
227__BUILD_IOPORT_STRING(b, u8)
228__BUILD_IOPORT_STRING(w, u16)
229__BUILD_IOPORT_STRING(l, u32)
230__BUILD_IOPORT_STRING(q, u64)
231
232#endif
248 233
249/* 234/*
250 * This function provides a method for the generic case where a 235 * Legacy SuperH on-chip I/O functions
251 * board-specific ioport_map simply needs to return the port + some
252 * arbitrary port base.
253 * 236 *
254 * We use this at board setup time to implicitly set the port base, and 237 * These are all deprecated, all new (and especially cross-platform) code
255 * as a result, we can use the generic ioport_map. 238 * should be using the __raw_xxx() routines directly.
256 */ 239 */
257static inline void __set_io_port_base(unsigned long pbase) 240static inline u8 __deprecated ctrl_inb(unsigned long addr)
258{ 241{
259 generic_io_base = pbase; 242 return __raw_readb(addr);
260} 243}
261 244
262#define __ioport_map(p, n) sh_mv.mv_ioport_map((p), (n)) 245static inline u16 __deprecated ctrl_inw(unsigned long addr)
246{
247 return __raw_readw(addr);
248}
263 249
264#endif 250static inline u32 __deprecated ctrl_inl(unsigned long addr)
251{
252 return __raw_readl(addr);
253}
254
255static inline u64 __deprecated ctrl_inq(unsigned long addr)
256{
257 return __raw_readq(addr);
258}
259
260static inline void __deprecated ctrl_outb(u8 v, unsigned long addr)
261{
262 __raw_writeb(v, addr);
263}
264
265static inline void __deprecated ctrl_outw(u16 v, unsigned long addr)
266{
267 __raw_writew(v, addr);
268}
269
270static inline void __deprecated ctrl_outl(u32 v, unsigned long addr)
271{
272 __raw_writel(v, addr);
273}
274
275static inline void __deprecated ctrl_outq(u64 v, unsigned long addr)
276{
277 __raw_writeq(v, addr);
278}
279
280#define IO_SPACE_LIMIT 0xffffffff
281
282/* synco on SH-4A, otherwise a nop */
283#define mmiowb() wmb()
265 284
266/* We really want to try and get these to memcpy etc */ 285/* We really want to try and get these to memcpy etc */
267void memcpy_fromio(void *, const volatile void __iomem *, unsigned long); 286void memcpy_fromio(void *, const volatile void __iomem *, unsigned long);
@@ -395,10 +414,6 @@ static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }
395#define ioremap_nocache ioremap 414#define ioremap_nocache ioremap
396#define iounmap __iounmap 415#define iounmap __iounmap
397 416
398#define maybebadio(port) \
399 printk(KERN_ERR "bad PC-like io %s:%u for port 0x%lx at 0x%08x\n", \
400 __func__, __LINE__, (port), (u32)__builtin_return_address(0))
401
402/* 417/*
403 * Convert a physical pointer to a virtual kernel pointer for /dev/mem 418 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
404 * access 419 * access
diff --git a/arch/sh/include/asm/io_generic.h b/arch/sh/include/asm/io_generic.h
index 491df93cbf8e..b5f6956f19c8 100644
--- a/arch/sh/include/asm/io_generic.h
+++ b/arch/sh/include/asm/io_generic.h
@@ -11,31 +11,6 @@
11#error "Don't include this header without a valid system prefix" 11#error "Don't include this header without a valid system prefix"
12#endif 12#endif
13 13
14u8 IO_CONCAT(__IO_PREFIX,inb)(unsigned long);
15u16 IO_CONCAT(__IO_PREFIX,inw)(unsigned long);
16u32 IO_CONCAT(__IO_PREFIX,inl)(unsigned long);
17
18void IO_CONCAT(__IO_PREFIX,outb)(u8, unsigned long);
19void IO_CONCAT(__IO_PREFIX,outw)(u16, unsigned long);
20void IO_CONCAT(__IO_PREFIX,outl)(u32, unsigned long);
21
22u8 IO_CONCAT(__IO_PREFIX,inb_p)(unsigned long);
23u16 IO_CONCAT(__IO_PREFIX,inw_p)(unsigned long);
24u32 IO_CONCAT(__IO_PREFIX,inl_p)(unsigned long);
25void IO_CONCAT(__IO_PREFIX,outb_p)(u8, unsigned long);
26void IO_CONCAT(__IO_PREFIX,outw_p)(u16, unsigned long);
27void IO_CONCAT(__IO_PREFIX,outl_p)(u32, unsigned long);
28
29void IO_CONCAT(__IO_PREFIX,insb)(unsigned long, void *dst, unsigned long count);
30void IO_CONCAT(__IO_PREFIX,insw)(unsigned long, void *dst, unsigned long count);
31void IO_CONCAT(__IO_PREFIX,insl)(unsigned long, void *dst, unsigned long count);
32void IO_CONCAT(__IO_PREFIX,outsb)(unsigned long, const void *src, unsigned long count);
33void IO_CONCAT(__IO_PREFIX,outsw)(unsigned long, const void *src, unsigned long count);
34void IO_CONCAT(__IO_PREFIX,outsl)(unsigned long, const void *src, unsigned long count);
35
36void *IO_CONCAT(__IO_PREFIX,ioremap)(unsigned long offset, unsigned long size);
37void IO_CONCAT(__IO_PREFIX,iounmap)(void *addr);
38
39void __iomem *IO_CONCAT(__IO_PREFIX,ioport_map)(unsigned long addr, unsigned int size); 14void __iomem *IO_CONCAT(__IO_PREFIX,ioport_map)(unsigned long addr, unsigned int size);
40void IO_CONCAT(__IO_PREFIX,ioport_unmap)(void __iomem *addr); 15void IO_CONCAT(__IO_PREFIX,ioport_unmap)(void __iomem *addr);
41void IO_CONCAT(__IO_PREFIX,mem_init)(void); 16void IO_CONCAT(__IO_PREFIX,mem_init)(void);
diff --git a/arch/sh/include/asm/machvec.h b/arch/sh/include/asm/machvec.h
index a0b0cf79cf8a..dd5d6e5bf204 100644
--- a/arch/sh/include/asm/machvec.h
+++ b/arch/sh/include/asm/machvec.h
@@ -23,27 +23,6 @@ struct sh_machine_vector {
23 void (*mv_init_irq)(void); 23 void (*mv_init_irq)(void);
24 24
25#ifdef CONFIG_HAS_IOPORT 25#ifdef CONFIG_HAS_IOPORT
26 u8 (*mv_inb)(unsigned long);
27 u16 (*mv_inw)(unsigned long);
28 u32 (*mv_inl)(unsigned long);
29 void (*mv_outb)(u8, unsigned long);
30 void (*mv_outw)(u16, unsigned long);
31 void (*mv_outl)(u32, unsigned long);
32
33 u8 (*mv_inb_p)(unsigned long);
34 u16 (*mv_inw_p)(unsigned long);
35 u32 (*mv_inl_p)(unsigned long);
36 void (*mv_outb_p)(u8, unsigned long);
37 void (*mv_outw_p)(u16, unsigned long);
38 void (*mv_outl_p)(u32, unsigned long);
39
40 void (*mv_insb)(unsigned long, void *dst, unsigned long count);
41 void (*mv_insw)(unsigned long, void *dst, unsigned long count);
42 void (*mv_insl)(unsigned long, void *dst, unsigned long count);
43 void (*mv_outsb)(unsigned long, const void *src, unsigned long count);
44 void (*mv_outsw)(unsigned long, const void *src, unsigned long count);
45 void (*mv_outsl)(unsigned long, const void *src, unsigned long count);
46
47 void __iomem *(*mv_ioport_map)(unsigned long port, unsigned int size); 26 void __iomem *(*mv_ioport_map)(unsigned long port, unsigned int size);
48 void (*mv_ioport_unmap)(void __iomem *); 27 void (*mv_ioport_unmap)(void __iomem *);
49#endif 28#endif
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 8eed6a485446..ff80227b02d8 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -20,6 +20,11 @@ obj-y := clkdev.o debugtraps.o dma-nommu.o dumpstack.o \
20 syscalls_$(BITS).o time.o topology.o traps.o \ 20 syscalls_$(BITS).o time.o topology.o traps.o \
21 traps_$(BITS).o unwinder.o 21 traps_$(BITS).o unwinder.o
22 22
23ifndef CONFIG_GENERIC_IOMAP
24obj-y += iomap.o
25obj-$(CONFIG_HAS_IOPORT) += ioport.o
26endif
27
23obj-y += cpu/ 28obj-y += cpu/
24obj-$(CONFIG_VSYSCALL) += vsyscall/ 29obj-$(CONFIG_VSYSCALL) += vsyscall/
25obj-$(CONFIG_SMP) += smp.o 30obj-$(CONFIG_SMP) += smp.o
@@ -39,7 +44,6 @@ obj-$(CONFIG_DUMP_CODE) += disassemble.o
39obj-$(CONFIG_HIBERNATION) += swsusp.o 44obj-$(CONFIG_HIBERNATION) += swsusp.o
40obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o 45obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o
41obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o 46obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o
42obj-$(CONFIG_HAS_IOPORT) += io_generic.o
43 47
44obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o 48obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
45obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o 49obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
deleted file mode 100644
index 447d78f666f9..000000000000
--- a/arch/sh/kernel/io_generic.c
+++ /dev/null
@@ -1,180 +0,0 @@
1/*
2 * arch/sh/kernel/io_generic.c
3 *
4 * Copyright (C) 2000 Niibe Yutaka
5 * Copyright (C) 2005 - 2007 Paul Mundt
6 *
7 * Generic I/O routine. These can be used where a machine specific version
8 * is not required.
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.
13 */
14#include <linux/module.h>
15#include <linux/io.h>
16#include <asm/machvec.h>
17
18#ifdef CONFIG_CPU_SH3
19/* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a
20 * workaround. */
21/* I'm not sure SH7709 has this kind of bug */
22#define dummy_read() __raw_readb(0xba000000)
23#else
24#define dummy_read()
25#endif
26
27unsigned long generic_io_base = 0;
28
29u8 generic_inb(unsigned long port)
30{
31 return __raw_readb(__ioport_map(port, 1));
32}
33
34u16 generic_inw(unsigned long port)
35{
36 return __raw_readw(__ioport_map(port, 2));
37}
38
39u32 generic_inl(unsigned long port)
40{
41 return __raw_readl(__ioport_map(port, 4));
42}
43
44u8 generic_inb_p(unsigned long port)
45{
46 unsigned long v = generic_inb(port);
47
48 ctrl_delay();
49 return v;
50}
51
52u16 generic_inw_p(unsigned long port)
53{
54 unsigned long v = generic_inw(port);
55
56 ctrl_delay();
57 return v;
58}
59
60u32 generic_inl_p(unsigned long port)
61{
62 unsigned long v = generic_inl(port);
63
64 ctrl_delay();
65 return v;
66}
67
68/*
69 * insb/w/l all read a series of bytes/words/longs from a fixed port
70 * address. However as the port address doesn't change we only need to
71 * convert the port address to real address once.
72 */
73
74void generic_insb(unsigned long port, void *dst, unsigned long count)
75{
76 __raw_readsb(__ioport_map(port, 1), dst, count);
77 dummy_read();
78}
79
80void generic_insw(unsigned long port, void *dst, unsigned long count)
81{
82 __raw_readsw(__ioport_map(port, 2), dst, count);
83 dummy_read();
84}
85
86void generic_insl(unsigned long port, void *dst, unsigned long count)
87{
88 __raw_readsl(__ioport_map(port, 4), dst, count);
89 dummy_read();
90}
91
92void generic_outb(u8 b, unsigned long port)
93{
94 __raw_writeb(b, __ioport_map(port, 1));
95}
96
97void generic_outw(u16 b, unsigned long port)
98{
99 __raw_writew(b, __ioport_map(port, 2));
100}
101
102void generic_outl(u32 b, unsigned long port)
103{
104 __raw_writel(b, __ioport_map(port, 4));
105}
106
107void generic_outb_p(u8 b, unsigned long port)
108{
109 generic_outb(b, port);
110 ctrl_delay();
111}
112
113void generic_outw_p(u16 b, unsigned long port)
114{
115 generic_outw(b, port);
116 ctrl_delay();
117}
118
119void generic_outl_p(u32 b, unsigned long port)
120{
121 generic_outl(b, port);
122 ctrl_delay();
123}
124
125/*
126 * outsb/w/l all write a series of bytes/words/longs to a fixed port
127 * address. However as the port address doesn't change we only need to
128 * convert the port address to real address once.
129 */
130void generic_outsb(unsigned long port, const void *src, unsigned long count)
131{
132 __raw_writesb(__ioport_map(port, 1), src, count);
133 dummy_read();
134}
135
136void generic_outsw(unsigned long port, const void *src, unsigned long count)
137{
138 __raw_writesw(__ioport_map(port, 2), src, count);
139 dummy_read();
140}
141
142void generic_outsl(unsigned long port, const void *src, unsigned long count)
143{
144 __raw_writesl(__ioport_map(port, 4), src, count);
145 dummy_read();
146}
147
148void __iomem *generic_ioport_map(unsigned long addr, unsigned int size)
149{
150#ifdef P1SEG
151 if (PXSEG(addr) >= P1SEG)
152 return (void __iomem *)addr;
153#endif
154
155 return (void __iomem *)(addr + generic_io_base);
156}
157
158void generic_ioport_unmap(void __iomem *addr)
159{
160}
161
162#ifndef CONFIG_GENERIC_IOMAP
163void __iomem *ioport_map(unsigned long port, unsigned int nr)
164{
165 void __iomem *ret;
166
167 ret = __ioport_map_trapped(port, nr);
168 if (ret)
169 return ret;
170
171 return __ioport_map(port, nr);
172}
173EXPORT_SYMBOL(ioport_map);
174
175void ioport_unmap(void __iomem *addr)
176{
177 sh_mv.mv_ioport_unmap(addr);
178}
179EXPORT_SYMBOL(ioport_unmap);
180#endif /* CONFIG_GENERIC_IOMAP */
diff --git a/arch/sh/kernel/iomap.c b/arch/sh/kernel/iomap.c
new file mode 100644
index 000000000000..2e8e8b9b9cef
--- /dev/null
+++ b/arch/sh/kernel/iomap.c
@@ -0,0 +1,165 @@
1/*
2 * arch/sh/kernel/iomap.c
3 *
4 * Copyright (C) 2000 Niibe Yutaka
5 * Copyright (C) 2005 - 2007 Paul Mundt
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11#include <linux/module.h>
12#include <linux/io.h>
13
14unsigned int ioread8(void __iomem *addr)
15{
16 return readb(addr);
17}
18EXPORT_SYMBOL(ioread8);
19
20unsigned int ioread16(void __iomem *addr)
21{
22 return readw(addr);
23}
24EXPORT_SYMBOL(ioread16);
25
26unsigned int ioread16be(void __iomem *addr)
27{
28 return be16_to_cpu(__raw_readw(addr));
29}
30EXPORT_SYMBOL(ioread16be);
31
32unsigned int ioread32(void __iomem *addr)
33{
34 return readl(addr);
35}
36EXPORT_SYMBOL(ioread32);
37
38unsigned int ioread32be(void __iomem *addr)
39{
40 return be32_to_cpu(__raw_readl(addr));
41}
42EXPORT_SYMBOL(ioread32be);
43
44void iowrite8(u8 val, void __iomem *addr)
45{
46 writeb(val, addr);
47}
48EXPORT_SYMBOL(iowrite8);
49
50void iowrite16(u16 val, void __iomem *addr)
51{
52 writew(val, addr);
53}
54EXPORT_SYMBOL(iowrite16);
55
56void iowrite16be(u16 val, void __iomem *addr)
57{
58 __raw_writew(cpu_to_be16(val), addr);
59}
60EXPORT_SYMBOL(iowrite16be);
61
62void iowrite32(u32 val, void __iomem *addr)
63{
64 writel(val, addr);
65}
66EXPORT_SYMBOL(iowrite32);
67
68void iowrite32be(u32 val, void __iomem *addr)
69{
70 __raw_writel(cpu_to_be32(val), addr);
71}
72EXPORT_SYMBOL(iowrite32be);
73
74/*
75 * These are the "repeat MMIO read/write" functions.
76 * Note the "__raw" accesses, since we don't want to
77 * convert to CPU byte order. We write in "IO byte
78 * order" (we also don't have IO barriers).
79 */
80static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
81{
82 while (--count >= 0) {
83 u8 data = __raw_readb(addr);
84 *dst = data;
85 dst++;
86 }
87}
88
89static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
90{
91 while (--count >= 0) {
92 u16 data = __raw_readw(addr);
93 *dst = data;
94 dst++;
95 }
96}
97
98static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
99{
100 while (--count >= 0) {
101 u32 data = __raw_readl(addr);
102 *dst = data;
103 dst++;
104 }
105}
106
107static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
108{
109 while (--count >= 0) {
110 __raw_writeb(*src, addr);
111 src++;
112 }
113}
114
115static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
116{
117 while (--count >= 0) {
118 __raw_writew(*src, addr);
119 src++;
120 }
121}
122
123static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
124{
125 while (--count >= 0) {
126 __raw_writel(*src, addr);
127 src++;
128 }
129}
130
131void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
132{
133 mmio_insb(addr, dst, count);
134}
135EXPORT_SYMBOL(ioread8_rep);
136
137void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
138{
139 mmio_insw(addr, dst, count);
140}
141EXPORT_SYMBOL(ioread16_rep);
142
143void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
144{
145 mmio_insl(addr, dst, count);
146}
147EXPORT_SYMBOL(ioread32_rep);
148
149void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
150{
151 mmio_outsb(addr, src, count);
152}
153EXPORT_SYMBOL(iowrite8_rep);
154
155void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
156{
157 mmio_outsw(addr, src, count);
158}
159EXPORT_SYMBOL(iowrite16_rep);
160
161void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
162{
163 mmio_outsl(addr, src, count);
164}
165EXPORT_SYMBOL(iowrite32_rep);
diff --git a/arch/sh/kernel/ioport.c b/arch/sh/kernel/ioport.c
new file mode 100644
index 000000000000..e3ad6103e7c1
--- /dev/null
+++ b/arch/sh/kernel/ioport.c
@@ -0,0 +1,43 @@
1/*
2 * arch/sh/kernel/ioport.c
3 *
4 * Copyright (C) 2000 Niibe Yutaka
5 * Copyright (C) 2005 - 2007 Paul Mundt
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11#include <linux/module.h>
12#include <linux/io.h>
13
14const unsigned long sh_io_port_base __read_mostly = -1;
15EXPORT_SYMBOL(sh_io_port_base);
16
17void __iomem *__ioport_map(unsigned long addr, unsigned int size)
18{
19 if (sh_mv.mv_ioport_map)
20 return sh_mv.mv_ioport_map(addr, size);
21
22 return (void __iomem *)(addr + sh_io_port_base);
23}
24EXPORT_SYMBOL(__ioport_map);
25
26void __iomem *ioport_map(unsigned long port, unsigned int nr)
27{
28 void __iomem *ret;
29
30 ret = __ioport_map_trapped(port, nr);
31 if (ret)
32 return ret;
33
34 return __ioport_map(port, nr);
35}
36EXPORT_SYMBOL(ioport_map);
37
38void ioport_unmap(void __iomem *addr)
39{
40 if (sh_mv.mv_ioport_unmap)
41 sh_mv.mv_ioport_unmap(addr);
42}
43EXPORT_SYMBOL(ioport_unmap);
diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c
index 9f9bb63616ad..3d722e49db08 100644
--- a/arch/sh/kernel/machvec.c
+++ b/arch/sh/kernel/machvec.c
@@ -118,28 +118,6 @@ void __init sh_mv_setup(void)
118 sh_mv.mv_##elem = generic_##elem; \ 118 sh_mv.mv_##elem = generic_##elem; \
119} while (0) 119} while (0)
120 120
121#ifdef CONFIG_HAS_IOPORT
122
123#ifdef P2SEG
124 __set_io_port_base(P2SEG);
125#else
126 __set_io_port_base(0);
127#endif
128
129 mv_set(inb); mv_set(inw); mv_set(inl);
130 mv_set(outb); mv_set(outw); mv_set(outl);
131
132 mv_set(inb_p); mv_set(inw_p); mv_set(inl_p);
133 mv_set(outb_p); mv_set(outw_p); mv_set(outl_p);
134
135 mv_set(insb); mv_set(insw); mv_set(insl);
136 mv_set(outsb); mv_set(outsw); mv_set(outsl);
137
138 mv_set(ioport_map);
139 mv_set(ioport_unmap);
140
141#endif
142
143 mv_set(irq_demux); 121 mv_set(irq_demux);
144 mv_set(mode_pins); 122 mv_set(mode_pins);
145 mv_set(mem_init); 123 mv_set(mem_init);