io_se.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:6k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: io_se.c,v 1.12 2001/08/11 01:23:28 jzs Exp $
  2.  *
  3.  * linux/arch/sh/kernel/io_se.c
  4.  *
  5.  * Copyright (C) 2000  Kazumoto Kojima
  6.  *
  7.  * I/O routine for Hitachi SolutionEngine.
  8.  *
  9.  */
  10. #include <linux/kernel.h>
  11. #include <linux/types.h>
  12. #include <asm/io.h>
  13. #include <asm/hitachi_se.h>
  14. /* SH pcmcia io window base, start and end.  */
  15. int sh_pcic_io_wbase = 0xb8400000;
  16. int sh_pcic_io_start;
  17. int sh_pcic_io_stop;
  18. int sh_pcic_io_type;
  19. int sh_pcic_io_dummy;
  20. static inline void delay(void)
  21. {
  22. ctrl_inw(0xa0000000);
  23. }
  24. /* MS7750 requires special versions of in*, out* routines, since
  25.    PC-like io ports are located at upper half byte of 16-bit word which
  26.    can be accessed only with 16-bit wide.  */
  27. static inline volatile __u16 *
  28. port2adr(unsigned int port)
  29. {
  30. if (port >= 0x2000)
  31. return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
  32. else if (port >= 0x1000)
  33. return (volatile __u16 *) (PA_83902 + (port << 1));
  34. else if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
  35. return (volatile __u16 *) (sh_pcic_io_wbase + (port &~ 1));
  36. else
  37. return (volatile __u16 *) (PA_SUPERIO + (port << 1));
  38. }
  39. static inline int
  40. shifted_port(unsigned long port)
  41. {
  42. /* For IDE registers, value is not shifted */
  43. if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
  44. return 0;
  45. else
  46. return 1;
  47. }
  48. #define maybebadio(name,port) 
  49.   printk("bad PC-like io %s for port 0x%lx at 0x%08xn", 
  50.  #name, (port), (__u32) __builtin_return_address(0))
  51. unsigned char se_inb(unsigned long port)
  52. {
  53. if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
  54. return *(__u8 *) (sh_pcic_io_wbase + 0x40000 + port); 
  55. else if (shifted_port(port))
  56. return (*port2adr(port) >> 8); 
  57. else
  58. return (*port2adr(port))&0xff; 
  59. }
  60. unsigned char se_inb_p(unsigned long port)
  61. {
  62. unsigned long v;
  63. if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
  64. v = *(__u8 *) (sh_pcic_io_wbase + 0x40000 + port); 
  65. else if (shifted_port(port))
  66. v = (*port2adr(port) >> 8); 
  67. else
  68. v = (*port2adr(port))&0xff; 
  69. delay();
  70. return v;
  71. }
  72. unsigned short se_inw(unsigned long port)
  73. {
  74. if (port >= 0x2000 ||
  75.     (sh_pcic_io_start <= port && port <= sh_pcic_io_stop))
  76. return *port2adr(port);
  77. else
  78. maybebadio(inw, port);
  79. return 0;
  80. }
  81. unsigned int se_inl(unsigned long port)
  82. {
  83. maybebadio(inl, port);
  84. return 0;
  85. }
  86. void se_outb(unsigned char value, unsigned long port)
  87. {
  88. if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
  89. *(__u8 *)(sh_pcic_io_wbase + port) = value; 
  90. else if (shifted_port(port))
  91. *(port2adr(port)) = value << 8;
  92. else
  93. *(port2adr(port)) = value;
  94. }
  95. void se_outb_p(unsigned char value, unsigned long port)
  96. {
  97. if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
  98. *(__u8 *)(sh_pcic_io_wbase + port) = value; 
  99. else if (shifted_port(port))
  100. *(port2adr(port)) = value << 8;
  101. else
  102. *(port2adr(port)) = value;
  103. delay();
  104. }
  105. void se_outw(unsigned short value, unsigned long port)
  106. {
  107. if (port >= 0x2000 ||
  108.     (sh_pcic_io_start <= port && port <= sh_pcic_io_stop))
  109. *port2adr(port) = value;
  110. else
  111. maybebadio(outw, port);
  112. }
  113. void se_outl(unsigned int value, unsigned long port)
  114. {
  115. maybebadio(outl, port);
  116. }
  117. void se_insb(unsigned long port, void *addr, unsigned long count)
  118. {
  119. volatile __u16 *p = port2adr(port);
  120. if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) {
  121. volatile __u8 *bp = (__u8 *) (sh_pcic_io_wbase + 0x40000 + port); 
  122. while (count--)
  123. *((__u8 *) addr)++ = *bp;
  124. } else if (shifted_port(port)) {
  125. while (count--)
  126. *((__u8 *) addr)++ = *p >> 8;
  127. } else {
  128. while (count--)
  129. *((__u8 *) addr)++ = *p;
  130. }
  131. }
  132. void se_insw(unsigned long port, void *addr, unsigned long count)
  133. {
  134. volatile __u16 *p = port2adr(port);
  135. while (count--)
  136. *((__u16 *) addr)++ = *p;
  137. }
  138. void se_insl(unsigned long port, void *addr, unsigned long count)
  139. {
  140. maybebadio(insl, port);
  141. }
  142. void se_outsb(unsigned long port, const void *addr, unsigned long count)
  143. {
  144. volatile __u16 *p = port2adr(port);
  145. if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) {
  146. volatile __u8 *bp = (__u8 *) (sh_pcic_io_wbase + port); 
  147. while (count--)
  148. *bp = *((__u8 *) addr)++;
  149. } else if (shifted_port(port)) {
  150. while (count--)
  151. *p = *((__u8 *) addr)++ << 8;
  152. } else {
  153. while (count--)
  154. *p = *((__u8 *) addr)++;
  155. }
  156. }
  157. void se_outsw(unsigned long port, const void *addr, unsigned long count)
  158. {
  159. volatile __u16 *p = port2adr(port);
  160. while (count--)
  161. *p = *((__u16 *) addr)++;
  162. }
  163. void se_outsl(unsigned long port, const void *addr, unsigned long count)
  164. {
  165. maybebadio(outsw, port);
  166. }
  167. unsigned char se_readb(unsigned long addr)
  168. {
  169. return *(volatile unsigned char*)addr;
  170. }
  171. unsigned short se_readw(unsigned long addr)
  172. {
  173. return *(volatile unsigned short*)addr;
  174. }
  175. unsigned int se_readl(unsigned long addr)
  176. {
  177. return *(volatile unsigned long*)addr;
  178. }
  179. void se_writeb(unsigned char b, unsigned long addr)
  180. {
  181. *(volatile unsigned char*)addr = b;
  182. }
  183. void se_writew(unsigned short b, unsigned long addr)
  184. {
  185. *(volatile unsigned short*)addr = b;
  186. }
  187. void se_writel(unsigned int b, unsigned long addr)
  188. {
  189.         *(volatile unsigned long*)addr = b;
  190. }
  191. /* Map ISA bus address to the real address. Only for PCMCIA.  */
  192. /* ISA page descriptor.  */
  193. static __u32 sh_isa_memmap[256];
  194. static int
  195. sh_isa_mmap(__u32 start, __u32 length, __u32 offset)
  196. {
  197. int idx;
  198. if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000))
  199. return -1;
  200. idx = start >> 12;
  201. sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff);
  202. #if 0
  203. printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)n",
  204.        start, length, offset, idx, sh_isa_memmap[idx]);
  205. #endif
  206. return 0;
  207. }
  208. unsigned long
  209. se_isa_port2addr(unsigned long offset)
  210. {
  211. int idx;
  212. idx = (offset >> 12) & 0xff;
  213. offset &= 0xfff;
  214. return sh_isa_memmap[idx] + offset;
  215. }