1 /* 2 * arch/arm/mach-rpc/include/mach/io.h 3 * 4 * Copyright (C) 1997 Russell King 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * Modifications: 11 * 06-Dec-1997 RMK Created. 12 */ 13 #ifndef __ASM_ARM_ARCH_IO_H 14 #define __ASM_ARM_ARCH_IO_H 15 16 #include <mach/hardware.h> 17 18 #define IO_SPACE_LIMIT 0xffffffff 19 20 /* 21 * GCC is totally crap at loading/storing data. We try to persuade it 22 * to do the right thing by using these whereever possible instead of 23 * the above. 24 */ 25 #define __arch_base_getb(b,o) \ 26 ({ \ 27 unsigned int __v, __r = (b); \ 28 __asm__ __volatile__( \ 29 "ldrb %0, [%1, %2]" \ 30 : "=r" (__v) \ 31 : "r" (__r), "Ir" (o)); \ 32 __v; \ 33 }) 34 35 #define __arch_base_getl(b,o) \ 36 ({ \ 37 unsigned int __v, __r = (b); \ 38 __asm__ __volatile__( \ 39 "ldr %0, [%1, %2]" \ 40 : "=r" (__v) \ 41 : "r" (__r), "Ir" (o)); \ 42 __v; \ 43 }) 44 45 #define __arch_base_putb(v,b,o) \ 46 ({ \ 47 unsigned int __r = (b); \ 48 __asm__ __volatile__( \ 49 "strb %0, [%1, %2]" \ 50 : \ 51 : "r" (v), "r" (__r), "Ir" (o));\ 52 }) 53 54 #define __arch_base_putl(v,b,o) \ 55 ({ \ 56 unsigned int __r = (b); \ 57 __asm__ __volatile__( \ 58 "str %0, [%1, %2]" \ 59 : \ 60 : "r" (v), "r" (__r), "Ir" (o));\ 61 }) 62 63 /* 64 * We use two different types of addressing - PC style addresses, and ARM 65 * addresses. PC style accesses the PC hardware with the normal PC IO 66 * addresses, eg 0x3f8 for serial#1. ARM addresses are 0x80000000+ 67 * and are translated to the start of IO. Note that all addresses are 68 * shifted left! 69 */ 70 #define __PORT_PCIO(x) (!((x) & 0x80000000)) 71 72 /* 73 * Dynamic IO functions. 74 */ 75 static inline void __outb (unsigned int value, unsigned int port) 76 { 77 unsigned long temp; 78 __asm__ __volatile__( 79 "tst %2, #0x80000000\n\t" 80 "mov %0, %4\n\t" 81 "addeq %0, %0, %3\n\t" 82 "strb %1, [%0, %2, lsl #2] @ outb" 83 : "=&r" (temp) 84 : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) 85 : "cc"); 86 } 87 88 static inline void __outw (unsigned int value, unsigned int port) 89 { 90 unsigned long temp; 91 __asm__ __volatile__( 92 "tst %2, #0x80000000\n\t" 93 "mov %0, %4\n\t" 94 "addeq %0, %0, %3\n\t" 95 "str %1, [%0, %2, lsl #2] @ outw" 96 : "=&r" (temp) 97 : "r" (value|value<<16), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) 98 : "cc"); 99 } 100 101 static inline void __outl (unsigned int value, unsigned int port) 102 { 103 unsigned long temp; 104 __asm__ __volatile__( 105 "tst %2, #0x80000000\n\t" 106 "mov %0, %4\n\t" 107 "addeq %0, %0, %3\n\t" 108 "str %1, [%0, %2, lsl #2] @ outl" 109 : "=&r" (temp) 110 : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) 111 : "cc"); 112 } 113 114 #define DECLARE_DYN_IN(sz,fnsuffix,instr) \ 115 static inline unsigned sz __in##fnsuffix (unsigned int port) \ 116 { \ 117 unsigned long temp, value; \ 118 __asm__ __volatile__( \ 119 "tst %2, #0x80000000\n\t" \ 120 "mov %0, %4\n\t" \ 121 "addeq %0, %0, %3\n\t" \ 122 "ldr" instr " %1, [%0, %2, lsl #2] @ in" #fnsuffix \ 123 : "=&r" (temp), "=r" (value) \ 124 : "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) \ 125 : "cc"); \ 126 return (unsigned sz)value; \ 127 } 128 129 static inline void __iomem *__deprecated __ioaddr(unsigned int port) 130 { 131 void __iomem *ret; 132 if (__PORT_PCIO(port)) 133 ret = PCIO_BASE; 134 else 135 ret = IO_BASE; 136 return ret + (port << 2); 137 } 138 139 #define DECLARE_IO(sz,fnsuffix,instr) \ 140 DECLARE_DYN_IN(sz,fnsuffix,instr) 141 142 DECLARE_IO(char,b,"b") 143 DECLARE_IO(short,w,"") 144 DECLARE_IO(int,l,"") 145 146 #undef DECLARE_IO 147 #undef DECLARE_DYN_IN 148 149 /* 150 * Constant address IO functions 151 * 152 * These have to be macros for the 'J' constraint to work - 153 * +/-4096 immediate operand. 154 */ 155 #define __outbc(value,port) \ 156 ({ \ 157 if (__PORT_PCIO((port))) \ 158 __asm__ __volatile__( \ 159 "strb %0, [%1, %2] @ outbc" \ 160 : : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 161 else \ 162 __asm__ __volatile__( \ 163 "strb %0, [%1, %2] @ outbc" \ 164 : : "r" (value), "r" (IO_BASE), "r" ((port) << 2)); \ 165 }) 166 167 #define __inbc(port) \ 168 ({ \ 169 unsigned char result; \ 170 if (__PORT_PCIO((port))) \ 171 __asm__ __volatile__( \ 172 "ldrb %0, [%1, %2] @ inbc" \ 173 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 174 else \ 175 __asm__ __volatile__( \ 176 "ldrb %0, [%1, %2] @ inbc" \ 177 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ 178 result; \ 179 }) 180 181 #define __outwc(value,port) \ 182 ({ \ 183 unsigned long __v = value; \ 184 if (__PORT_PCIO((port))) \ 185 __asm__ __volatile__( \ 186 "str %0, [%1, %2] @ outwc" \ 187 : : "r" (__v|__v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 188 else \ 189 __asm__ __volatile__( \ 190 "str %0, [%1, %2] @ outwc" \ 191 : : "r" (__v|__v<<16), "r" (IO_BASE), "r" ((port) << 2)); \ 192 }) 193 194 #define __inwc(port) \ 195 ({ \ 196 unsigned short result; \ 197 if (__PORT_PCIO((port))) \ 198 __asm__ __volatile__( \ 199 "ldr %0, [%1, %2] @ inwc" \ 200 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 201 else \ 202 __asm__ __volatile__( \ 203 "ldr %0, [%1, %2] @ inwc" \ 204 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ 205 result & 0xffff; \ 206 }) 207 208 #define __outlc(value,port) \ 209 ({ \ 210 unsigned long __v = value; \ 211 if (__PORT_PCIO((port))) \ 212 __asm__ __volatile__( \ 213 "str %0, [%1, %2] @ outlc" \ 214 : : "r" (__v), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 215 else \ 216 __asm__ __volatile__( \ 217 "str %0, [%1, %2] @ outlc" \ 218 : : "r" (__v), "r" (IO_BASE), "r" ((port) << 2)); \ 219 }) 220 221 #define __inlc(port) \ 222 ({ \ 223 unsigned long result; \ 224 if (__PORT_PCIO((port))) \ 225 __asm__ __volatile__( \ 226 "ldr %0, [%1, %2] @ inlc" \ 227 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 228 else \ 229 __asm__ __volatile__( \ 230 "ldr %0, [%1, %2] @ inlc" \ 231 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ 232 result; \ 233 }) 234 235 #define __ioaddrc(port) __ioaddr(port) 236 237 #define inb(p) (__builtin_constant_p((p)) ? __inbc(p) : __inb(p)) 238 #define inw(p) (__builtin_constant_p((p)) ? __inwc(p) : __inw(p)) 239 #define inl(p) (__builtin_constant_p((p)) ? __inlc(p) : __inl(p)) 240 #define outb(v,p) (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p)) 241 #define outw(v,p) (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p)) 242 #define outl(v,p) (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p)) 243 #define __ioaddr(p) (__builtin_constant_p((p)) ? __ioaddr(p) : __ioaddrc(p)) 244 /* the following macro is deprecated */ 245 #define ioaddr(port) ((unsigned long)__ioaddr((port))) 246 247 #define insb(p,d,l) __raw_readsb(__ioaddr(p),d,l) 248 #define insw(p,d,l) __raw_readsw(__ioaddr(p),d,l) 249 250 #define outsb(p,d,l) __raw_writesb(__ioaddr(p),d,l) 251 #define outsw(p,d,l) __raw_writesw(__ioaddr(p),d,l) 252 253 /* 254 * 1:1 mapping for ioremapped regions. 255 */ 256 #define __mem_pci(x) (x) 257 258 #endif 259