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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* 
  2.  * linux/arch/sh/kernel/io_cat68701.c
  3.  *
  4.  * Copyright (C) 2000  Niibe Yutaka
  5.  *               2001  Yutaro Ebihara
  6.  *
  7.  * I/O routine and setup routines for A-ONE Corp CAT-68701 SH7708 Board
  8.  *
  9.  * This file is subject to the terms and conditions of the GNU General Public
  10.  * License.  See the file "COPYING" in the main directory of this archive
  11.  * for more details.
  12.  *
  13.  */
  14. #include <asm/io.h>
  15. #include <asm/machvec.h>
  16. #include <linux/config.h>
  17. #include <linux/module.h>
  18. #define SH3_PCMCIA_BUG_WORKAROUND 1
  19. #define DUMMY_READ_AREA6   0xba000000
  20. #define PORT2ADDR(x) (cat68701_isa_port2addr(x))
  21. static inline void delay(void)
  22. {
  23. ctrl_inw(0xa0000000);
  24. }
  25. unsigned char cat68701_inb(unsigned long port)
  26. {
  27. return *(volatile unsigned char*)PORT2ADDR(port);
  28. }
  29. unsigned short cat68701_inw(unsigned long port)
  30. {
  31. return *(volatile unsigned short*)PORT2ADDR(port);
  32. }
  33. unsigned int cat68701_inl(unsigned long port)
  34. {
  35. return *(volatile unsigned long*)PORT2ADDR(port);
  36. }
  37. unsigned char cat68701_inb_p(unsigned long port)
  38. {
  39. unsigned long v = *(volatile unsigned char*)PORT2ADDR(port);
  40. delay();
  41. return v;
  42. }
  43. unsigned short cat68701_inw_p(unsigned long port)
  44. {
  45. unsigned long v = *(volatile unsigned short*)PORT2ADDR(port);
  46. delay();
  47. return v;
  48. }
  49. unsigned int cat68701_inl_p(unsigned long port)
  50. {
  51. unsigned long v = *(volatile unsigned long*)PORT2ADDR(port);
  52. delay();
  53. return v;
  54. }
  55. void cat68701_insb(unsigned long port, void *buffer, unsigned long count)
  56. {
  57. unsigned char *buf=buffer;
  58. while(count--) *buf++=inb(port);
  59. }
  60. void cat68701_insw(unsigned long port, void *buffer, unsigned long count)
  61. {
  62. unsigned short *buf=buffer;
  63. while(count--) *buf++=inw(port);
  64. #ifdef SH3_PCMCIA_BUG_WORKAROUND
  65. ctrl_inb (DUMMY_READ_AREA6);
  66. #endif
  67. }
  68. void cat68701_insl(unsigned long port, void *buffer, unsigned long count)
  69. {
  70. unsigned long *buf=buffer;
  71. while(count--) *buf++=inl(port);
  72. #ifdef SH3_PCMCIA_BUG_WORKAROUND
  73. ctrl_inb (DUMMY_READ_AREA6);
  74. #endif
  75. }
  76. void cat68701_outb(unsigned char b, unsigned long port)
  77. {
  78. *(volatile unsigned char*)PORT2ADDR(port) = b;
  79. }
  80. void cat68701_outw(unsigned short b, unsigned long port)
  81. {
  82. *(volatile unsigned short*)PORT2ADDR(port) = b;
  83. }
  84. void cat68701_outl(unsigned int b, unsigned long port)
  85. {
  86.         *(volatile unsigned long*)PORT2ADDR(port) = b;
  87. }
  88. void cat68701_outb_p(unsigned char b, unsigned long port)
  89. {
  90. *(volatile unsigned char*)PORT2ADDR(port) = b;
  91. delay();
  92. }
  93. void cat68701_outw_p(unsigned short b, unsigned long port)
  94. {
  95. *(volatile unsigned short*)PORT2ADDR(port) = b;
  96. delay();
  97. }
  98. void cat68701_outl_p(unsigned int b, unsigned long port)
  99. {
  100. *(volatile unsigned long*)PORT2ADDR(port) = b;
  101. delay();
  102. }
  103. void cat68701_outsb(unsigned long port, const void *buffer, unsigned long count)
  104. {
  105. const unsigned char *buf=buffer;
  106. while(count--) outb(*buf++, port);
  107. }
  108. void cat68701_outsw(unsigned long port, const void *buffer, unsigned long count)
  109. {
  110. const unsigned short *buf=buffer;
  111. while(count--) outw(*buf++, port);
  112. #ifdef SH3_PCMCIA_BUG_WORKAROUND
  113. ctrl_inb (DUMMY_READ_AREA6);
  114. #endif
  115. }
  116. void cat68701_outsl(unsigned long port, const void *buffer, unsigned long count)
  117. {
  118. const unsigned long *buf=buffer;
  119. while(count--) outl(*buf++, port);
  120. #ifdef SH3_PCMCIA_BUG_WORKAROUND
  121. ctrl_inb (DUMMY_READ_AREA6);
  122. #endif
  123. }
  124. unsigned char cat68701_readb(unsigned long addr)
  125. {
  126. return *(volatile unsigned char*)addr;
  127. }
  128. unsigned short cat68701_readw(unsigned long addr)
  129. {
  130. return *(volatile unsigned short*)addr;
  131. }
  132. unsigned int cat68701_readl(unsigned long addr)
  133. {
  134. return *(volatile unsigned long*)addr;
  135. }
  136. void cat68701_writeb(unsigned char b, unsigned long addr)
  137. {
  138. *(volatile unsigned char*)addr = b;
  139. }
  140. void cat68701_writew(unsigned short b, unsigned long addr)
  141. {
  142. *(volatile unsigned short*)addr = b;
  143. }
  144. void cat68701_writel(unsigned int b, unsigned long addr)
  145. {
  146.         *(volatile unsigned long*)addr = b;
  147. }
  148. void * cat68701_ioremap(unsigned long offset, unsigned long size)
  149. {
  150. return (void *) P2SEGADDR(offset);
  151. }
  152. EXPORT_SYMBOL(cat68701_ioremap);
  153. void cat68701_iounmap(void *addr)
  154. {
  155. }
  156. EXPORT_SYMBOL(cat68701_iounmap);
  157. unsigned long cat68701_isa_port2addr(unsigned long offset)
  158. {
  159.   /* CompactFlash (IDE) */
  160.   if(((offset >= 0x1f0) && (offset <= 0x1f7)) || (offset==0x3f6))
  161.     return 0xba000000 + offset;
  162.   /* INPUT PORT */
  163.   if((offset >= 0x3fc) && (offset <= 0x3fd))
  164.     return 0xb4007000 + offset;
  165.   /* OUTPUT PORT */
  166.   if((offset >= 0x3fe) && (offset <= 0x3ff))
  167.     return 0xb4007400 + offset;
  168.   return offset + 0xb4000000; /* other I/O (EREA 5)*/
  169. }
  170. int cat68701_irq_demux(int irq)
  171. {
  172.   if(irq==13) return 14;
  173.   if(irq==7)  return 10;
  174.   return irq;
  175. }
  176. /*-------------------------------------------------------*/
  177. void setup_cat68701(){
  178.   /* dummy read erea5 (CS8900A) */
  179. }
  180. void init_cat68701_IRQ(){
  181.   make_imask_irq(10);
  182.   make_imask_irq(14);
  183. }
  184. #ifdef CONFIG_HEARTBEAT
  185. #include <linux/sched.h>
  186. void heartbeat_cat68701()
  187. {
  188.         static unsigned int cnt = 0, period = 0 , bit = 0;
  189.         cnt += 1;
  190.         if (cnt < period) {
  191.                 return;
  192.         }
  193.         cnt = 0;
  194.         /* Go through the points (roughly!):
  195.          * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
  196.          */
  197.         period = 110 - ( (300<<FSHIFT)/
  198.                          ((avenrun[0]/5) + (3<<FSHIFT)) );
  199. if(bit){ bit=0; }else{ bit=1; }
  200. outw(bit<<15,0x3fe);
  201. }
  202. #endif /* CONFIG_HEARTBEAT */