Commit | Line | Data |
---|---|---|
9c57548f PM |
1 | /* |
2 | * arch/sh/kernel/io_generic.c | |
1da177e4 LT |
3 | * |
4 | * Copyright (C) 2000 Niibe Yutaka | |
9c57548f | 5 | * Copyright (C) 2005 - 2007 Paul Mundt |
1da177e4 LT |
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. | |
1da177e4 | 13 | */ |
b66c1a39 | 14 | #include <linux/module.h> |
9c57548f | 15 | #include <linux/io.h> |
1da177e4 | 16 | #include <asm/machvec.h> |
1da177e4 | 17 | |
b66c1a39 PM |
18 | #ifdef CONFIG_CPU_SH3 |
19 | /* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a | |
20 | * workaround. */ | |
1da177e4 | 21 | /* I'm not sure SH7709 has this kind of bug */ |
14866543 | 22 | #define dummy_read() __raw_readb(0xba000000) |
b66c1a39 PM |
23 | #else |
24 | #define dummy_read() | |
1da177e4 LT |
25 | #endif |
26 | ||
e9c58fc5 | 27 | unsigned long generic_io_base = 0; |
1da177e4 | 28 | |
b66c1a39 | 29 | u8 generic_inb(unsigned long port) |
1da177e4 | 30 | { |
14866543 | 31 | return __raw_readb(__ioport_map(port, 1)); |
1da177e4 LT |
32 | } |
33 | ||
b66c1a39 | 34 | u16 generic_inw(unsigned long port) |
1da177e4 | 35 | { |
14866543 | 36 | return __raw_readw(__ioport_map(port, 2)); |
1da177e4 LT |
37 | } |
38 | ||
b66c1a39 | 39 | u32 generic_inl(unsigned long port) |
1da177e4 | 40 | { |
14866543 | 41 | return __raw_readl(__ioport_map(port, 4)); |
1da177e4 LT |
42 | } |
43 | ||
b66c1a39 | 44 | u8 generic_inb_p(unsigned long port) |
1da177e4 | 45 | { |
b66c1a39 | 46 | unsigned long v = generic_inb(port); |
1da177e4 | 47 | |
14866543 | 48 | ctrl_delay(); |
1da177e4 LT |
49 | return v; |
50 | } | |
51 | ||
b66c1a39 | 52 | u16 generic_inw_p(unsigned long port) |
1da177e4 | 53 | { |
b66c1a39 | 54 | unsigned long v = generic_inw(port); |
1da177e4 | 55 | |
14866543 | 56 | ctrl_delay(); |
1da177e4 LT |
57 | return v; |
58 | } | |
59 | ||
b66c1a39 | 60 | u32 generic_inl_p(unsigned long port) |
1da177e4 | 61 | { |
b66c1a39 | 62 | unsigned long v = generic_inl(port); |
1da177e4 | 63 | |
14866543 | 64 | ctrl_delay(); |
1da177e4 LT |
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 | ||
b66c1a39 | 74 | void generic_insb(unsigned long port, void *dst, unsigned long count) |
1da177e4 | 75 | { |
8af57f8b SM |
76 | __raw_readsb(__ioport_map(port, 1), dst, count); |
77 | dummy_read(); | |
1da177e4 LT |
78 | } |
79 | ||
b66c1a39 | 80 | void generic_insw(unsigned long port, void *dst, unsigned long count) |
1da177e4 | 81 | { |
8af57f8b | 82 | __raw_readsw(__ioport_map(port, 2), dst, count); |
b66c1a39 | 83 | dummy_read(); |
1da177e4 LT |
84 | } |
85 | ||
b66c1a39 | 86 | void generic_insl(unsigned long port, void *dst, unsigned long count) |
1da177e4 | 87 | { |
8af57f8b | 88 | __raw_readsl(__ioport_map(port, 4), dst, count); |
b66c1a39 | 89 | dummy_read(); |
1da177e4 LT |
90 | } |
91 | ||
b66c1a39 | 92 | void generic_outb(u8 b, unsigned long port) |
1da177e4 | 93 | { |
14866543 | 94 | __raw_writeb(b, __ioport_map(port, 1)); |
1da177e4 LT |
95 | } |
96 | ||
b66c1a39 | 97 | void generic_outw(u16 b, unsigned long port) |
1da177e4 | 98 | { |
14866543 | 99 | __raw_writew(b, __ioport_map(port, 2)); |
1da177e4 LT |
100 | } |
101 | ||
b66c1a39 | 102 | void generic_outl(u32 b, unsigned long port) |
1da177e4 | 103 | { |
14866543 | 104 | __raw_writel(b, __ioport_map(port, 4)); |
1da177e4 LT |
105 | } |
106 | ||
b66c1a39 | 107 | void generic_outb_p(u8 b, unsigned long port) |
1da177e4 | 108 | { |
b66c1a39 | 109 | generic_outb(b, port); |
14866543 | 110 | ctrl_delay(); |
1da177e4 LT |
111 | } |
112 | ||
b66c1a39 | 113 | void generic_outw_p(u16 b, unsigned long port) |
1da177e4 | 114 | { |
b66c1a39 | 115 | generic_outw(b, port); |
14866543 | 116 | ctrl_delay(); |
1da177e4 LT |
117 | } |
118 | ||
b66c1a39 | 119 | void generic_outl_p(u32 b, unsigned long port) |
1da177e4 | 120 | { |
b66c1a39 | 121 | generic_outl(b, port); |
14866543 | 122 | ctrl_delay(); |
1da177e4 LT |
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 | */ | |
b66c1a39 | 130 | void generic_outsb(unsigned long port, const void *src, unsigned long count) |
1da177e4 | 131 | { |
8af57f8b SM |
132 | __raw_writesb(__ioport_map(port, 1), src, count); |
133 | dummy_read(); | |
1da177e4 LT |
134 | } |
135 | ||
b66c1a39 | 136 | void generic_outsw(unsigned long port, const void *src, unsigned long count) |
1da177e4 | 137 | { |
8af57f8b | 138 | __raw_writesw(__ioport_map(port, 2), src, count); |
b66c1a39 | 139 | dummy_read(); |
1da177e4 LT |
140 | } |
141 | ||
b66c1a39 | 142 | void generic_outsl(unsigned long port, const void *src, unsigned long count) |
1da177e4 | 143 | { |
8af57f8b | 144 | __raw_writesl(__ioport_map(port, 4), src, count); |
b66c1a39 | 145 | dummy_read(); |
1da177e4 LT |
146 | } |
147 | ||
b66c1a39 | 148 | void __iomem *generic_ioport_map(unsigned long addr, unsigned int size) |
1da177e4 | 149 | { |
e9c58fc5 | 150 | #ifdef P1SEG |
48ff3e04 PM |
151 | if (PXSEG(addr) >= P1SEG) |
152 | return (void __iomem *)addr; | |
e9c58fc5 | 153 | #endif |
48ff3e04 | 154 | |
b66c1a39 | 155 | return (void __iomem *)(addr + generic_io_base); |
1da177e4 | 156 | } |
1da177e4 | 157 | |
b66c1a39 | 158 | void generic_ioport_unmap(void __iomem *addr) |
1da177e4 | 159 | { |
1da177e4 | 160 | } |