1 /* SPDX-License-Identifier: GPL-2.0+ */ 2 /* 3 * IO header file 4 * 5 * Copyright (C) 2004-2007, 2012 Freescale Semiconductor, Inc. 6 * TsiChung Liew (Tsi-Chung.Liew@freescale.com) 7 */ 8 9 #ifndef __ASM_M68K_IO_H__ 10 #define __ASM_M68K_IO_H__ 11 12 #include <asm/byteorder.h> 13 14 #ifndef _IO_BASE 15 #define _IO_BASE 0 16 #endif 17 18 #define __raw_readb(addr) (*(volatile u8 *)(addr)) 19 #define __raw_readw(addr) (*(volatile u16 *)(addr)) 20 #define __raw_readl(addr) (*(volatile u32 *)(addr)) 21 22 #define __raw_writeb(b,addr) ((*(volatile u8 *) (addr)) = (b)) 23 #define __raw_writew(w,addr) ((*(volatile u16 *) (addr)) = (w)) 24 #define __raw_writel(l,addr) ((*(volatile u32 *) (addr)) = (l)) 25 26 #define readb(addr) in_8((volatile u8 *)(addr)) 27 #define writeb(b,addr) out_8((volatile u8 *)(addr), (b)) 28 #if !defined(__BIG_ENDIAN) 29 #define readw(addr) (*(volatile u16 *) (addr)) 30 #define readl(addr) (*(volatile u32 *) (addr)) 31 #define writew(b,addr) ((*(volatile u16 *) (addr)) = (b)) 32 #define writel(b,addr) ((*(volatile u32 *) (addr)) = (b)) 33 #else 34 #define readw(addr) in_be16((volatile u16 *)(addr)) 35 #define readl(addr) in_be32((volatile u32 *)(addr)) 36 #define writew(b,addr) out_be16((volatile u16 *)(addr),(b)) 37 #define writel(b,addr) out_be32((volatile u32 *)(addr),(b)) 38 #endif 39 40 /* 41 * The insw/outsw/insl/outsl macros don't do byte-swapping. 42 * They are only used in practice for transferring buffers which 43 * are arrays of bytes, and byte-swapping is not appropriate in 44 * that case. - paulus 45 */ 46 #define insb(port, buf, ns) _insb((u8 *)((port)+_IO_BASE), (buf), (ns)) 47 #define outsb(port, buf, ns) _outsb((u8 *)((port)+_IO_BASE), (buf), (ns)) 48 #define insw(port, buf, ns) _insw_ns((u16 *)((port)+_IO_BASE), (buf), (ns)) 49 #define outsw(port, buf, ns) _outsw_ns((u16 *)((port)+_IO_BASE), (buf), (ns)) 50 #define insl(port, buf, nl) _insl_ns((u32 *)((port)+_IO_BASE), (buf), (nl)) 51 #define outsl(port, buf, nl) _outsl_ns((u32 *)((port)+_IO_BASE), (buf), (nl)) 52 53 #define inb(port) in_8((u8 *)((port)+_IO_BASE)) 54 #define outb(val, port) out_8((u8 *)((port)+_IO_BASE), (val)) 55 #if !defined(__BIG_ENDIAN) 56 #define inw(port) in_be16((u16 *)((port)+_IO_BASE)) 57 #define outw(val, port) out_be16((u16 *)((port)+_IO_BASE), (val)) 58 #define inl(port) in_be32((u32 *)((port)+_IO_BASE)) 59 #define outl(val, port) out_be32((u32 *)((port)+_IO_BASE), (val)) 60 #else 61 #define inw(port) in_le16((u16 *)((port)+_IO_BASE)) 62 #define outw(val, port) out_le16((u16 *)((port)+_IO_BASE), (val)) 63 #define inl(port) in_le32((u32 *)((port)+_IO_BASE)) 64 #define outl(val, port) out_le32((u32 *)((port)+_IO_BASE), (val)) 65 #endif 66 67 #define mb() __asm__ __volatile__ ("" : : : "memory") 68 69 static inline void _insb(volatile u8 * port, void *buf, int ns) 70 { 71 u8 *data = (u8 *) buf; 72 while (ns--) 73 *data++ = *port; 74 } 75 76 static inline void _outsb(volatile u8 * port, const void *buf, int ns) 77 { 78 u8 *data = (u8 *) buf; 79 while (ns--) 80 *port = *data++; 81 } 82 83 static inline void _insw(volatile u16 * port, void *buf, int ns) 84 { 85 u16 *data = (u16 *) buf; 86 while (ns--) 87 *data++ = __sw16(*port); 88 } 89 90 static inline void _outsw(volatile u16 * port, const void *buf, int ns) 91 { 92 u16 *data = (u16 *) buf; 93 while (ns--) { 94 *port = __sw16(*data); 95 data++; 96 } 97 } 98 99 static inline void _insl(volatile u32 * port, void *buf, int nl) 100 { 101 u32 *data = (u32 *) buf; 102 while (nl--) 103 *data++ = __sw32(*port); 104 } 105 106 static inline void _outsl(volatile u32 * port, const void *buf, int nl) 107 { 108 u32 *data = (u32 *) buf; 109 while (nl--) { 110 *port = __sw32(*data); 111 data++; 112 } 113 } 114 115 static inline void _insw_ns(volatile u16 * port, void *buf, int ns) 116 { 117 u16 *data = (u16 *) buf; 118 while (ns--) 119 *data++ = *port; 120 } 121 122 static inline void _outsw_ns(volatile u16 * port, const void *buf, int ns) 123 { 124 u16 *data = (u16 *) buf; 125 while (ns--) { 126 *port = *data++; 127 } 128 } 129 130 static inline void _insl_ns(volatile u32 * port, void *buf, int nl) 131 { 132 u32 *data = (u32 *) buf; 133 while (nl--) 134 *data++ = *port; 135 } 136 137 static inline void _outsl_ns(volatile u32 * port, const void *buf, int nl) 138 { 139 u32 *data = (u32 *) buf; 140 while (nl--) { 141 *port = *data; 142 data++; 143 } 144 } 145 146 /* 147 * The *_ns versions below don't do byte-swapping. 148 * Neither do the standard versions now, these are just here 149 * for older code. 150 */ 151 #define insw_ns(port, buf, ns) _insw_ns((u16 *)((port)+_IO_BASE), (buf), (ns)) 152 #define outsw_ns(port, buf, ns) _outsw_ns((u16 *)((port)+_IO_BASE), (buf), (ns)) 153 #define insl_ns(port, buf, nl) _insl_ns((u32 *)((port)+_IO_BASE), (buf), (nl)) 154 #define outsl_ns(port, buf, nl) _outsl_ns((u32 *)((port)+_IO_BASE), (buf), (nl)) 155 156 #define IO_SPACE_LIMIT ~0 157 158 /* 159 * 8, 16 and 32 bit, big and little endian I/O operations, with barrier. 160 */ 161 static inline int in_8(volatile u8 * addr) 162 { 163 return (int)*addr; 164 } 165 166 static inline void out_8(volatile u8 * addr, int val) 167 { 168 *addr = (u8) val; 169 } 170 171 static inline int in_le16(volatile u16 * addr) 172 { 173 return __sw16(*addr); 174 } 175 176 static inline int in_be16(volatile u16 * addr) 177 { 178 return (*addr & 0xFFFF); 179 } 180 181 static inline void out_le16(volatile u16 * addr, int val) 182 { 183 *addr = __sw16(val); 184 } 185 186 static inline void out_be16(volatile u16 * addr, int val) 187 { 188 *addr = (u16) val; 189 } 190 191 static inline unsigned in_le32(volatile u32 * addr) 192 { 193 return __sw32(*addr); 194 } 195 196 static inline unsigned in_be32(volatile u32 * addr) 197 { 198 return (*addr); 199 } 200 201 static inline void out_le32(volatile unsigned *addr, int val) 202 { 203 *addr = __sw32(val); 204 } 205 206 static inline void out_be32(volatile unsigned *addr, int val) 207 { 208 *addr = val; 209 } 210 211 /* Clear and set bits in one shot. These macros can be used to clear and 212 * set multiple bits in a register using a single call. These macros can 213 * also be used to set a multiple-bit bit pattern using a mask, by 214 * specifying the mask in the 'clear' parameter and the new bit pattern 215 * in the 'set' parameter. 216 */ 217 218 #define clrbits(type, addr, clear) \ 219 out_##type((addr), in_##type(addr) & ~(clear)) 220 221 #define setbits(type, addr, set) \ 222 out_##type((addr), in_##type(addr) | (set)) 223 224 #define clrsetbits(type, addr, clear, set) \ 225 out_##type((addr), (in_##type(addr) & ~(clear)) | (set)) 226 227 #define clrbits_be32(addr, clear) clrbits(be32, addr, clear) 228 #define setbits_be32(addr, set) setbits(be32, addr, set) 229 #define clrsetbits_be32(addr, clear, set) clrsetbits(be32, addr, clear, set) 230 231 #define clrbits_le32(addr, clear) clrbits(le32, addr, clear) 232 #define setbits_le32(addr, set) setbits(le32, addr, set) 233 #define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set) 234 235 #define clrbits_be16(addr, clear) clrbits(be16, addr, clear) 236 #define setbits_be16(addr, set) setbits(be16, addr, set) 237 #define clrsetbits_be16(addr, clear, set) clrsetbits(be16, addr, clear, set) 238 239 #define clrbits_le16(addr, clear) clrbits(le16, addr, clear) 240 #define setbits_le16(addr, set) setbits(le16, addr, set) 241 #define clrsetbits_le16(addr, clear, set) clrsetbits(le16, addr, clear, set) 242 243 #define clrbits_8(addr, clear) clrbits(8, addr, clear) 244 #define setbits_8(addr, set) setbits(8, addr, set) 245 #define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set) 246 247 static inline void sync(void) 248 { 249 /* This sync function is for PowerPC or other architecture instruction 250 * ColdFire does not have this instruction. Dummy function, added for 251 * compatibility (CFI driver) 252 */ 253 } 254 255 #include <asm-generic/io.h> 256 257 #endif /* __ASM_M68K_IO_H__ */ 258