io.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /*
  2. * arch/sh/boards/se/7343/io.c
  3. *
  4. * I/O routine for SH-Mobile3AS 7343 SolutionEngine.
  5. *
  6. */
  7. #include <linux/kernel.h>
  8. #include <asm/io.h>
  9. #include <asm/mach/se7343.h>
  10. #define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a)
  11. struct iop {
  12. unsigned long start, end;
  13. unsigned long base;
  14. struct iop *(*check) (struct iop * p, unsigned long port);
  15. unsigned char (*inb) (struct iop * p, unsigned long port);
  16. unsigned short (*inw) (struct iop * p, unsigned long port);
  17. void (*outb) (struct iop * p, unsigned char value, unsigned long port);
  18. void (*outw) (struct iop * p, unsigned short value, unsigned long port);
  19. };
  20. struct iop *
  21. simple_check(struct iop *p, unsigned long port)
  22. {
  23. static int count;
  24. if (count < 100)
  25. count++;
  26. port &= 0xFFFF;
  27. if ((p->start <= port) && (port <= p->end))
  28. return p;
  29. else
  30. badio(check, port);
  31. }
  32. struct iop *
  33. ide_check(struct iop *p, unsigned long port)
  34. {
  35. if (((0x1f0 <= port) && (port <= 0x1f7)) || (port == 0x3f7))
  36. return p;
  37. return NULL;
  38. }
  39. unsigned char
  40. simple_inb(struct iop *p, unsigned long port)
  41. {
  42. return *(unsigned char *) (p->base + port);
  43. }
  44. unsigned short
  45. simple_inw(struct iop *p, unsigned long port)
  46. {
  47. return *(unsigned short *) (p->base + port);
  48. }
  49. void
  50. simple_outb(struct iop *p, unsigned char value, unsigned long port)
  51. {
  52. *(unsigned char *) (p->base + port) = value;
  53. }
  54. void
  55. simple_outw(struct iop *p, unsigned short value, unsigned long port)
  56. {
  57. *(unsigned short *) (p->base + port) = value;
  58. }
  59. unsigned char
  60. pcc_inb(struct iop *p, unsigned long port)
  61. {
  62. unsigned long addr = p->base + port + 0x40000;
  63. unsigned long v;
  64. if (port & 1)
  65. addr += 0x00400000;
  66. v = *(volatile unsigned char *) addr;
  67. return v;
  68. }
  69. void
  70. pcc_outb(struct iop *p, unsigned char value, unsigned long port)
  71. {
  72. unsigned long addr = p->base + port + 0x40000;
  73. if (port & 1)
  74. addr += 0x00400000;
  75. *(volatile unsigned char *) addr = value;
  76. }
  77. unsigned char
  78. bad_inb(struct iop *p, unsigned long port)
  79. {
  80. badio(inb, port);
  81. }
  82. void
  83. bad_outb(struct iop *p, unsigned char value, unsigned long port)
  84. {
  85. badio(inw, port);
  86. }
  87. #ifdef CONFIG_SMC91X
  88. /* MSTLANEX01 LAN at 0xb400:0000 */
  89. static struct iop laniop = {
  90. .start = 0x00,
  91. .end = 0x0F,
  92. .base = 0x04000000,
  93. .check = simple_check,
  94. .inb = simple_inb,
  95. .inw = simple_inw,
  96. .outb = simple_outb,
  97. .outw = simple_outw,
  98. };
  99. #endif
  100. #ifdef CONFIG_NE2000
  101. /* NE2000 pc card NIC */
  102. static struct iop neiop = {
  103. .start = 0x280,
  104. .end = 0x29f,
  105. .base = 0xb0600000 + 0x80, /* soft 0x280 -> hard 0x300 */
  106. .check = simple_check,
  107. .inb = pcc_inb,
  108. .inw = simple_inw,
  109. .outb = pcc_outb,
  110. .outw = simple_outw,
  111. };
  112. #endif
  113. #ifdef CONFIG_IDE
  114. /* CF in CF slot */
  115. static struct iop cfiop = {
  116. .base = 0xb0600000,
  117. .check = ide_check,
  118. .inb = pcc_inb,
  119. .inw = simple_inw,
  120. .outb = pcc_outb,
  121. .outw = simple_outw,
  122. };
  123. #endif
  124. static __inline__ struct iop *
  125. port2iop(unsigned long port)
  126. {
  127. if (0) ;
  128. #if defined(CONFIG_SMC91X)
  129. else if (laniop.check(&laniop, port))
  130. return &laniop;
  131. #endif
  132. #if defined(CONFIG_NE2000)
  133. else if (neiop.check(&neiop, port))
  134. return &neiop;
  135. #endif
  136. #if defined(CONFIG_IDE)
  137. else if (cfiop.check(&cfiop, port))
  138. return &cfiop;
  139. #endif
  140. else
  141. return NULL;
  142. }
  143. static inline void
  144. delay(void)
  145. {
  146. ctrl_inw(0xac000000);
  147. ctrl_inw(0xac000000);
  148. }
  149. unsigned char
  150. sh7343se_inb(unsigned long port)
  151. {
  152. struct iop *p = port2iop(port);
  153. return (p->inb) (p, port);
  154. }
  155. unsigned char
  156. sh7343se_inb_p(unsigned long port)
  157. {
  158. unsigned char v = sh7343se_inb(port);
  159. delay();
  160. return v;
  161. }
  162. unsigned short
  163. sh7343se_inw(unsigned long port)
  164. {
  165. struct iop *p = port2iop(port);
  166. return (p->inw) (p, port);
  167. }
  168. unsigned int
  169. sh7343se_inl(unsigned long port)
  170. {
  171. badio(inl, port);
  172. }
  173. void
  174. sh7343se_outb(unsigned char value, unsigned long port)
  175. {
  176. struct iop *p = port2iop(port);
  177. (p->outb) (p, value, port);
  178. }
  179. void
  180. sh7343se_outb_p(unsigned char value, unsigned long port)
  181. {
  182. sh7343se_outb(value, port);
  183. delay();
  184. }
  185. void
  186. sh7343se_outw(unsigned short value, unsigned long port)
  187. {
  188. struct iop *p = port2iop(port);
  189. (p->outw) (p, value, port);
  190. }
  191. void
  192. sh7343se_outl(unsigned int value, unsigned long port)
  193. {
  194. badio(outl, port);
  195. }
  196. void
  197. sh7343se_insb(unsigned long port, void *addr, unsigned long count)
  198. {
  199. unsigned char *a = addr;
  200. struct iop *p = port2iop(port);
  201. while (count--)
  202. *a++ = (p->inb) (p, port);
  203. }
  204. void
  205. sh7343se_insw(unsigned long port, void *addr, unsigned long count)
  206. {
  207. unsigned short *a = addr;
  208. struct iop *p = port2iop(port);
  209. while (count--)
  210. *a++ = (p->inw) (p, port);
  211. }
  212. void
  213. sh7343se_insl(unsigned long port, void *addr, unsigned long count)
  214. {
  215. badio(insl, port);
  216. }
  217. void
  218. sh7343se_outsb(unsigned long port, const void *addr, unsigned long count)
  219. {
  220. unsigned char *a = (unsigned char *) addr;
  221. struct iop *p = port2iop(port);
  222. while (count--)
  223. (p->outb) (p, *a++, port);
  224. }
  225. void
  226. sh7343se_outsw(unsigned long port, const void *addr, unsigned long count)
  227. {
  228. unsigned short *a = (unsigned short *) addr;
  229. struct iop *p = port2iop(port);
  230. while (count--)
  231. (p->outw) (p, *a++, port);
  232. }
  233. void
  234. sh7343se_outsl(unsigned long port, const void *addr, unsigned long count)
  235. {
  236. badio(outsw, port);
  237. }