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 69static inline void _insb(volatile u8 * port, void *buf, int ns) 70{ 71 u8 *data = (u8 *) buf; 72 while (ns--) 73 *data++ = *port; 74} 75 76static 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 83static 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 90static 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 99static 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 106static 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 115static 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 122static 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 130static 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 137static 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 */ 161static inline int in_8(volatile u8 * addr) 162{ 163 return (int)*addr; 164} 165 166static inline void out_8(volatile u8 * addr, int val) 167{ 168 *addr = (u8) val; 169} 170 171static inline int in_le16(volatile u16 * addr) 172{ 173 return __sw16(*addr); 174} 175 176static inline int in_be16(volatile u16 * addr) 177{ 178 return (*addr & 0xFFFF); 179} 180 181static inline void out_le16(volatile u16 * addr, int val) 182{ 183 *addr = __sw16(val); 184} 185 186static inline void out_be16(volatile u16 * addr, int val) 187{ 188 *addr = (u16) val; 189} 190 191static inline unsigned in_le32(volatile u32 * addr) 192{ 193 return __sw32(*addr); 194} 195 196static inline unsigned in_be32(volatile u32 * addr) 197{ 198 return (*addr); 199} 200 201static inline void out_le32(volatile unsigned *addr, int val) 202{ 203 *addr = __sw32(val); 204} 205 206static 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 247static 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