linux/arch/arm/mach-s3c24xx/include/mach/io.h
<<
>>
Prefs
   1/*
   2 * arch/arm/mach-s3c2410/include/mach/io.h
   3 *  from arch/arm/mach-rpc/include/mach/io.h
   4 *
   5 * Copyright (C) 1997 Russell King
   6 *           (C) 2003 Simtec Electronics
   7*/
   8
   9#ifndef __ASM_ARM_ARCH_IO_H
  10#define __ASM_ARM_ARCH_IO_H
  11
  12#include <mach/hardware.h>
  13
  14#define IO_SPACE_LIMIT 0xffffffff
  15
  16/*
  17 * We use two different types of addressing - PC style addresses, and ARM
  18 * addresses.  PC style accesses the PC hardware with the normal PC IO
  19 * addresses, eg 0x3f8 for serial#1.  ARM addresses are above A28
  20 * and are translated to the start of IO.  Note that all addresses are
  21 * not shifted left!
  22 */
  23
  24#define __PORT_PCIO(x)  ((x) < (1<<28))
  25
  26#define PCIO_BASE        (S3C24XX_VA_ISA_WORD)
  27#define PCIO_BASE_b      (S3C24XX_VA_ISA_BYTE)
  28#define PCIO_BASE_w      (S3C24XX_VA_ISA_WORD)
  29#define PCIO_BASE_l      (S3C24XX_VA_ISA_WORD)
  30/*
  31 * Dynamic IO functions - let the compiler
  32 * optimize the expressions
  33 */
  34
  35#define DECLARE_DYN_OUT(sz,fnsuffix,instr) \
  36static inline void __out##fnsuffix (unsigned int val, unsigned int port) \
  37{ \
  38        unsigned long temp;                                   \
  39        __asm__ __volatile__(                                 \
  40        "cmp    %2, #(1<<28)\n\t"                             \
  41        "mov    %0, %2\n\t"                                   \
  42        "addcc  %0, %0, %3\n\t"                               \
  43        "str" instr " %1, [%0, #0 ]     @ out" #fnsuffix      \
  44        : "=&r" (temp)                                        \
  45        : "r" (val), "r" (port), "Ir" (PCIO_BASE_##fnsuffix)  \
  46        : "cc");                                              \
  47}
  48
  49
  50#define DECLARE_DYN_IN(sz,fnsuffix,instr)                               \
  51static inline unsigned sz __in##fnsuffix (unsigned int port)            \
  52{                                                                       \
  53        unsigned long temp, value;                                      \
  54        __asm__ __volatile__(                                           \
  55        "cmp    %2, #(1<<28)\n\t"                                       \
  56        "mov    %0, %2\n\t"                                             \
  57        "addcc  %0, %0, %3\n\t"                                         \
  58        "ldr" instr "   %1, [%0, #0 ]   @ in" #fnsuffix         \
  59        : "=&r" (temp), "=r" (value)                                    \
  60        : "r" (port), "Ir" (PCIO_BASE_##fnsuffix)       \
  61        : "cc");                                                        \
  62        return (unsigned sz)value;                                      \
  63}
  64
  65static inline void __iomem *__ioaddr (unsigned long port)
  66{
  67        return __PORT_PCIO(port) ? (PCIO_BASE + port) : (void __iomem *)port;
  68}
  69
  70#define DECLARE_IO(sz,fnsuffix,instr)   \
  71        DECLARE_DYN_IN(sz,fnsuffix,instr) \
  72        DECLARE_DYN_OUT(sz,fnsuffix,instr)
  73
  74DECLARE_IO(char,b,"b")
  75DECLARE_IO(short,w,"h")
  76DECLARE_IO(int,l,"")
  77
  78#undef DECLARE_IO
  79#undef DECLARE_DYN_IN
  80
  81/*
  82 * Constant address IO functions
  83 *
  84 * These have to be macros for the 'J' constraint to work -
  85 * +/-4096 immediate operand.
  86 */
  87#define __outbc(value,port)                                             \
  88({                                                                      \
  89        if (__PORT_PCIO((port)))                                        \
  90                __asm__ __volatile__(                                   \
  91                "strb   %0, [%1, %2]    @ outbc"                        \
  92                : : "r" (value), "r" (PCIO_BASE), "Jr" ((port)));       \
  93        else                                                            \
  94                __asm__ __volatile__(                                   \
  95                "strb   %0, [%1, #0]    @ outbc"                        \
  96                : : "r" (value), "r" ((port)));                         \
  97})
  98
  99#define __inbc(port)                                                    \
 100({                                                                      \
 101        unsigned char result;                                           \
 102        if (__PORT_PCIO((port)))                                        \
 103                __asm__ __volatile__(                                   \
 104                "ldrb   %0, [%1, %2]    @ inbc"                         \
 105                : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port)));      \
 106        else                                                            \
 107                __asm__ __volatile__(                                   \
 108                "ldrb   %0, [%1, #0]    @ inbc"                         \
 109                : "=r" (result) : "r" ((port)));                        \
 110        result;                                                         \
 111})
 112
 113#define __outwc(value,port)                                             \
 114({                                                                      \
 115        unsigned long v = value;                                        \
 116        if (__PORT_PCIO((port))) {                                      \
 117                if ((port) < 256 && (port) > -256)                      \
 118                        __asm__ __volatile__(                           \
 119                        "strh   %0, [%1, %2]    @ outwc"                \
 120                        : : "r" (v), "r" (PCIO_BASE), "Jr" ((port)));   \
 121                else if ((port) > 0)                                    \
 122                        __asm__ __volatile__(                           \
 123                        "strh   %0, [%1, %2]    @ outwc"                \
 124                        : : "r" (v),                                    \
 125                            "r" (PCIO_BASE + ((port) & ~0xff)),         \
 126                             "Jr" (((port) & 0xff)));                   \
 127                else                                                    \
 128                        __asm__ __volatile__(                           \
 129                        "strh   %0, [%1, #0]    @ outwc"                \
 130                        : : "r" (v),                                    \
 131                            "r" (PCIO_BASE + (port)));                  \
 132        } else                                                          \
 133                __asm__ __volatile__(                                   \
 134                "strh   %0, [%1, #0]    @ outwc"                        \
 135                : : "r" (v), "r" ((port)));                             \
 136})
 137
 138#define __inwc(port)                                                    \
 139({                                                                      \
 140        unsigned short result;                                          \
 141        if (__PORT_PCIO((port))) {                                      \
 142                if ((port) < 256 && (port) > -256 )                     \
 143                        __asm__ __volatile__(                           \
 144                        "ldrh   %0, [%1, %2]    @ inwc"                 \
 145                        : "=r" (result)                                 \
 146                        : "r" (PCIO_BASE),                              \
 147                          "Jr" ((port)));                               \
 148                else if ((port) > 0)                                    \
 149                        __asm__ __volatile__(                           \
 150                        "ldrh   %0, [%1, %2]    @ inwc"                 \
 151                        : "=r" (result)                                 \
 152                        : "r" (PCIO_BASE + ((port) & ~0xff)),           \
 153                          "Jr" (((port) & 0xff)));                      \
 154                else                                                    \
 155                        __asm__ __volatile__(                           \
 156                        "ldrh   %0, [%1, #0]    @ inwc"                 \
 157                        : "=r" (result)                                 \
 158                        : "r" (PCIO_BASE + ((port))));                  \
 159        } else                                                          \
 160                __asm__ __volatile__(                                   \
 161                "ldrh   %0, [%1, #0]    @ inwc"                         \
 162                : "=r" (result) : "r" ((port)));                        \
 163        result;                                                         \
 164})
 165
 166#define __outlc(value,port)                                             \
 167({                                                                      \
 168        unsigned long v = value;                                        \
 169        if (__PORT_PCIO((port)))                                        \
 170                __asm__ __volatile__(                                   \
 171                "str    %0, [%1, %2]    @ outlc"                        \
 172                : : "r" (v), "r" (PCIO_BASE), "Jr" ((port)));   \
 173        else                                                            \
 174                __asm__ __volatile__(                                   \
 175                "str    %0, [%1, #0]    @ outlc"                        \
 176                : : "r" (v), "r" ((port)));             \
 177})
 178
 179#define __inlc(port)                                                    \
 180({                                                                      \
 181        unsigned long result;                                           \
 182        if (__PORT_PCIO((port)))                                        \
 183                __asm__ __volatile__(                                   \
 184                "ldr    %0, [%1, %2]    @ inlc"                         \
 185                : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port)));      \
 186        else                                                            \
 187                __asm__ __volatile__(                                   \
 188                "ldr    %0, [%1, #0]    @ inlc"                         \
 189                : "=r" (result) : "r" ((port)));                \
 190        result;                                                         \
 191})
 192
 193#define __ioaddrc(port) ((__PORT_PCIO(port) ? PCIO_BASE + (port) : (void __iomem *)(port)))
 194
 195#define inb(p)          (__builtin_constant_p((p)) ? __inbc(p)     : __inb(p))
 196#define inw(p)          (__builtin_constant_p((p)) ? __inwc(p)     : __inw(p))
 197#define inl(p)          (__builtin_constant_p((p)) ? __inlc(p)     : __inl(p))
 198#define outb(v,p)       (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p))
 199#define outw(v,p)       (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
 200#define outl(v,p)       (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
 201#define __ioaddr(p)     (__builtin_constant_p((p)) ? __ioaddr(p)  : __ioaddrc(p))
 202
 203#define insb(p,d,l)     __raw_readsb(__ioaddr(p),d,l)
 204#define insw(p,d,l)     __raw_readsw(__ioaddr(p),d,l)
 205#define insl(p,d,l)     __raw_readsl(__ioaddr(p),d,l)
 206
 207#define outsb(p,d,l)    __raw_writesb(__ioaddr(p),d,l)
 208#define outsw(p,d,l)    __raw_writesw(__ioaddr(p),d,l)
 209#define outsl(p,d,l)    __raw_writesl(__ioaddr(p),d,l)
 210
 211#endif
 212