io.c 5.0 KB

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