io.c 5.0 KB

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