io.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /* $Id: io.c,v 1.7 2006/02/05 21:55:29 lethal 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/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. /* MS7750 requires special versions of in*, out* routines, since
  21. PC-like io ports are located at upper half byte of 16-bit word which
  22. can be accessed only with 16-bit wide. */
  23. static inline volatile __u16 *
  24. port2adr(unsigned int port)
  25. {
  26. if (port & 0xff000000)
  27. return ( volatile __u16 *) port;
  28. if (port >= 0x2000)
  29. return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
  30. else if (port >= 0x1000)
  31. return (volatile __u16 *) (PA_83902 + (port << 1));
  32. else if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
  33. return (volatile __u16 *) (sh_pcic_io_wbase + (port &~ 1));
  34. else
  35. return (volatile __u16 *) (PA_SUPERIO + (port << 1));
  36. }
  37. static inline int
  38. shifted_port(unsigned long port)
  39. {
  40. /* For IDE registers, value is not shifted */
  41. if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
  42. return 0;
  43. else
  44. return 1;
  45. }
  46. unsigned char se_inb(unsigned long port)
  47. {
  48. if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
  49. return *(__u8 *) (sh_pcic_io_wbase + 0x40000 + port);
  50. else if (shifted_port(port))
  51. return (*port2adr(port) >> 8);
  52. else
  53. return (*port2adr(port))&0xff;
  54. }
  55. unsigned char se_inb_p(unsigned long port)
  56. {
  57. unsigned long v;
  58. if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
  59. v = *(__u8 *) (sh_pcic_io_wbase + 0x40000 + port);
  60. else if (shifted_port(port))
  61. v = (*port2adr(port) >> 8);
  62. else
  63. v = (*port2adr(port))&0xff;
  64. ctrl_delay();
  65. return v;
  66. }
  67. unsigned short se_inw(unsigned long port)
  68. {
  69. if (port >= 0x2000 ||
  70. (sh_pcic_io_start <= port && port <= sh_pcic_io_stop))
  71. return *port2adr(port);
  72. else
  73. maybebadio(port);
  74. return 0;
  75. }
  76. unsigned int se_inl(unsigned long port)
  77. {
  78. maybebadio(port);
  79. return 0;
  80. }
  81. void se_outb(unsigned char value, unsigned long port)
  82. {
  83. if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
  84. *(__u8 *)(sh_pcic_io_wbase + port) = value;
  85. else if (shifted_port(port))
  86. *(port2adr(port)) = value << 8;
  87. else
  88. *(port2adr(port)) = value;
  89. }
  90. void se_outb_p(unsigned char value, unsigned long port)
  91. {
  92. if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
  93. *(__u8 *)(sh_pcic_io_wbase + port) = value;
  94. else if (shifted_port(port))
  95. *(port2adr(port)) = value << 8;
  96. else
  97. *(port2adr(port)) = value;
  98. ctrl_delay();
  99. }
  100. void se_outw(unsigned short value, unsigned long port)
  101. {
  102. if (port >= 0x2000 ||
  103. (sh_pcic_io_start <= port && port <= sh_pcic_io_stop))
  104. *port2adr(port) = value;
  105. else
  106. maybebadio(port);
  107. }
  108. void se_outl(unsigned int value, unsigned long port)
  109. {
  110. maybebadio(port);
  111. }
  112. void se_insb(unsigned long port, void *addr, unsigned long count)
  113. {
  114. volatile __u16 *p = port2adr(port);
  115. __u8 *ap = addr;
  116. if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) {
  117. volatile __u8 *bp = (__u8 *) (sh_pcic_io_wbase + 0x40000 + port);
  118. while (count--)
  119. *ap++ = *bp;
  120. } else if (shifted_port(port)) {
  121. while (count--)
  122. *ap++ = *p >> 8;
  123. } else {
  124. while (count--)
  125. *ap++ = *p;
  126. }
  127. }
  128. void se_insw(unsigned long port, void *addr, unsigned long count)
  129. {
  130. volatile __u16 *p = port2adr(port);
  131. __u16 *ap = addr;
  132. while (count--)
  133. *ap++ = *p;
  134. }
  135. void se_insl(unsigned long port, void *addr, unsigned long count)
  136. {
  137. maybebadio(port);
  138. }
  139. void se_outsb(unsigned long port, const void *addr, unsigned long count)
  140. {
  141. volatile __u16 *p = port2adr(port);
  142. const __u8 *ap = addr;
  143. if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) {
  144. volatile __u8 *bp = (__u8 *) (sh_pcic_io_wbase + port);
  145. while (count--)
  146. *bp = *ap++;
  147. } else if (shifted_port(port)) {
  148. while (count--)
  149. *p = *ap++ << 8;
  150. } else {
  151. while (count--)
  152. *p = *ap++;
  153. }
  154. }
  155. void se_outsw(unsigned long port, const void *addr, unsigned long count)
  156. {
  157. volatile __u16 *p = port2adr(port);
  158. const __u16 *ap = addr;
  159. while (count--)
  160. *p = *ap++;
  161. }
  162. void se_outsl(unsigned long port, const void *addr, unsigned long count)
  163. {
  164. maybebadio(port);
  165. }