io_bigsur.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:7k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * include/asm-sh/io_bigsur.c
  3.  *
  4.  * By Dustin McIntire (dustin@sensoria.com) (c)2001
  5.  * Derived from io_hd64465.h, which bore the message:
  6.  * By Greg Banks <gbanks@pocketpenguins.com>
  7.  * (c) 2000 PocketPenguins Inc. 
  8.  * and from io_hd64461.h, which bore the message:
  9.  * Copyright 2000 Stuart Menefy (stuart.menefy@st.com)
  10.  *
  11.  * May be copied or modified under the terms of the GNU General Public
  12.  * License.  See linux/COPYING for more information.
  13.  *
  14.  * IO functions for a Hitachi Big Sur Evaluation Board.
  15.  */
  16. #include <linux/config.h>
  17. #include <linux/kernel.h>
  18. #include <linux/module.h>
  19. #include <asm/machvec.h>
  20. #include <asm/io.h>
  21. #include <asm/bigsur.h>
  22. //#define BIGSUR_DEBUG 2
  23. #undef BIGSUR_DEBUG
  24. #ifdef BIGSUR_DEBUG
  25. #define DPRINTK(args...) printk(args)
  26. #define DIPRINTK(n, args...) if (BIGSUR_DEBUG>(n)) printk(args)
  27. #else
  28. #define DPRINTK(args...)
  29. #define DIPRINTK(n, args...)
  30. #endif
  31. /* Low iomap maps port 0-1K to addresses in 8byte chunks */
  32. #define BIGSUR_IOMAP_LO_THRESH 0x400
  33. #define BIGSUR_IOMAP_LO_SHIFT 3
  34. #define BIGSUR_IOMAP_LO_MASK ((1<<BIGSUR_IOMAP_LO_SHIFT)-1)
  35. #define BIGSUR_IOMAP_LO_NMAP (BIGSUR_IOMAP_LO_THRESH>>BIGSUR_IOMAP_LO_SHIFT)
  36. static u32 bigsur_iomap_lo[BIGSUR_IOMAP_LO_NMAP];
  37. static u8 bigsur_iomap_lo_shift[BIGSUR_IOMAP_LO_NMAP];
  38. /* High iomap maps port 1K-64K to addresses in 1K chunks */
  39. #define BIGSUR_IOMAP_HI_THRESH 0x10000
  40. #define BIGSUR_IOMAP_HI_SHIFT 10
  41. #define BIGSUR_IOMAP_HI_MASK ((1<<BIGSUR_IOMAP_HI_SHIFT)-1)
  42. #define BIGSUR_IOMAP_HI_NMAP (BIGSUR_IOMAP_HI_THRESH>>BIGSUR_IOMAP_HI_SHIFT)
  43. static u32 bigsur_iomap_hi[BIGSUR_IOMAP_HI_NMAP];
  44. static u8 bigsur_iomap_hi_shift[BIGSUR_IOMAP_HI_NMAP];
  45. #ifndef MAX
  46. #define MAX(a,b)    ((a)>(b)?(a):(b))
  47. #endif
  48. #define PORT2ADDR(x) (sh_mv.mv_isa_port2addr(x))
  49. void bigsur_port_map(u32 baseport, u32 nports, u32 addr, u8 shift)
  50. {
  51.     u32 port, endport = baseport + nports;
  52.     DPRINTK("bigsur_port_map(base=0x%0x, n=0x%0x, addr=0x%08x)n",
  53.     baseport, nports, addr);
  54.     
  55. for (port = baseport ;
  56.      port < endport && port < BIGSUR_IOMAP_LO_THRESH ;
  57.      port += (1<<BIGSUR_IOMAP_LO_SHIFT)) {
  58.      DPRINTK("    maplo[0x%x] = 0x%08xn", port, addr);
  59.          bigsur_iomap_lo[port>>BIGSUR_IOMAP_LO_SHIFT] = addr;
  60.          bigsur_iomap_lo_shift[port>>BIGSUR_IOMAP_LO_SHIFT] = shift;
  61.      addr += (1<<(BIGSUR_IOMAP_LO_SHIFT));
  62. }
  63. for (port = MAX(baseport, BIGSUR_IOMAP_LO_THRESH) ;
  64.      port < endport && port < BIGSUR_IOMAP_HI_THRESH ;
  65.      port += (1<<BIGSUR_IOMAP_HI_SHIFT)) {
  66.      DPRINTK("    maphi[0x%x] = 0x%08xn", port, addr);
  67.          bigsur_iomap_hi[port>>BIGSUR_IOMAP_HI_SHIFT] = addr;
  68.          bigsur_iomap_hi_shift[port>>BIGSUR_IOMAP_HI_SHIFT] = shift;
  69.      addr += (1<<(BIGSUR_IOMAP_HI_SHIFT));
  70. }
  71. }
  72. EXPORT_SYMBOL(bigsur_port_map);
  73. void bigsur_port_unmap(u32 baseport, u32 nports)
  74. {
  75.     u32 port, endport = baseport + nports;
  76.     DPRINTK("bigsur_port_unmap(base=0x%0x, n=0x%0x)n", baseport, nports);
  77. for (port = baseport ;
  78.      port < endport && port < BIGSUR_IOMAP_LO_THRESH ;
  79.      port += (1<<BIGSUR_IOMAP_LO_SHIFT)) {
  80.          bigsur_iomap_lo[port>>BIGSUR_IOMAP_LO_SHIFT] = 0;
  81. }
  82. for (port = MAX(baseport, BIGSUR_IOMAP_LO_THRESH) ;
  83.      port < endport && port < BIGSUR_IOMAP_HI_THRESH ;
  84.      port += (1<<BIGSUR_IOMAP_HI_SHIFT)) {
  85.          bigsur_iomap_hi[port>>BIGSUR_IOMAP_HI_SHIFT] = 0;
  86. }
  87. }
  88. EXPORT_SYMBOL(bigsur_port_unmap);
  89. unsigned long bigsur_isa_port2addr(unsigned long port)
  90. {
  91.     unsigned long addr = 0;
  92. unsigned char shift;
  93. /* Physical address not in P0, do nothing */
  94. if (PXSEG(port)) addr = port;
  95. /* physical address in P0, map to P2 */
  96. else if (port >= 0x30000)
  97.     addr = P2SEGADDR(port);
  98. /* Big Sur I/O + HD64465 registers 0x10000-0x30000 */
  99. else if (port >= BIGSUR_IOMAP_HI_THRESH)
  100.     addr = BIGSUR_INTERNAL_BASE + (port - BIGSUR_IOMAP_HI_THRESH);
  101. /* Handle remapping of high IO/PCI IO ports */
  102. else if (port >= BIGSUR_IOMAP_LO_THRESH) {
  103.     addr = bigsur_iomap_hi[port >> BIGSUR_IOMAP_HI_SHIFT];
  104.     shift = bigsur_iomap_hi_shift[port >> BIGSUR_IOMAP_HI_SHIFT];
  105.     if (addr != 0)
  106.     addr += (port & BIGSUR_IOMAP_HI_MASK) << shift;
  107. }
  108. /* Handle remapping of low IO ports */
  109. else {
  110.     addr = bigsur_iomap_lo[port >> BIGSUR_IOMAP_LO_SHIFT];
  111.     shift = bigsur_iomap_lo_shift[port >> BIGSUR_IOMAP_LO_SHIFT];
  112.     if (addr != 0)
  113.      addr += (port & BIGSUR_IOMAP_LO_MASK) << shift;
  114. }
  115.     DIPRINTK(2, "PORT2ADDR(0x%08lx) = 0x%08lxn", port, addr);
  116. return addr;
  117. }
  118. static inline void delay(void)
  119. {
  120. ctrl_inw(0xa0000000);
  121. }
  122. unsigned char bigsur_inb(unsigned long port)
  123. {
  124. unsigned long addr = PORT2ADDR(port);
  125. unsigned long b = (addr == 0 ? 0 : *(volatile unsigned char*)addr);
  126. DIPRINTK(0, "inb(%08lx) = %02xn", addr, (unsigned)b);
  127. return b;
  128. }
  129. unsigned char bigsur_inb_p(unsigned long port)
  130. {
  131.     unsigned long v;
  132. unsigned long addr = PORT2ADDR(port);
  133. v = (addr == 0 ? 0 : *(volatile unsigned char*)addr);
  134. delay();
  135. DIPRINTK(0, "inb_p(%08lx) = %02xn", addr, (unsigned)v);
  136. return v;
  137. }
  138. unsigned short bigsur_inw(unsigned long port)
  139. {
  140.     unsigned long addr = PORT2ADDR(port);
  141. unsigned long b = (addr == 0 ? 0 : *(volatile unsigned short*)addr);
  142. DIPRINTK(0, "inw(%08lx) = %04lxn", addr, b);
  143. return b;
  144. }
  145. unsigned int bigsur_inl(unsigned long port)
  146. {
  147.     unsigned long addr = PORT2ADDR(port);
  148. unsigned int b = (addr == 0 ? 0 : *(volatile unsigned long*)addr);
  149. DIPRINTK(0, "inl(%08lx) = %08xn", addr, b);
  150. return b;
  151. }
  152. void bigsur_insb(unsigned long port, void *buffer, unsigned long count)
  153. {
  154. unsigned char *buf=buffer;
  155. while(count--) *buf++=inb(port);
  156. }
  157. void bigsur_insw(unsigned long port, void *buffer, unsigned long count)
  158. {
  159. unsigned short *buf=buffer;
  160. while(count--) *buf++=inw(port);
  161. }
  162. void bigsur_insl(unsigned long port, void *buffer, unsigned long count)
  163. {
  164. unsigned long *buf=buffer;
  165. while(count--) *buf++=inl(port);
  166. }
  167. void bigsur_outb(unsigned char b, unsigned long port)
  168. {
  169. unsigned long addr = PORT2ADDR(port);
  170. DIPRINTK(0, "outb(%02x, %08lx)n", (unsigned)b, addr);
  171. if (addr != 0)
  172.     *(volatile unsigned char*)addr = b;
  173. }
  174. void bigsur_outb_p(unsigned char b, unsigned long port)
  175. {
  176. unsigned long addr = PORT2ADDR(port);
  177. DIPRINTK(0, "outb_p(%02x, %08lx)n", (unsigned)b, addr);
  178.     if (addr != 0)
  179.     *(volatile unsigned char*)addr = b;
  180. delay();
  181. }
  182. void bigsur_outw(unsigned short b, unsigned long port)
  183. {
  184. unsigned long addr = PORT2ADDR(port);
  185. DIPRINTK(0, "outw(%04x, %08lx)n", (unsigned)b, addr);
  186. if (addr != 0)
  187.     *(volatile unsigned short*)addr = b;
  188. }
  189. void bigsur_outl(unsigned int b, unsigned long port)
  190. {
  191. unsigned long addr = PORT2ADDR(port);
  192. DIPRINTK(0, "outl(%08x, %08lx)n", b, addr);
  193. if (addr != 0)
  194.             *(volatile unsigned long*)addr = b;
  195. }
  196. void bigsur_outsb(unsigned long port, const void *buffer, unsigned long count)
  197. {
  198. const unsigned char *buf=buffer;
  199. while(count--) outb(*buf++, port);
  200. }
  201. void bigsur_outsw(unsigned long port, const void *buffer, unsigned long count)
  202. {
  203. const unsigned short *buf=buffer;
  204. while(count--) outw(*buf++, port);
  205. }
  206. void bigsur_outsl(unsigned long port, const void *buffer, unsigned long count)
  207. {
  208. const unsigned long *buf=buffer;
  209. while(count--) outl(*buf++, port);
  210. }