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