1 /* 2 * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #ifndef __ASM_ARC_IO_H 8 #define __ASM_ARC_IO_H 9 10 #include <linux/types.h> 11 #include <asm/byteorder.h> 12 13 static inline void sync(void) 14 { 15 /* Not yet implemented */ 16 } 17 18 static inline u8 __raw_readb(const volatile void __iomem *addr) 19 { 20 u8 b; 21 22 __asm__ __volatile__("ldb%U1 %0, %1\n" 23 : "=r" (b) 24 : "m" (*(volatile u8 __force *)addr) 25 : "memory"); 26 return b; 27 } 28 29 static inline u16 __raw_readw(const volatile void __iomem *addr) 30 { 31 u16 s; 32 33 __asm__ __volatile__("ldw%U1 %0, %1\n" 34 : "=r" (s) 35 : "m" (*(volatile u16 __force *)addr) 36 : "memory"); 37 return s; 38 } 39 40 static inline u32 __raw_readl(const volatile void __iomem *addr) 41 { 42 u32 w; 43 44 __asm__ __volatile__("ld%U1 %0, %1\n" 45 : "=r" (w) 46 : "m" (*(volatile u32 __force *)addr) 47 : "memory"); 48 return w; 49 } 50 51 #define readb __raw_readb 52 53 static inline u16 readw(const volatile void __iomem *addr) 54 { 55 return __le16_to_cpu(__raw_readw(addr)); 56 } 57 58 static inline u32 readl(const volatile void __iomem *addr) 59 { 60 return __le32_to_cpu(__raw_readl(addr)); 61 } 62 63 static inline void __raw_writeb(u8 b, volatile void __iomem *addr) 64 { 65 __asm__ __volatile__("stb%U1 %0, %1\n" 66 : 67 : "r" (b), "m" (*(volatile u8 __force *)addr) 68 : "memory"); 69 } 70 71 static inline void __raw_writew(u16 s, volatile void __iomem *addr) 72 { 73 __asm__ __volatile__("stw%U1 %0, %1\n" 74 : 75 : "r" (s), "m" (*(volatile u16 __force *)addr) 76 : "memory"); 77 } 78 79 static inline void __raw_writel(u32 w, volatile void __iomem *addr) 80 { 81 __asm__ __volatile__("st%U1 %0, %1\n" 82 : 83 : "r" (w), "m" (*(volatile u32 __force *)addr) 84 : "memory"); 85 } 86 87 #define writeb __raw_writeb 88 #define writew(b, addr) __raw_writew(__cpu_to_le16(b), addr) 89 #define writel(b, addr) __raw_writel(__cpu_to_le32(b), addr) 90 91 static inline int __raw_readsb(unsigned int addr, void *data, int bytelen) 92 { 93 __asm__ __volatile__ ("1:ld.di r8, [r0]\n" 94 "sub.f r2, r2, 1\n" 95 "bnz.d 1b\n" 96 "stb.ab r8, [r1, 1]\n" 97 : 98 : "r" (addr), "r" (data), "r" (bytelen) 99 : "r8"); 100 return bytelen; 101 } 102 103 static inline int __raw_readsw(unsigned int addr, void *data, int wordlen) 104 { 105 __asm__ __volatile__ ("1:ld.di r8, [r0]\n" 106 "sub.f r2, r2, 1\n" 107 "bnz.d 1b\n" 108 "stw.ab r8, [r1, 2]\n" 109 : 110 : "r" (addr), "r" (data), "r" (wordlen) 111 : "r8"); 112 return wordlen; 113 } 114 115 static inline int __raw_readsl(unsigned int addr, void *data, int longlen) 116 { 117 __asm__ __volatile__ ("1:ld.di r8, [r0]\n" 118 "sub.f r2, r2, 1\n" 119 "bnz.d 1b\n" 120 "st.ab r8, [r1, 4]\n" 121 : 122 : "r" (addr), "r" (data), "r" (longlen) 123 : "r8"); 124 return longlen; 125 } 126 127 static inline int __raw_writesb(unsigned int addr, void *data, int bytelen) 128 { 129 __asm__ __volatile__ ("1:ldb.ab r8, [r1, 1]\n" 130 "sub.f r2, r2, 1\n" 131 "bnz.d 1b\n" 132 "st.di r8, [r0, 0]\n" 133 : 134 : "r" (addr), "r" (data), "r" (bytelen) 135 : "r8"); 136 return bytelen; 137 } 138 139 static inline int __raw_writesw(unsigned int addr, void *data, int wordlen) 140 { 141 __asm__ __volatile__ ("1:ldw.ab r8, [r1, 2]\n" 142 "sub.f r2, r2, 1\n" 143 "bnz.d 1b\n" 144 "st.ab.di r8, [r0, 0]\n" 145 : 146 : "r" (addr), "r" (data), "r" (wordlen) 147 : "r8"); 148 return wordlen; 149 } 150 151 static inline int __raw_writesl(unsigned int addr, void *data, int longlen) 152 { 153 __asm__ __volatile__ ("1:ld.ab r8, [r1, 4]\n" 154 "sub.f r2, r2, 1\n" 155 "bnz.d 1b\n" 156 "st.ab.di r8, [r0, 0]\n" 157 : 158 : "r" (addr), "r" (data), "r" (longlen) 159 : "r8"); 160 return longlen; 161 } 162 163 #define out_arch(type, endian, a, v) __raw_write##type(cpu_to_##endian(v), a) 164 #define in_arch(type, endian, a) endian##_to_cpu(__raw_read##type(a)) 165 166 #define out_le32(a, v) out_arch(l, le32, a, v) 167 #define out_le16(a, v) out_arch(w, le16, a, v) 168 169 #define in_le32(a) in_arch(l, le32, a) 170 #define in_le16(a) in_arch(w, le16, a) 171 172 #define out_be32(a, v) out_arch(l, be32, a, v) 173 #define out_be16(a, v) out_arch(w, be16, a, v) 174 175 #define in_be32(a) in_arch(l, be32, a) 176 #define in_be16(a) in_arch(w, be16, a) 177 178 #define out_8(a, v) __raw_writeb(v, a) 179 #define in_8(a) __raw_readb(a) 180 181 /* 182 * Clear and set bits in one shot. These macros can be used to clear and 183 * set multiple bits in a register using a single call. These macros can 184 * also be used to set a multiple-bit bit pattern using a mask, by 185 * specifying the mask in the 'clear' parameter and the new bit pattern 186 * in the 'set' parameter. 187 */ 188 189 #define clrbits(type, addr, clear) \ 190 out_##type((addr), in_##type(addr) & ~(clear)) 191 192 #define setbits(type, addr, set) \ 193 out_##type((addr), in_##type(addr) | (set)) 194 195 #define clrsetbits(type, addr, clear, set) \ 196 out_##type((addr), (in_##type(addr) & ~(clear)) | (set)) 197 198 #define clrbits_be32(addr, clear) clrbits(be32, addr, clear) 199 #define setbits_be32(addr, set) setbits(be32, addr, set) 200 #define clrsetbits_be32(addr, clear, set) clrsetbits(be32, addr, clear, set) 201 202 #define clrbits_le32(addr, clear) clrbits(le32, addr, clear) 203 #define setbits_le32(addr, set) setbits(le32, addr, set) 204 #define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set) 205 206 #define clrbits_be16(addr, clear) clrbits(be16, addr, clear) 207 #define setbits_be16(addr, set) setbits(be16, addr, set) 208 #define clrsetbits_be16(addr, clear, set) clrsetbits(be16, addr, clear, set) 209 210 #define clrbits_le16(addr, clear) clrbits(le16, addr, clear) 211 #define setbits_le16(addr, set) setbits(le16, addr, set) 212 #define clrsetbits_le16(addr, clear, set) clrsetbits(le16, addr, clear, set) 213 214 #define clrbits_8(addr, clear) clrbits(8, addr, clear) 215 #define setbits_8(addr, set) setbits(8, addr, set) 216 #define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set) 217 218 #endif /* __ASM_ARC_IO_H */ 219