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 * We use two different types of addressing - PC style addresses, and ARM 22 * addresses. PC style accesses the PC hardware with the normal PC IO 23 * addresses, eg 0x3f8 for serial#1. ARM addresses are 0x80000000+ 24 * and are translated to the start of IO. Note that all addresses are 25 * shifted left! 26 */ 27#define __PORT_PCIO(x) (!((x) & 0x80000000)) 28 29/* 30 * Dynamic IO functions. 31 */ 32static inline void __outb (unsigned int value, unsigned int port) 33{ 34 unsigned long temp; 35 __asm__ __volatile__( 36 "tst %2, #0x80000000\n\t" 37 "mov %0, %4\n\t" 38 "addeq %0, %0, %3\n\t" 39 "strb %1, [%0, %2, lsl #2] @ outb" 40 : "=&r" (temp) 41 : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) 42 : "cc"); 43} 44 45static inline void __outw (unsigned int value, unsigned int port) 46{ 47 unsigned long temp; 48 __asm__ __volatile__( 49 "tst %2, #0x80000000\n\t" 50 "mov %0, %4\n\t" 51 "addeq %0, %0, %3\n\t" 52 "str %1, [%0, %2, lsl #2] @ outw" 53 : "=&r" (temp) 54 : "r" (value|value<<16), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) 55 : "cc"); 56} 57 58static inline void __outl (unsigned int value, unsigned int port) 59{ 60 unsigned long temp; 61 __asm__ __volatile__( 62 "tst %2, #0x80000000\n\t" 63 "mov %0, %4\n\t" 64 "addeq %0, %0, %3\n\t" 65 "str %1, [%0, %2, lsl #2] @ outl" 66 : "=&r" (temp) 67 : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) 68 : "cc"); 69} 70 71#define DECLARE_DYN_IN(sz,fnsuffix,instr) \ 72static inline unsigned sz __in##fnsuffix (unsigned int port) \ 73{ \ 74 unsigned long temp, value; \ 75 __asm__ __volatile__( \ 76 "tst %2, #0x80000000\n\t" \ 77 "mov %0, %4\n\t" \ 78 "addeq %0, %0, %3\n\t" \ 79 "ldr" instr " %1, [%0, %2, lsl #2] @ in" #fnsuffix \ 80 : "=&r" (temp), "=r" (value) \ 81 : "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) \ 82 : "cc"); \ 83 return (unsigned sz)value; \ 84} 85 86static inline void __iomem *__deprecated __ioaddr(unsigned int port) 87{ 88 void __iomem *ret; 89 if (__PORT_PCIO(port)) 90 ret = PCIO_BASE; 91 else 92 ret = IO_BASE; 93 return ret + (port << 2); 94} 95 96#define DECLARE_IO(sz,fnsuffix,instr) \ 97 DECLARE_DYN_IN(sz,fnsuffix,instr) 98 99DECLARE_IO(char,b,"b") 100DECLARE_IO(short,w,"") 101DECLARE_IO(int,l,"") 102 103#undef DECLARE_IO 104#undef DECLARE_DYN_IN 105 106/* 107 * Constant address IO functions 108 * 109 * These have to be macros for the 'J' constraint to work - 110 * +/-4096 immediate operand. 111 */ 112#define __outbc(value,port) \ 113({ \ 114 if (__PORT_PCIO((port))) \ 115 __asm__ __volatile__( \ 116 "strb %0, [%1, %2] @ outbc" \ 117 : : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 118 else \ 119 __asm__ __volatile__( \ 120 "strb %0, [%1, %2] @ outbc" \ 121 : : "r" (value), "r" (IO_BASE), "r" ((port) << 2)); \ 122}) 123 124#define __inbc(port) \ 125({ \ 126 unsigned char result; \ 127 if (__PORT_PCIO((port))) \ 128 __asm__ __volatile__( \ 129 "ldrb %0, [%1, %2] @ inbc" \ 130 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 131 else \ 132 __asm__ __volatile__( \ 133 "ldrb %0, [%1, %2] @ inbc" \ 134 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ 135 result; \ 136}) 137 138#define __outwc(value,port) \ 139({ \ 140 unsigned long __v = value; \ 141 if (__PORT_PCIO((port))) \ 142 __asm__ __volatile__( \ 143 "str %0, [%1, %2] @ outwc" \ 144 : : "r" (__v|__v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 145 else \ 146 __asm__ __volatile__( \ 147 "str %0, [%1, %2] @ outwc" \ 148 : : "r" (__v|__v<<16), "r" (IO_BASE), "r" ((port) << 2)); \ 149}) 150 151#define __inwc(port) \ 152({ \ 153 unsigned short result; \ 154 if (__PORT_PCIO((port))) \ 155 __asm__ __volatile__( \ 156 "ldr %0, [%1, %2] @ inwc" \ 157 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 158 else \ 159 __asm__ __volatile__( \ 160 "ldr %0, [%1, %2] @ inwc" \ 161 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ 162 result & 0xffff; \ 163}) 164 165#define __outlc(value,port) \ 166({ \ 167 unsigned long __v = value; \ 168 if (__PORT_PCIO((port))) \ 169 __asm__ __volatile__( \ 170 "str %0, [%1, %2] @ outlc" \ 171 : : "r" (__v), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 172 else \ 173 __asm__ __volatile__( \ 174 "str %0, [%1, %2] @ outlc" \ 175 : : "r" (__v), "r" (IO_BASE), "r" ((port) << 2)); \ 176}) 177 178#define __inlc(port) \ 179({ \ 180 unsigned long result; \ 181 if (__PORT_PCIO((port))) \ 182 __asm__ __volatile__( \ 183 "ldr %0, [%1, %2] @ inlc" \ 184 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 185 else \ 186 __asm__ __volatile__( \ 187 "ldr %0, [%1, %2] @ inlc" \ 188 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ 189 result; \ 190}) 191 192#define inb(p) (__builtin_constant_p((p)) ? __inbc(p) : __inb(p)) 193#define inw(p) (__builtin_constant_p((p)) ? __inwc(p) : __inw(p)) 194#define inl(p) (__builtin_constant_p((p)) ? __inlc(p) : __inl(p)) 195#define outb(v,p) (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p)) 196#define outw(v,p) (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p)) 197#define outl(v,p) (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p)) 198 199/* the following macro is deprecated */ 200#define ioaddr(port) ((unsigned long)__ioaddr((port))) 201 202#define insb(p,d,l) __raw_readsb(__ioaddr(p),d,l) 203#define insw(p,d,l) __raw_readsw(__ioaddr(p),d,l) 204 205#define outsb(p,d,l) __raw_writesb(__ioaddr(p),d,l) 206#define outsw(p,d,l) __raw_writesw(__ioaddr(p),d,l) 207 208/* 209 * 1:1 mapping for ioremapped regions. 210 */ 211#define __mem_pci(x) (x) 212 213#endif 214