io.c 4.1 KB

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