Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sh: More I/O routine overhauling.

This tidies up a lot of the PIO/MMIO split. No in-tree platforms were
making use of the MMIO overloading through the machvec (nor have any of
them been in some time), so we just kill all of that off. The ISA I/O
routine wrapping remains unaffected, which remains the only special
casing outside of the iomap API that boards need to think about.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>

+109 -226
+90 -155
arch/sh/include/asm/io.h
··· 1 1 #ifndef __ASM_SH_IO_H 2 2 #define __ASM_SH_IO_H 3 - 4 3 /* 5 4 * Convention: 6 - * read{b,w,l}/write{b,w,l} are for PCI, 5 + * read{b,w,l,q}/write{b,w,l,q} are for PCI, 7 6 * while in{b,w,l}/out{b,w,l} are for ISA 8 - * These may (will) be platform specific function. 7 + * 9 8 * In addition we have 'pausing' versions: in{b,w,l}_p/out{b,w,l}_p 10 9 * and 'string' versions: ins{b,w,l}/outs{b,w,l} 11 - * For read{b,w,l} and write{b,w,l} there are also __raw versions, which 12 - * do not have a memory barrier after them. 13 10 * 14 - * In addition, we have 15 - * ctrl_in{b,w,l}/ctrl_out{b,w,l} for SuperH specific I/O. 16 - * which are processor specific. 17 - */ 18 - 19 - /* 20 - * We follow the Alpha convention here: 21 - * __inb expands to an inline function call (which calls via the mv) 22 - * _inb is a real function call (note ___raw fns are _ version of __raw) 23 - * inb by default expands to _inb, but the machine specific code may 24 - * define it to __inb if it chooses. 11 + * While read{b,w,l,q} and write{b,w,l,q} contain memory barriers 12 + * automatically, there are also __raw versions, which do not. 13 + * 14 + * Historically, we have also had ctrl_in{b,w,l,q}/ctrl_out{b,w,l,q} for 15 + * 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 + * 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. 25 24 */ 26 25 #include <asm/cache.h> 27 26 #include <asm/system.h> ··· 30 31 #include <asm-generic/iomap.h> 31 32 32 33 #ifdef __KERNEL__ 33 - 34 34 /* 35 35 * Depending on which platform we are running on, we need different 36 36 * I/O functions. ··· 38 40 #include <asm/io_generic.h> 39 41 #include <asm/io_trapped.h> 40 42 41 - #define maybebadio(port) \ 42 - printk(KERN_ERR "bad PC-like io %s:%u for port 0x%lx at 0x%08x\n", \ 43 - __FUNCTION__, __LINE__, (port), (u32)__builtin_return_address(0)) 43 + #define inb(p) sh_mv.mv_inb((p)) 44 + #define inw(p) sh_mv.mv_inw((p)) 45 + #define inl(p) sh_mv.mv_inl((p)) 46 + #define outb(x,p) sh_mv.mv_outb((x),(p)) 47 + #define outw(x,p) sh_mv.mv_outw((x),(p)) 48 + #define outl(x,p) sh_mv.mv_outl((x),(p)) 44 49 45 - /* 46 - * Since boards are able to define their own set of I/O routines through 47 - * their respective machine vector, we always wrap through the mv. 48 - * 49 - * Also, in the event that a board hasn't provided its own definition for 50 - * a given routine, it will be wrapped to generic code at run-time. 51 - */ 50 + #define inb_p(p) sh_mv.mv_inb_p((p)) 51 + #define inw_p(p) sh_mv.mv_inw_p((p)) 52 + #define inl_p(p) sh_mv.mv_inl_p((p)) 53 + #define outb_p(x,p) sh_mv.mv_outb_p((x),(p)) 54 + #define outw_p(x,p) sh_mv.mv_outw_p((x),(p)) 55 + #define outl_p(x,p) sh_mv.mv_outl_p((x),(p)) 52 56 53 - #define __inb(p) sh_mv.mv_inb((p)) 54 - #define __inw(p) sh_mv.mv_inw((p)) 55 - #define __inl(p) sh_mv.mv_inl((p)) 56 - #define __outb(x,p) sh_mv.mv_outb((x),(p)) 57 - #define __outw(x,p) sh_mv.mv_outw((x),(p)) 58 - #define __outl(x,p) sh_mv.mv_outl((x),(p)) 57 + #define insb(p,b,c) sh_mv.mv_insb((p), (b), (c)) 58 + #define insw(p,b,c) sh_mv.mv_insw((p), (b), (c)) 59 + #define insl(p,b,c) sh_mv.mv_insl((p), (b), (c)) 60 + #define outsb(p,b,c) sh_mv.mv_outsb((p), (b), (c)) 61 + #define outsw(p,b,c) sh_mv.mv_outsw((p), (b), (c)) 62 + #define outsl(p,b,c) sh_mv.mv_outsl((p), (b), (c)) 59 63 60 - #define __inb_p(p) sh_mv.mv_inb_p((p)) 61 - #define __inw_p(p) sh_mv.mv_inw_p((p)) 62 - #define __inl_p(p) sh_mv.mv_inl_p((p)) 63 - #define __outb_p(x,p) sh_mv.mv_outb_p((x),(p)) 64 - #define __outw_p(x,p) sh_mv.mv_outw_p((x),(p)) 65 - #define __outl_p(x,p) sh_mv.mv_outl_p((x),(p)) 64 + #define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile u8 __force *)(a) = (v)) 65 + #define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile u16 __force *)(a) = (v)) 66 + #define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile u32 __force *)(a) = (v)) 67 + #define __raw_writeq(v,a) (__chk_io_ptr(a), *(volatile u64 __force *)(a) = (v)) 66 68 67 - #define __insb(p,b,c) sh_mv.mv_insb((p), (b), (c)) 68 - #define __insw(p,b,c) sh_mv.mv_insw((p), (b), (c)) 69 - #define __insl(p,b,c) sh_mv.mv_insl((p), (b), (c)) 70 - #define __outsb(p,b,c) sh_mv.mv_outsb((p), (b), (c)) 71 - #define __outsw(p,b,c) sh_mv.mv_outsw((p), (b), (c)) 72 - #define __outsl(p,b,c) sh_mv.mv_outsl((p), (b), (c)) 69 + #define __raw_readb(a) (__chk_io_ptr(a), *(volatile u8 __force *)(a)) 70 + #define __raw_readw(a) (__chk_io_ptr(a), *(volatile u16 __force *)(a)) 71 + #define __raw_readl(a) (__chk_io_ptr(a), *(volatile u32 __force *)(a)) 72 + #define __raw_readq(a) (__chk_io_ptr(a), *(volatile u64 __force *)(a)) 73 73 74 - #define __readb(a) sh_mv.mv_readb((a)) 75 - #define __readw(a) sh_mv.mv_readw((a)) 76 - #define __readl(a) sh_mv.mv_readl((a)) 77 - #define __writeb(v,a) sh_mv.mv_writeb((v),(a)) 78 - #define __writew(v,a) sh_mv.mv_writew((v),(a)) 79 - #define __writel(v,a) sh_mv.mv_writel((v),(a)) 74 + #define readb(a) ({ u8 r_ = __raw_readb(a); mb(); r_; }) 75 + #define readw(a) ({ u16 r_ = __raw_readw(a); mb(); r_; }) 76 + #define readl(a) ({ u32 r_ = __raw_readl(a); mb(); r_; }) 77 + #define readq(a) ({ u64 r_ = __raw_readq(a); mb(); r_; }) 80 78 81 - #define inb __inb 82 - #define inw __inw 83 - #define inl __inl 84 - #define outb __outb 85 - #define outw __outw 86 - #define outl __outl 79 + #define writeb(v,a) ({ __raw_writeb((v),(a)); mb(); }) 80 + #define writew(v,a) ({ __raw_writew((v),(a)); mb(); }) 81 + #define writel(v,a) ({ __raw_writel((v),(a)); mb(); }) 82 + #define writeq(v,a) ({ __raw_writeq((v),(a)); mb(); }) 87 83 88 - #define inb_p __inb_p 89 - #define inw_p __inw_p 90 - #define inl_p __inl_p 91 - #define outb_p __outb_p 92 - #define outw_p __outw_p 93 - #define outl_p __outl_p 84 + /* SuperH on-chip I/O functions */ 85 + #define ctrl_inb __raw_readb 86 + #define ctrl_inw __raw_readw 87 + #define ctrl_inl __raw_readl 88 + #define ctrl_inq __raw_readq 94 89 95 - #define insb __insb 96 - #define insw __insw 97 - #define insl __insl 98 - #define outsb __outsb 99 - #define outsw __outsw 100 - #define outsl __outsl 90 + #define ctrl_outb __raw_writeb 91 + #define ctrl_outw __raw_writew 92 + #define ctrl_outl __raw_writel 93 + #define ctrl_outq __raw_writeq 101 94 102 - #define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v)) 103 - #define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v)) 104 - #define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v)) 105 - 106 - #define __raw_readb(a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a)) 107 - #define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a)) 108 - #define __raw_readl(a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a)) 109 - 110 - void __raw_writesl(void __iomem *addr, const void *data, int longlen); 111 - void __raw_readsl(const void __iomem *addr, void *data, int longlen); 112 - 113 - /* 114 - * The platform header files may define some of these macros to use 115 - * the inlined versions where appropriate. These macros may also be 116 - * redefined by userlevel programs. 117 - */ 118 - #define readb(a) ({ unsigned int r_ = __readb(a); mb(); r_; }) 119 - #define readw(a) ({ unsigned int r_ = __readw(a); mb(); r_; }) 120 - #define readl(a) ({ unsigned int r_ = __readl(a); mb(); r_; }) 121 - 122 - #define writeb(v,a) ({ __writeb((v),(a)); mb(); }) 123 - #define writew(v,a) ({ __writew((v),(a)); mb(); }) 124 - #define writel(v,a) ({ __writel((v),(a)); mb(); }) 95 + static inline void ctrl_delay(void) 96 + { 97 + #ifdef P2SEG 98 + __raw_readw(P2SEG); 99 + #endif 100 + } 125 101 126 102 #define __BUILD_MEMORY_STRING(bwlq, type) \ 127 103 \ ··· 123 151 124 152 __BUILD_MEMORY_STRING(b, u8) 125 153 __BUILD_MEMORY_STRING(w, u16) 154 + __BUILD_MEMORY_STRING(q, u64) 126 155 127 - #define writesb __raw_writesb 128 - #define writesw __raw_writesw 129 - #define writesl __raw_writesl 156 + void __raw_writesl(void __iomem *addr, const void *data, int longlen); 157 + void __raw_readsl(const void __iomem *addr, void *data, int longlen); 130 158 131 - #define readsb __raw_readsb 132 - #define readsw __raw_readsw 133 - #define readsl __raw_readsl 159 + #define writesb __raw_writesb 160 + #define writesw __raw_writesw 161 + #define writesl __raw_writesl 134 162 135 - #define readb_relaxed(a) readb(a) 136 - #define readw_relaxed(a) readw(a) 137 - #define readl_relaxed(a) readl(a) 163 + #define readsb __raw_readsb 164 + #define readsw __raw_readsw 165 + #define readsl __raw_readsl 166 + 167 + #define readb_relaxed(a) readb(a) 168 + #define readw_relaxed(a) readw(a) 169 + #define readl_relaxed(a) readl(a) 170 + #define readq_relaxed(a) readq(a) 138 171 139 172 /* Simple MMIO */ 140 173 #define ioread8(a) __raw_readb(a) ··· 162 185 #define iowrite16_rep(a, s, c) __raw_writesw((a), (s), (c)) 163 186 #define iowrite32_rep(a, s, c) __raw_writesl((a), (s), (c)) 164 187 165 - #define mmiowb() wmb() /* synco on SH-4A, otherwise a nop */ 188 + /* synco on SH-4A, otherwise a nop */ 189 + #define mmiowb() wmb() 166 190 167 191 #define IO_SPACE_LIMIT 0xffffffff 168 192 169 193 extern unsigned long generic_io_base; 170 194 171 195 /* 172 - * This function provides a method for the generic case where a board-specific 173 - * ioport_map simply needs to return the port + some arbitrary port base. 196 + * This function provides a method for the generic case where a 197 + * board-specific ioport_map simply needs to return the port + some 198 + * arbitrary port base. 174 199 * 175 200 * We use this at board setup time to implicitly set the port base, and 176 201 * as a result, we can use the generic ioport_map. ··· 185 206 #define __ioport_map(p, n) sh_mv.mv_ioport_map((p), (n)) 186 207 187 208 /* We really want to try and get these to memcpy etc */ 188 - extern void memcpy_fromio(void *, volatile void __iomem *, unsigned long); 189 - extern void memcpy_toio(volatile void __iomem *, const void *, unsigned long); 190 - extern void memset_io(volatile void __iomem *, int, unsigned long); 191 - 192 - /* SuperH on-chip I/O functions */ 193 - static inline unsigned char ctrl_inb(unsigned long addr) 194 - { 195 - return *(volatile unsigned char*)addr; 196 - } 197 - 198 - static inline unsigned short ctrl_inw(unsigned long addr) 199 - { 200 - return *(volatile unsigned short*)addr; 201 - } 202 - 203 - static inline unsigned int ctrl_inl(unsigned long addr) 204 - { 205 - return *(volatile unsigned long*)addr; 206 - } 207 - 208 - static inline unsigned long long ctrl_inq(unsigned long addr) 209 - { 210 - return *(volatile unsigned long long*)addr; 211 - } 212 - 213 - static inline void ctrl_outb(unsigned char b, unsigned long addr) 214 - { 215 - *(volatile unsigned char*)addr = b; 216 - } 217 - 218 - static inline void ctrl_outw(unsigned short b, unsigned long addr) 219 - { 220 - *(volatile unsigned short*)addr = b; 221 - } 222 - 223 - static inline void ctrl_outl(unsigned int b, unsigned long addr) 224 - { 225 - *(volatile unsigned long*)addr = b; 226 - } 227 - 228 - static inline void ctrl_outq(unsigned long long b, unsigned long addr) 229 - { 230 - *(volatile unsigned long long*)addr = b; 231 - } 232 - 233 - static inline void ctrl_delay(void) 234 - { 235 - #ifdef P2SEG 236 - ctrl_inw(P2SEG); 237 - #endif 238 - } 209 + void memcpy_fromio(void *, const volatile void __iomem *, unsigned long); 210 + void memcpy_toio(volatile void __iomem *, const void *, unsigned long); 211 + void memset_io(volatile void __iomem *, int, unsigned long); 239 212 240 213 /* Quad-word real-mode I/O, don't ask.. */ 241 214 unsigned long long peek_real_address_q(unsigned long long addr); ··· 277 346 __ioremap_mode((offset), (size), (flags)) 278 347 #define iounmap(addr) \ 279 348 __iounmap((addr)) 349 + 350 + #define maybebadio(port) \ 351 + printk(KERN_ERR "bad PC-like io %s:%u for port 0x%lx at 0x%08x\n", \ 352 + __func__, __LINE__, (port), (u32)__builtin_return_address(0)) 280 353 281 354 /* 282 355 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
-7
arch/sh/include/asm/io_generic.h
··· 33 33 void IO_CONCAT(__IO_PREFIX,outsw)(unsigned long, const void *src, unsigned long count); 34 34 void IO_CONCAT(__IO_PREFIX,outsl)(unsigned long, const void *src, unsigned long count); 35 35 36 - u8 IO_CONCAT(__IO_PREFIX,readb)(void __iomem *); 37 - u16 IO_CONCAT(__IO_PREFIX,readw)(void __iomem *); 38 - u32 IO_CONCAT(__IO_PREFIX,readl)(void __iomem *); 39 - void IO_CONCAT(__IO_PREFIX,writeb)(u8, void __iomem *); 40 - void IO_CONCAT(__IO_PREFIX,writew)(u16, void __iomem *); 41 - void IO_CONCAT(__IO_PREFIX,writel)(u32, void __iomem *); 42 - 43 36 void *IO_CONCAT(__IO_PREFIX,ioremap)(unsigned long offset, unsigned long size); 44 37 void IO_CONCAT(__IO_PREFIX,iounmap)(void *addr); 45 38
-7
arch/sh/include/asm/machvec.h
··· 42 42 void (*mv_outsw)(unsigned long, const void *src, unsigned long count); 43 43 void (*mv_outsl)(unsigned long, const void *src, unsigned long count); 44 44 45 - u8 (*mv_readb)(void __iomem *); 46 - u16 (*mv_readw)(void __iomem *); 47 - u32 (*mv_readl)(void __iomem *); 48 - void (*mv_writeb)(u8, void __iomem *); 49 - void (*mv_writew)(u16, void __iomem *); 50 - void (*mv_writel)(u32, void __iomem *); 51 - 52 45 int (*mv_irq_demux)(int irq); 53 46 54 47 void (*mv_init_irq)(void);
+6 -6
arch/sh/kernel/io.c
··· 19 19 * Copy data from IO memory space to "real" memory space. 20 20 * This needs to be optimized. 21 21 */ 22 - void memcpy_fromio(void *to, volatile void __iomem *from, unsigned long count) 22 + void memcpy_fromio(void *to, const volatile void __iomem *from, unsigned long count) 23 23 { 24 - char *p = to; 24 + unsigned char *p = to; 25 25 while (count) { 26 26 count--; 27 - *p = readb((void __iomem *)from); 27 + *p = readb(from); 28 28 p++; 29 29 from++; 30 30 } ··· 37 37 */ 38 38 void memcpy_toio(volatile void __iomem *to, const void *from, unsigned long count) 39 39 { 40 - const char *p = from; 40 + const unsigned char *p = from; 41 41 while (count) { 42 42 count--; 43 - writeb(*p, (void __iomem *)to); 43 + writeb(*p, to); 44 44 p++; 45 45 to++; 46 46 } ··· 55 55 { 56 56 while (count) { 57 57 count--; 58 - writeb(c, (void __iomem *)dst); 58 + writeb(c, dst); 59 59 dst++; 60 60 } 61 61 }
+13 -48
arch/sh/kernel/io_generic.c
··· 19 19 /* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a 20 20 * workaround. */ 21 21 /* I'm not sure SH7709 has this kind of bug */ 22 - #define dummy_read() ctrl_inb(0xba000000) 22 + #define dummy_read() __raw_readb(0xba000000) 23 23 #else 24 24 #define dummy_read() 25 25 #endif 26 26 27 27 unsigned long generic_io_base; 28 28 29 - static inline void delay(void) 30 - { 31 - ctrl_inw(0xa0000000); 32 - } 33 - 34 29 u8 generic_inb(unsigned long port) 35 30 { 36 - return ctrl_inb((unsigned long __force)__ioport_map(port, 1)); 31 + return __raw_readb(__ioport_map(port, 1)); 37 32 } 38 33 39 34 u16 generic_inw(unsigned long port) 40 35 { 41 - return ctrl_inw((unsigned long __force)__ioport_map(port, 2)); 36 + return __raw_readw(__ioport_map(port, 2)); 42 37 } 43 38 44 39 u32 generic_inl(unsigned long port) 45 40 { 46 - return ctrl_inl((unsigned long __force)__ioport_map(port, 4)); 41 + return __raw_readl(__ioport_map(port, 4)); 47 42 } 48 43 49 44 u8 generic_inb_p(unsigned long port) 50 45 { 51 46 unsigned long v = generic_inb(port); 52 47 53 - delay(); 48 + ctrl_delay(); 54 49 return v; 55 50 } 56 51 ··· 53 58 { 54 59 unsigned long v = generic_inw(port); 55 60 56 - delay(); 61 + ctrl_delay(); 57 62 return v; 58 63 } 59 64 ··· 61 66 { 62 67 unsigned long v = generic_inl(port); 63 68 64 - delay(); 69 + ctrl_delay(); 65 70 return v; 66 71 } 67 72 ··· 107 112 108 113 void generic_outb(u8 b, unsigned long port) 109 114 { 110 - ctrl_outb(b, (unsigned long __force)__ioport_map(port, 1)); 115 + __raw_writeb(b, __ioport_map(port, 1)); 111 116 } 112 117 113 118 void generic_outw(u16 b, unsigned long port) 114 119 { 115 - ctrl_outw(b, (unsigned long __force)__ioport_map(port, 2)); 120 + __raw_writew(b, __ioport_map(port, 2)); 116 121 } 117 122 118 123 void generic_outl(u32 b, unsigned long port) 119 124 { 120 - ctrl_outl(b, (unsigned long __force)__ioport_map(port, 4)); 125 + __raw_writel(b, __ioport_map(port, 4)); 121 126 } 122 127 123 128 void generic_outb_p(u8 b, unsigned long port) 124 129 { 125 130 generic_outb(b, port); 126 - delay(); 131 + ctrl_delay(); 127 132 } 128 133 129 134 void generic_outw_p(u16 b, unsigned long port) 130 135 { 131 136 generic_outw(b, port); 132 - delay(); 137 + ctrl_delay(); 133 138 } 134 139 135 140 void generic_outl_p(u32 b, unsigned long port) 136 141 { 137 142 generic_outl(b, port); 138 - delay(); 143 + ctrl_delay(); 139 144 } 140 145 141 146 /* ··· 177 182 *port_addr = *buf++; 178 183 179 184 dummy_read(); 180 - } 181 - 182 - u8 generic_readb(void __iomem *addr) 183 - { 184 - return ctrl_inb((unsigned long __force)addr); 185 - } 186 - 187 - u16 generic_readw(void __iomem *addr) 188 - { 189 - return ctrl_inw((unsigned long __force)addr); 190 - } 191 - 192 - u32 generic_readl(void __iomem *addr) 193 - { 194 - return ctrl_inl((unsigned long __force)addr); 195 - } 196 - 197 - void generic_writeb(u8 b, void __iomem *addr) 198 - { 199 - ctrl_outb(b, (unsigned long __force)addr); 200 - } 201 - 202 - void generic_writew(u16 b, void __iomem *addr) 203 - { 204 - ctrl_outw(b, (unsigned long __force)addr); 205 - } 206 - 207 - void generic_writel(u32 b, void __iomem *addr) 208 - { 209 - ctrl_outl(b, (unsigned long __force)addr); 210 185 } 211 186 212 187 void __iomem *generic_ioport_map(unsigned long addr, unsigned int size)
-3
arch/sh/kernel/machvec.c
··· 126 126 mv_set(insb); mv_set(insw); mv_set(insl); 127 127 mv_set(outsb); mv_set(outsw); mv_set(outsl); 128 128 129 - mv_set(readb); mv_set(readw); mv_set(readl); 130 - mv_set(writeb); mv_set(writew); mv_set(writel); 131 - 132 129 mv_set(ioport_map); 133 130 mv_set(ioport_unmap); 134 131 mv_set(irq_demux);