home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-arm / arch-rpc / io.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  6.8 KB  |  260 lines

  1. /*
  2.  *  linux/include/asm-arm/arch-rpc/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 <asm/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 *__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)        \
  236.     ((__PORT_PCIO(port) ? PCIO_BASE : IO_BASE) + ((port) << 2))
  237.  
  238. #define inb(p)         (__builtin_constant_p((p)) ? __inbc(p)    : __inb(p))
  239. #define inw(p)         (__builtin_constant_p((p)) ? __inwc(p)    : __inw(p))
  240. #define inl(p)         (__builtin_constant_p((p)) ? __inlc(p)    : __inl(p))
  241. #define outb(v,p)    (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p))
  242. #define outw(v,p)    (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
  243. #define outl(v,p)    (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
  244. #define __ioaddr(p)    (__builtin_constant_p((p)) ? __ioaddr(p)  : __ioaddrc(p))
  245. /* the following macro is deprecated */
  246. #define ioaddr(port)    ((unsigned long)__ioaddr((port)))
  247.  
  248. #define insb(p,d,l)    __raw_readsb(__ioaddr(p),d,l)
  249. #define insw(p,d,l)    __raw_readsw(__ioaddr(p),d,l)
  250.  
  251. #define outsb(p,d,l)    __raw_writesb(__ioaddr(p),d,l)
  252. #define outsw(p,d,l)    __raw_writesw(__ioaddr(p),d,l)
  253.  
  254. /*
  255.  * 1:1 mapping for ioremapped regions.
  256.  */
  257. #define __mem_pci(x)    (x)
  258.  
  259. #endif
  260.