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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * $Id: io_hd64465.c,v 1.7 2001/05/09 07:39:36 gniibe Exp $
  3.  * by Greg Banks <gbanks@pocketpenguins.com>
  4.  * (c) 2000 PocketPenguins Inc
  5.  *
  6.  * Derived from io_hd64461.c, which bore the message:
  7.  * Copyright (C) 2000 YAEGASHI Takeshi
  8.  *
  9.  * Typical I/O routines for HD64465 system.
  10.  */
  11. #include <linux/config.h>
  12. #include <linux/kernel.h>
  13. #include <linux/module.h>
  14. #include <asm/io.h>
  15. #include <asm/hd64465.h>
  16. #define HD64465_DEBUG 0
  17. #if HD64465_DEBUG
  18. #define DPRINTK(args...) printk(args)
  19. #define DIPRINTK(n, args...) if (hd64465_io_debug>(n)) printk(args)
  20. #else
  21. #define DPRINTK(args...)
  22. #define DIPRINTK(n, args...)
  23. #endif
  24. /* This is a hack suitable only for debugging IO port problems */
  25. int hd64465_io_debug;
  26. EXPORT_SYMBOL(hd64465_io_debug);
  27. /* Low iomap maps port 0-1K to addresses in 8byte chunks */
  28. #define HD64465_IOMAP_LO_THRESH 0x400
  29. #define HD64465_IOMAP_LO_SHIFT 3
  30. #define HD64465_IOMAP_LO_MASK ((1<<HD64465_IOMAP_LO_SHIFT)-1)
  31. #define HD64465_IOMAP_LO_NMAP (HD64465_IOMAP_LO_THRESH>>HD64465_IOMAP_LO_SHIFT)
  32. static unsigned long hd64465_iomap_lo[HD64465_IOMAP_LO_NMAP];
  33. static unsigned char hd64465_iomap_lo_shift[HD64465_IOMAP_LO_NMAP];
  34. /* High iomap maps port 1K-64K to addresses in 1K chunks */
  35. #define HD64465_IOMAP_HI_THRESH 0x10000
  36. #define HD64465_IOMAP_HI_SHIFT 10
  37. #define HD64465_IOMAP_HI_MASK ((1<<HD64465_IOMAP_HI_SHIFT)-1)
  38. #define HD64465_IOMAP_HI_NMAP (HD64465_IOMAP_HI_THRESH>>HD64465_IOMAP_HI_SHIFT)
  39. static unsigned long hd64465_iomap_hi[HD64465_IOMAP_HI_NMAP];
  40. static unsigned char hd64465_iomap_hi_shift[HD64465_IOMAP_HI_NMAP];
  41. #ifndef MAX
  42. #define MAX(a,b)    ((a)>(b)?(a):(b))
  43. #endif
  44. #define PORT2ADDR(x) (sh_mv.mv_isa_port2addr(x))
  45. void hd64465_port_map(unsigned short baseport, unsigned int nports,
  46.       unsigned long addr, unsigned char shift)
  47. {
  48.      unsigned int port, endport = baseport + nports;
  49.      DPRINTK("hd64465_port_map(base=0x%04hx, n=0x%04hx, addr=0x%08lx,endport=0x%04x)n",
  50.     baseport, nports, addr,endport);
  51.     
  52. for (port = baseport ;
  53.      port < endport && port < HD64465_IOMAP_LO_THRESH ;
  54.      port += (1<<HD64465_IOMAP_LO_SHIFT)) {
  55.     DPRINTK("    maplo[0x%x] = 0x%08lxn", port, addr);
  56.          hd64465_iomap_lo[port>>HD64465_IOMAP_LO_SHIFT] = addr;
  57.          hd64465_iomap_lo_shift[port>>HD64465_IOMAP_LO_SHIFT] = shift;
  58.     addr += (1<<(HD64465_IOMAP_LO_SHIFT));
  59. }
  60. for (port = MAX(baseport, HD64465_IOMAP_LO_THRESH) ;
  61.      port < endport && port < HD64465_IOMAP_HI_THRESH ;
  62.      port += (1<<HD64465_IOMAP_HI_SHIFT)) {
  63.     DPRINTK("    maphi[0x%x] = 0x%08lxn", port, addr);
  64.          hd64465_iomap_hi[port>>HD64465_IOMAP_HI_SHIFT] = addr;
  65.          hd64465_iomap_hi_shift[port>>HD64465_IOMAP_HI_SHIFT] = shift;
  66.     addr += (1<<(HD64465_IOMAP_HI_SHIFT));
  67. }
  68. }
  69. EXPORT_SYMBOL(hd64465_port_map);
  70. void hd64465_port_unmap(unsigned short baseport, unsigned int nports)
  71. {
  72.      unsigned int port, endport = baseport + nports;
  73.      DPRINTK("hd64465_port_unmap(base=0x%04hx, n=0x%04hx)n",
  74.     baseport, nports);
  75. for (port = baseport ;
  76.      port < endport && port < HD64465_IOMAP_LO_THRESH ;
  77.      port += (1<<HD64465_IOMAP_LO_SHIFT)) {
  78.          hd64465_iomap_lo[port>>HD64465_IOMAP_LO_SHIFT] = 0;
  79. }
  80. for (port = MAX(baseport, HD64465_IOMAP_LO_THRESH) ;
  81.      port < endport && port < HD64465_IOMAP_HI_THRESH ;
  82.      port += (1<<HD64465_IOMAP_HI_SHIFT)) {
  83.          hd64465_iomap_hi[port>>HD64465_IOMAP_HI_SHIFT] = 0;
  84. }
  85. }
  86. EXPORT_SYMBOL(hd64465_port_unmap);
  87. unsigned long hd64465_isa_port2addr(unsigned long port)
  88. {
  89.      unsigned long addr = 0;
  90. unsigned char shift;
  91. /* handle remapping of low IO ports */
  92. if (port < HD64465_IOMAP_LO_THRESH) {
  93.     addr = hd64465_iomap_lo[port >> HD64465_IOMAP_LO_SHIFT];
  94.     shift = hd64465_iomap_lo_shift[port >> HD64465_IOMAP_LO_SHIFT];
  95.     if (addr != 0)
  96.      addr += (port & HD64465_IOMAP_LO_MASK) << shift;
  97.     else
  98. printk(KERN_NOTICE "io_hd64465: access to un-mapped port %lxn", port);
  99. } else if (port < HD64465_IOMAP_HI_THRESH) {
  100.     addr = hd64465_iomap_hi[port >> HD64465_IOMAP_HI_SHIFT];
  101.     shift = hd64465_iomap_hi_shift[port >> HD64465_IOMAP_HI_SHIFT];
  102.     if (addr != 0)
  103. addr += (port & HD64465_IOMAP_HI_MASK) << shift;
  104.     else
  105. printk(KERN_NOTICE "io_hd64465: access to un-mapped port %lxn", port);
  106. }
  107.     
  108. /* HD64465 internal devices (0xb0000000) */
  109. else if (port < 0x20000)
  110.     addr = CONFIG_HD64465_IOBASE + port - 0x10000;
  111. /* Whole physical address space (0xa0000000) */
  112. else
  113.     addr = P2SEGADDR(port);
  114.      DIPRINTK(2, "PORT2ADDR(0x%08lx) = 0x%08lxn", port, addr);
  115. return addr;
  116. }
  117. static inline void delay(void)
  118. {
  119. ctrl_inw(0xa0000000);
  120. }
  121. unsigned char hd64465_inb(unsigned long port)
  122. {
  123. unsigned long addr = PORT2ADDR(port);
  124. unsigned long b = (addr == 0 ? 0 : *(volatile unsigned char*)addr);
  125. DIPRINTK(0, "inb(%08lx) = %02xn", addr, (unsigned)b);
  126. return b;
  127. }
  128. unsigned char hd64465_inb_p(unsigned long port)
  129. {
  130.      unsigned long v;
  131. unsigned long addr = PORT2ADDR(port);
  132. v = (addr == 0 ? 0 : *(volatile unsigned char*)addr);
  133. delay();
  134. DIPRINTK(0, "inb_p(%08lx) = %02xn", addr, (unsigned)v);
  135. return v;
  136. }
  137. unsigned short hd64465_inw(unsigned long port)
  138. {
  139.      unsigned long addr = PORT2ADDR(port);
  140. unsigned long b = (addr == 0 ? 0 : *(volatile unsigned short*)addr);
  141. DIPRINTK(0, "inw(%08lx) = %04lxn", addr, b);
  142. return b;
  143. }
  144. unsigned int hd64465_inl(unsigned long port)
  145. {
  146.      unsigned long addr = PORT2ADDR(port);
  147. unsigned int b = (addr == 0 ? 0 : *(volatile unsigned long*)addr);
  148. DIPRINTK(0, "inl(%08lx) = %08xn", addr, b);
  149. return b;
  150. }
  151. void hd64465_insb(unsigned long port, void *buffer, unsigned long count)
  152. {
  153. unsigned char *buf=buffer;
  154. while(count--) *buf++=inb(port);
  155. }
  156. void hd64465_insw(unsigned long port, void *buffer, unsigned long count)
  157. {
  158. unsigned short *buf=buffer;
  159. while(count--) *buf++=inw(port);
  160. }
  161. void hd64465_insl(unsigned long port, void *buffer, unsigned long count)
  162. {
  163. unsigned long *buf=buffer;
  164. while(count--) *buf++=inl(port);
  165. }
  166. void hd64465_outb(unsigned char b, unsigned long port)
  167. {
  168. unsigned long addr = PORT2ADDR(port);
  169. DIPRINTK(0, "outb(%02x, %08lx)n", (unsigned)b, addr);
  170. if (addr != 0)
  171.     *(volatile unsigned char*)addr = b;
  172. }
  173. void hd64465_outb_p(unsigned char b, unsigned long port)
  174. {
  175. unsigned long addr = PORT2ADDR(port);
  176. DIPRINTK(0, "outb_p(%02x, %08lx)n", (unsigned)b, addr);
  177.      if (addr != 0)
  178.     *(volatile unsigned char*)addr = b;
  179. delay();
  180. }
  181. void hd64465_outw(unsigned short b, unsigned long port)
  182. {
  183. unsigned long addr = PORT2ADDR(port);
  184. DIPRINTK(0, "outw(%04x, %08lx)n", (unsigned)b, addr);
  185. if (addr != 0)
  186.     *(volatile unsigned short*)addr = b;
  187. }
  188. void hd64465_outl(unsigned int b, unsigned long port)
  189. {
  190. unsigned long addr = PORT2ADDR(port);
  191. DIPRINTK(0, "outl(%08x, %08lx)n", b, addr);
  192. if (addr != 0)
  193.             *(volatile unsigned long*)addr = b;
  194. }
  195. void hd64465_outsb(unsigned long port, const void *buffer, unsigned long count)
  196. {
  197. const unsigned char *buf=buffer;
  198. while(count--) outb(*buf++, port);
  199. }
  200. void hd64465_outsw(unsigned long port, const void *buffer, unsigned long count)
  201. {
  202. const unsigned short *buf=buffer;
  203. while(count--) outw(*buf++, port);
  204. }
  205. void hd64465_outsl(unsigned long port, const void *buffer, unsigned long count)
  206. {
  207. const unsigned long *buf=buffer;
  208. while(count--) outl(*buf++, port);
  209. }