io.h 6.3 KB

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