io.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  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. #ifdef CONFIG_SMC91X
  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. #endif
  99. /* NE2000 pc card NIC */
  100. static struct iop neiop = {
  101. .start = 0x280,
  102. .end = 0x29f,
  103. .base = 0xb0600000 + 0x80, /* soft 0x280 -> hard 0x300 */
  104. .check = simple_check,
  105. .inb = pcc_inb,
  106. .inw = simple_inw,
  107. .outb = pcc_outb,
  108. .outw = simple_outw,
  109. };
  110. #ifdef CONFIG_IDE
  111. /* CF in CF slot */
  112. static struct iop cfiop = {
  113. .base = 0xb0600000,
  114. .check = ide_check,
  115. .inb = pcc_inb,
  116. .inw = simple_inw,
  117. .outb = pcc_outb,
  118. .outw = simple_outw,
  119. };
  120. #endif
  121. static __inline__ struct iop *
  122. port2iop(unsigned long port)
  123. {
  124. if (0) ;
  125. #if defined(CONFIG_SMC91X)
  126. else if (laniop.check(&laniop, port))
  127. return &laniop;
  128. #endif
  129. #if defined(CONFIG_NE2000)
  130. else if (neiop.check(&neiop, port))
  131. return &neiop;
  132. #endif
  133. #if defined(CONFIG_IDE)
  134. else if (cfiop.check(&cfiop, port))
  135. return &cfiop;
  136. #endif
  137. else
  138. return &neiop; /* fallback */
  139. }
  140. static inline void
  141. delay(void)
  142. {
  143. ctrl_inw(0xac000000);
  144. ctrl_inw(0xac000000);
  145. }
  146. unsigned char
  147. sh73180se_inb(unsigned long port)
  148. {
  149. struct iop *p = port2iop(port);
  150. return (p->inb) (p, port);
  151. }
  152. unsigned char
  153. sh73180se_inb_p(unsigned long port)
  154. {
  155. unsigned char v = sh73180se_inb(port);
  156. delay();
  157. return v;
  158. }
  159. unsigned short
  160. sh73180se_inw(unsigned long port)
  161. {
  162. struct iop *p = port2iop(port);
  163. return (p->inw) (p, port);
  164. }
  165. unsigned int
  166. sh73180se_inl(unsigned long port)
  167. {
  168. badio(inl, port);
  169. }
  170. void
  171. sh73180se_outb(unsigned char value, unsigned long port)
  172. {
  173. struct iop *p = port2iop(port);
  174. (p->outb) (p, value, port);
  175. }
  176. void
  177. sh73180se_outb_p(unsigned char value, unsigned long port)
  178. {
  179. sh73180se_outb(value, port);
  180. delay();
  181. }
  182. void
  183. sh73180se_outw(unsigned short value, unsigned long port)
  184. {
  185. struct iop *p = port2iop(port);
  186. (p->outw) (p, value, port);
  187. }
  188. void
  189. sh73180se_outl(unsigned int value, unsigned long port)
  190. {
  191. badio(outl, port);
  192. }
  193. void
  194. sh73180se_insb(unsigned long port, void *addr, unsigned long count)
  195. {
  196. unsigned char *a = addr;
  197. struct iop *p = port2iop(port);
  198. while (count--)
  199. *a++ = (p->inb) (p, port);
  200. }
  201. void
  202. sh73180se_insw(unsigned long port, void *addr, unsigned long count)
  203. {
  204. unsigned short *a = addr;
  205. struct iop *p = port2iop(port);
  206. while (count--)
  207. *a++ = (p->inw) (p, port);
  208. }
  209. void
  210. sh73180se_insl(unsigned long port, void *addr, unsigned long count)
  211. {
  212. badio(insl, port);
  213. }
  214. void
  215. sh73180se_outsb(unsigned long port, const void *addr, unsigned long count)
  216. {
  217. unsigned char *a = (unsigned char *) addr;
  218. struct iop *p = port2iop(port);
  219. while (count--)
  220. (p->outb) (p, *a++, port);
  221. }
  222. void
  223. sh73180se_outsw(unsigned long port, const void *addr, unsigned long count)
  224. {
  225. unsigned short *a = (unsigned short *) addr;
  226. struct iop *p = port2iop(port);
  227. while (count--)
  228. (p->outw) (p, *a++, port);
  229. }
  230. void
  231. sh73180se_outsl(unsigned long port, const void *addr, unsigned long count)
  232. {
  233. badio(outsw, port);
  234. }