io.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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/config.h>
  11. #include <linux/kernel.h>
  12. #include <asm/mach/se73180.h>
  13. #include <asm/io.h>
  14. #define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a)
  15. struct iop {
  16. unsigned long start, end;
  17. unsigned long base;
  18. struct iop *(*check) (struct iop * p, unsigned long port);
  19. unsigned char (*inb) (struct iop * p, unsigned long port);
  20. unsigned short (*inw) (struct iop * p, unsigned long port);
  21. void (*outb) (struct iop * p, unsigned char value, unsigned long port);
  22. void (*outw) (struct iop * p, unsigned short value, unsigned long port);
  23. };
  24. struct iop *
  25. simple_check(struct iop *p, unsigned long port)
  26. {
  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. /* MSTLANEX01 LAN at 0xb400:0000 */
  88. static struct iop laniop = {
  89. .start = 0x300,
  90. .end = 0x30f,
  91. .base = 0xb4000000,
  92. .check = simple_check,
  93. .inb = simple_inb,
  94. .inw = simple_inw,
  95. .outb = simple_outb,
  96. .outw = simple_outw,
  97. };
  98. /* NE2000 pc card NIC */
  99. static struct iop neiop = {
  100. .start = 0x280,
  101. .end = 0x29f,
  102. .base = 0xb0600000 + 0x80, /* soft 0x280 -> hard 0x300 */
  103. .check = simple_check,
  104. .inb = pcc_inb,
  105. .inw = simple_inw,
  106. .outb = pcc_outb,
  107. .outw = simple_outw,
  108. };
  109. /* CF in CF slot */
  110. static struct iop cfiop = {
  111. .base = 0xb0600000,
  112. .check = ide_check,
  113. .inb = pcc_inb,
  114. .inw = simple_inw,
  115. .outb = pcc_outb,
  116. .outw = simple_outw,
  117. };
  118. static __inline__ struct iop *
  119. port2iop(unsigned long port)
  120. {
  121. if (0) ;
  122. #if defined(CONFIG_SMC91111)
  123. else if (laniop.check(&laniop, port))
  124. return &laniop;
  125. #endif
  126. #if defined(CONFIG_NE2000)
  127. else if (neiop.check(&neiop, port))
  128. return &neiop;
  129. #endif
  130. #if defined(CONFIG_IDE)
  131. else if (cfiop.check(&cfiop, port))
  132. return &cfiop;
  133. #endif
  134. else
  135. return &neiop; /* fallback */
  136. }
  137. static inline void
  138. delay(void)
  139. {
  140. ctrl_inw(0xac000000);
  141. ctrl_inw(0xac000000);
  142. }
  143. unsigned char
  144. sh73180se_inb(unsigned long port)
  145. {
  146. struct iop *p = port2iop(port);
  147. return (p->inb) (p, port);
  148. }
  149. unsigned char
  150. sh73180se_inb_p(unsigned long port)
  151. {
  152. unsigned char v = sh73180se_inb(port);
  153. delay();
  154. return v;
  155. }
  156. unsigned short
  157. sh73180se_inw(unsigned long port)
  158. {
  159. struct iop *p = port2iop(port);
  160. return (p->inw) (p, port);
  161. }
  162. unsigned int
  163. sh73180se_inl(unsigned long port)
  164. {
  165. badio(inl, port);
  166. }
  167. void
  168. sh73180se_outb(unsigned char value, unsigned long port)
  169. {
  170. struct iop *p = port2iop(port);
  171. (p->outb) (p, value, port);
  172. }
  173. void
  174. sh73180se_outb_p(unsigned char value, unsigned long port)
  175. {
  176. sh73180se_outb(value, port);
  177. delay();
  178. }
  179. void
  180. sh73180se_outw(unsigned short value, unsigned long port)
  181. {
  182. struct iop *p = port2iop(port);
  183. (p->outw) (p, value, port);
  184. }
  185. void
  186. sh73180se_outl(unsigned int value, unsigned long port)
  187. {
  188. badio(outl, port);
  189. }
  190. void
  191. sh73180se_insb(unsigned long port, void *addr, unsigned long count)
  192. {
  193. unsigned char *a = addr;
  194. struct iop *p = port2iop(port);
  195. while (count--)
  196. *a++ = (p->inb) (p, port);
  197. }
  198. void
  199. sh73180se_insw(unsigned long port, void *addr, unsigned long count)
  200. {
  201. unsigned short *a = addr;
  202. struct iop *p = port2iop(port);
  203. while (count--)
  204. *a++ = (p->inw) (p, port);
  205. }
  206. void
  207. sh73180se_insl(unsigned long port, void *addr, unsigned long count)
  208. {
  209. badio(insl, port);
  210. }
  211. void
  212. sh73180se_outsb(unsigned long port, const void *addr, unsigned long count)
  213. {
  214. unsigned char *a = (unsigned char *) addr;
  215. struct iop *p = port2iop(port);
  216. while (count--)
  217. (p->outb) (p, *a++, port);
  218. }
  219. void
  220. sh73180se_outsw(unsigned long port, const void *addr, unsigned long count)
  221. {
  222. unsigned short *a = (unsigned short *) addr;
  223. struct iop *p = port2iop(port);
  224. while (count--)
  225. (p->outw) (p, *a++, port);
  226. }
  227. void
  228. sh73180se_outsl(unsigned long port, const void *addr, unsigned long count)
  229. {
  230. badio(outsw, port);
  231. }