1/* 2 * linux/include/asm-arm/io.h 3 * 4 * Copyright (C) 1996-2000 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 * 16-Sep-1996 RMK Inlined the inx/outx functions & optimised for both 12 * constant addresses and variable addresses. 13 * 04-Dec-1997 RMK Moved a lot of this stuff to the new architecture 14 * specific IO header files. 15 * 27-Mar-1999 PJB Second parameter of memcpy_toio is const.. 16 * 04-Apr-1999 PJB Added check_signature. 17 * 12-Dec-1999 RMK More cleanups 18 * 18-Jun-2000 RMK Removed virt_to_* and friends definitions 19 */ 20#ifndef __ASM_ARM_IO_H 21#define __ASM_ARM_IO_H 22 23#ifdef __KERNEL__ 24 25#include <linux/types.h> 26#include <asm/byteorder.h> 27#include <asm/memory.h> 28#include <asm/hardware.h> 29 30/* 31 * Generic IO read/write. These perform native-endian accesses. Note 32 * that some architectures will want to re-define __raw_{read,write}w. 33 */ 34extern void __raw_writesb(unsigned int addr, const void *data, int bytelen); 35extern void __raw_writesw(unsigned int addr, const void *data, int wordlen); 36extern void __raw_writesl(unsigned int addr, const void *data, int longlen); 37 38extern void __raw_readsb(unsigned int addr, void *data, int bytelen); 39extern void __raw_readsw(unsigned int addr, void *data, int wordlen); 40extern void __raw_readsl(unsigned int addr, void *data, int longlen); 41 42#define __raw_writeb(v,a) (*(volatile unsigned char *)(a) = (v)) 43#define __raw_writew(v,a) (*(volatile unsigned short *)(a) = (v)) 44#define __raw_writel(v,a) (*(volatile unsigned int *)(a) = (v)) 45 46#define __raw_readb(a) (*(volatile unsigned char *)(a)) 47#define __raw_readw(a) (*(volatile unsigned short *)(a)) 48#define __raw_readl(a) (*(volatile unsigned int *)(a)) 49 50 51/* 52 * Bad read/write accesses... 53 */ 54extern void __readwrite_bug(const char *fn); 55 56/* 57 * Now, pick up the machine-defined IO definitions 58 */ 59 60#define IO_SPACE_LIMIT 0xffffffff 61 62/* 63 * GCC is totally crap at loading/storing data. We try to persuade it 64 * to do the right thing by using these whereever possible instead of 65 * the above. 66 */ 67#define __arch_base_getb(b,o) \ 68 ({ \ 69 unsigned int v, r = (b); \ 70 __asm__ __volatile__( \ 71 "ldrb %0, [%1, %2]" \ 72 : "=r" (v) \ 73 : "r" (r), "Ir" (o)); \ 74 v; \ 75 }) 76 77#define __arch_base_getl(b,o) \ 78 ({ \ 79 unsigned int v, r = (b); \ 80 __asm__ __volatile__( \ 81 "ldr %0, [%1, %2]" \ 82 : "=r" (v) \ 83 : "r" (r), "Ir" (o)); \ 84 v; \ 85 }) 86 87#define __arch_base_putb(v,b,o) \ 88 ({ \ 89 unsigned int r = (b); \ 90 __asm__ __volatile__( \ 91 "strb %0, [%1, %2]" \ 92 : \ 93 : "r" (v), "r" (r), "Ir" (o)); \ 94 }) 95 96#define __arch_base_putl(v,b,o) \ 97 ({ \ 98 unsigned int r = (b); \ 99 __asm__ __volatile__( \ 100 "str %0, [%1, %2]" \ 101 : \ 102 : "r" (v), "r" (r), "Ir" (o)); \ 103 }) 104 105/* 106 * We use two different types of addressing - PC style addresses, and ARM 107 * addresses. PC style accesses the PC hardware with the normal PC IO 108 * addresses, eg 0x3f8 for serial#1. ARM addresses are 0x80000000+ 109 * and are translated to the start of IO. Note that all addresses are 110 * shifted left! 111 */ 112#define __PORT_PCIO(x) (!((x) & 0x80000000)) 113 114/* 115 * Dynamic IO functions - let the compiler 116 * optimize the expressions 117 */ 118static inline void __outb (unsigned int value, unsigned int port) 119{ 120 unsigned long temp; 121 __asm__ __volatile__( 122 "tst %2, #0x80000000\n\t" 123 "mov %0, %4\n\t" 124 "addeq %0, %0, %3\n\t" 125 "strb %1, [%0, %2, lsl #2] @ outb" 126 : "=&r" (temp) 127 : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) 128 : "cc"); 129} 130 131static inline void __outw (unsigned int value, unsigned int port) 132{ 133 unsigned long temp; 134 __asm__ __volatile__( 135 "tst %2, #0x80000000\n\t" 136 "mov %0, %4\n\t" 137 "addeq %0, %0, %3\n\t" 138 "str %1, [%0, %2, lsl #2] @ outw" 139 : "=&r" (temp) 140 : "r" (value|value<<16), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) 141 : "cc"); 142} 143 144static inline void __outl (unsigned int value, unsigned int port) 145{ 146 unsigned long temp; 147 __asm__ __volatile__( 148 "tst %2, #0x80000000\n\t" 149 "mov %0, %4\n\t" 150 "addeq %0, %0, %3\n\t" 151 "str %1, [%0, %2, lsl #2] @ outl" 152 : "=&r" (temp) 153 : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) 154 : "cc"); 155} 156 157#define DECLARE_DYN_IN(sz,fnsuffix,instr) \ 158static inline unsigned sz __in##fnsuffix (unsigned int port) \ 159{ \ 160 unsigned long temp, value; \ 161 __asm__ __volatile__( \ 162 "tst %2, #0x80000000\n\t" \ 163 "mov %0, %4\n\t" \ 164 "addeq %0, %0, %3\n\t" \ 165 "ldr" instr " %1, [%0, %2, lsl #2] @ in" #fnsuffix \ 166 : "=&r" (temp), "=r" (value) \ 167 : "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) \ 168 : "cc"); \ 169 return (unsigned sz)value; \ 170} 171 172static inline unsigned int __ioaddr (unsigned int port) \ 173{ \ 174 if (__PORT_PCIO(port)) \ 175 return (unsigned int)(PCIO_BASE + (port << 2)); \ 176 else \ 177 return (unsigned int)(IO_BASE + (port << 2)); \ 178} 179 180#define DECLARE_IO(sz,fnsuffix,instr) \ 181 DECLARE_DYN_IN(sz,fnsuffix,instr) 182 183DECLARE_IO(char,b,"b") 184DECLARE_IO(short,w,"") 185DECLARE_IO(int,l,"") 186 187#undef DECLARE_IO 188#undef DECLARE_DYN_IN 189 190/* 191 * Constant address IO functions 192 * 193 * These have to be macros for the 'J' constraint to work - 194 * +/-4096 immediate operand. 195 */ 196#define __outbc(value,port) \ 197({ \ 198 if (__PORT_PCIO((port))) \ 199 __asm__ __volatile__( \ 200 "strb %0, [%1, %2] @ outbc" \ 201 : : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 202 else \ 203 __asm__ __volatile__( \ 204 "strb %0, [%1, %2] @ outbc" \ 205 : : "r" (value), "r" (IO_BASE), "r" ((port) << 2)); \ 206}) 207 208#define __inbc(port) \ 209({ \ 210 unsigned char result; \ 211 if (__PORT_PCIO((port))) \ 212 __asm__ __volatile__( \ 213 "ldrb %0, [%1, %2] @ inbc" \ 214 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 215 else \ 216 __asm__ __volatile__( \ 217 "ldrb %0, [%1, %2] @ inbc" \ 218 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ 219 result; \ 220}) 221 222#define __outwc(value,port) \ 223({ \ 224 unsigned long v = value; \ 225 if (__PORT_PCIO((port))) \ 226 __asm__ __volatile__( \ 227 "str %0, [%1, %2] @ outwc" \ 228 : : "r" (v|v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 229 else \ 230 __asm__ __volatile__( \ 231 "str %0, [%1, %2] @ outwc" \ 232 : : "r" (v|v<<16), "r" (IO_BASE), "r" ((port) << 2)); \ 233}) 234 235#define __inwc(port) \ 236({ \ 237 unsigned short result; \ 238 if (__PORT_PCIO((port))) \ 239 __asm__ __volatile__( \ 240 "ldr %0, [%1, %2] @ inwc" \ 241 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 242 else \ 243 __asm__ __volatile__( \ 244 "ldr %0, [%1, %2] @ inwc" \ 245 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ 246 result & 0xffff; \ 247}) 248 249#define __outlc(value,port) \ 250({ \ 251 unsigned long v = value; \ 252 if (__PORT_PCIO((port))) \ 253 __asm__ __volatile__( \ 254 "str %0, [%1, %2] @ outlc" \ 255 : : "r" (v), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 256 else \ 257 __asm__ __volatile__( \ 258 "str %0, [%1, %2] @ outlc" \ 259 : : "r" (v), "r" (IO_BASE), "r" ((port) << 2)); \ 260}) 261 262#define __inlc(port) \ 263({ \ 264 unsigned long result; \ 265 if (__PORT_PCIO((port))) \ 266 __asm__ __volatile__( \ 267 "ldr %0, [%1, %2] @ inlc" \ 268 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 269 else \ 270 __asm__ __volatile__( \ 271 "ldr %0, [%1, %2] @ inlc" \ 272 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ 273 result; \ 274}) 275 276#define __ioaddrc(port) \ 277({ \ 278 unsigned long addr; \ 279 if (__PORT_PCIO((port))) \ 280 addr = PCIO_BASE + ((port) << 2); \ 281 else \ 282 addr = IO_BASE + ((port) << 2); \ 283 addr; \ 284}) 285 286#define inb(p) (__builtin_constant_p((p)) ? __inbc(p) : __inb(p)) 287#define inw(p) (__builtin_constant_p((p)) ? __inwc(p) : __inw(p)) 288#define inl(p) (__builtin_constant_p((p)) ? __inlc(p) : __inl(p)) 289#define outb(v,p) (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p)) 290#define outw(v,p) (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p)) 291#define outl(v,p) (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p)) 292#define __ioaddr(p) (__builtin_constant_p((p)) ? __ioaddr(p) : __ioaddrc(p)) 293 294/* JMA 18.02.03 added sb,sl from arm/io.h, changing io to ioaddr */ 295 296#define outsb(p,d,l) __raw_writesb(__ioaddr(p),d,l) 297#define outsw(p,d,l) __raw_writesw(__ioaddr(p),d,l) 298#define outsl(p,d,l) __raw_writesl(__ioaddr(p),d,l) 299 300#define insb(p,d,l) __raw_readsb(__ioaddr(p),d,l) 301#define insw(p,d,l) __raw_readsw(__ioaddr(p),d,l) 302#define insl(p,d,l) __raw_readsl(__ioaddr(p),d,l) 303 304#define insw(p,d,l) __raw_readsw(__ioaddr(p),d,l) 305#define outsw(p,d,l) __raw_writesw(__ioaddr(p),d,l) 306 307#define readb(c) (__readwrite_bug("readb"),0) 308#define readw(c) (__readwrite_bug("readw"),0) 309#define readl(c) (__readwrite_bug("readl"),0) 310#define readb_relaxed(addr) readb(addr) 311#define readw_relaxed(addr) readw(addr) 312#define readl_relaxed(addr) readl(addr) 313#define writeb(v,c) __readwrite_bug("writeb") 314#define writew(v,c) __readwrite_bug("writew") 315#define writel(v,c) __readwrite_bug("writel") 316 317#define readsw(p,d,l) (__readwrite_bug("readsw"),0) 318#define readsl(p,d,l) (__readwrite_bug("readsl"),0) 319#define writesw(p,d,l) __readwrite_bug("writesw") 320#define writesl(p,d,l) __readwrite_bug("writesl") 321 322#define mmiowb() 323 324/* the following macro is deprecated */ 325#define ioaddr(port) __ioaddr((port)) 326 327/* 328 * No ioremap support here. 329 */ 330#define __arch_ioremap(c,s,f,a) ((void *)(c)) 331#define __arch_iounmap(c) do { } while (0) 332 333 334#if defined(__arch_putb) || defined(__arch_putw) || defined(__arch_putl) || \ 335 defined(__arch_getb) || defined(__arch_getw) || defined(__arch_getl) 336#warning machine class uses old __arch_putw or __arch_getw 337#endif 338 339/* 340 * IO port access primitives 341 * ------------------------- 342 * 343 * The ARM doesn't have special IO access instructions; all IO is memory 344 * mapped. Note that these are defined to perform little endian accesses 345 * only. Their primary purpose is to access PCI and ISA peripherals. 346 * 347 * Note that for a big endian machine, this implies that the following 348 * big endian mode connectivity is in place, as described by numerious 349 * ARM documents: 350 * 351 * PCI: D0-D7 D8-D15 D16-D23 D24-D31 352 * ARM: D24-D31 D16-D23 D8-D15 D0-D7 353 * 354 * The machine specific io.h include defines __io to translate an "IO" 355 * address to a memory address. 356 * 357 * Note that we prevent GCC re-ordering or caching values in expressions 358 * by introducing sequence points into the in*() definitions. Note that 359 * __raw_* do not guarantee this behaviour. 360 */ 361/* 362#define outsb(p,d,l) __raw_writesb(__io(p),d,l) 363#define outsw(p,d,l) __raw_writesw(__io(p),d,l) 364 365#define insb(p,d,l) __raw_readsb(__io(p),d,l) 366#define insw(p,d,l) __raw_readsw(__io(p),d,l) 367*/ 368#define outb_p(val,port) outb((val),(port)) 369#define outw_p(val,port) outw((val),(port)) 370#define inb_p(port) inb((port)) 371#define inw_p(port) inw((port)) 372#define inl_p(port) inl((port)) 373 374#define outsb_p(port,from,len) outsb(port,from,len) 375#define outsw_p(port,from,len) outsw(port,from,len) 376#define insb_p(port,to,len) insb(port,to,len) 377#define insw_p(port,to,len) insw(port,to,len) 378 379/* 380 * String version of IO memory access ops: 381 */ 382extern void _memcpy_fromio(void *, unsigned long, size_t); 383extern void _memcpy_toio(unsigned long, const void *, size_t); 384extern void _memset_io(unsigned long, int, size_t); 385 386/* 387 * ioremap and friends. 388 * 389 * ioremap takes a PCI memory address, as specified in 390 * Documentation/IO-mapping.txt. 391 */ 392extern void * __ioremap(unsigned long, size_t, unsigned long, unsigned long); 393extern void __iounmap(void *addr); 394 395#ifndef __arch_ioremap 396#define ioremap(cookie,size) __ioremap(cookie,size,0,1) 397#define ioremap_nocache(cookie,size) __ioremap(cookie,size,0,1) 398#define iounmap(cookie) __iounmap(cookie) 399#else 400#define ioremap(cookie,size) __arch_ioremap((cookie),(size),0,1) 401#define ioremap_nocache(cookie,size) __arch_ioremap((cookie),(size),0,1) 402#define iounmap(cookie) __arch_iounmap(cookie) 403#endif 404 405/* 406 * DMA-consistent mapping functions. These allocate/free a region of 407 * uncached, unwrite-buffered mapped memory space for use with DMA 408 * devices. This is the "generic" version. The PCI specific version 409 * is in pci.h 410 */ 411extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle); 412extern void consistent_free(void *vaddr, size_t size, dma_addr_t handle); 413extern void consistent_sync(void *vaddr, size_t size, int rw); 414 415/* 416 * can the hardware map this into one segment or not, given no other 417 * constraints. 418 */ 419#define BIOVEC_MERGEABLE(vec1, vec2) \ 420 ((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2))) 421 422/* 423 * Convert a physical pointer to a virtual kernel pointer for /dev/mem 424 * access 425 */ 426#define xlate_dev_mem_ptr(p) __va(p) 427 428/* 429 * Convert a virtual cached pointer to an uncached pointer 430 */ 431#define xlate_dev_kmem_ptr(p) p 432 433#endif /* __KERNEL__ */ 434#endif /* __ASM_ARM_IO_H */ 435