aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
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 /arch/sh/kernel
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>
Diffstat (limited to 'arch/sh/kernel')
-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
5 files changed, 213 insertions, 203 deletions
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);