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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * linux/arch/arm/mach-sa1100/graphicsclient.c
  3.  *
  4.  * Author: Nicolas Pitre
  5.  *
  6.  * Pieces specific to the GraphicsClient board
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License version 2 as
  10.  * published by the Free Software Foundation.
  11.  */
  12. #include <linux/init.h>
  13. #include <linux/sched.h>
  14. #include <linux/interrupt.h>
  15. #include <linux/ptrace.h>
  16. #include <asm/hardware.h>
  17. #include <asm/setup.h>
  18. #include <asm/irq.h>
  19. #include <asm/mach/irq.h>
  20. #include <asm/mach/arch.h>
  21. #include <asm/mach/map.h>
  22. #include <asm/mach/serial_sa1100.h>
  23. #include <linux/serial_core.h>
  24. #include <asm/arch/irq.h>
  25. #include "generic.h"
  26. /*
  27.  * Handlers for GraphicsClient's external IRQ logic
  28.  */
  29. static void ADS_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs )
  30. {
  31. int i;
  32. while( (irq = ADS_INT_ST1 | (ADS_INT_ST2 << 8)) ){
  33. for( i = 0; i < 16; i++ )
  34. if( irq & (1<<i) )
  35. do_IRQ( ADS_EXT_IRQ(i), regs );
  36. }
  37. }
  38. static struct irqaction ADS_ext_irq = {
  39. name: "ADS_ext_IRQ",
  40. handler: ADS_IRQ_demux,
  41. flags: SA_INTERRUPT
  42. };
  43. static void ADS_mask_and_ack_irq0(unsigned int irq)
  44. {
  45. int mask = (1 << (irq - ADS_EXT_IRQ(0)));
  46. ADS_INT_EN1 &= ~mask;
  47. ADS_INT_ST1 = mask;
  48. }
  49. static void ADS_mask_irq0(unsigned int irq)
  50. {
  51. ADS_INT_ST1 = (1 << (irq - ADS_EXT_IRQ(0)));
  52. }
  53. static void ADS_unmask_irq0(unsigned int irq)
  54. {
  55. ADS_INT_EN1 |= (1 << (irq - ADS_EXT_IRQ(0)));
  56. }
  57. static void ADS_mask_and_ack_irq1(unsigned int irq)
  58. {
  59. int mask = (1 << (irq - ADS_EXT_IRQ(8)));
  60. ADS_INT_EN2 &= ~mask;
  61. ADS_INT_ST2 = mask;
  62. }
  63. static void ADS_mask_irq1(unsigned int irq)
  64. {
  65. ADS_INT_ST2 = (1 << (irq - ADS_EXT_IRQ(8)));
  66. }
  67. static void ADS_unmask_irq1(unsigned int irq)
  68. {
  69. ADS_INT_EN2 |= (1 << (irq - ADS_EXT_IRQ(8)));
  70. }
  71. static void __init graphicsclient_init_irq(void)
  72. {
  73. int irq;
  74. /* First the standard SA1100 IRQs */
  75. sa1100_init_irq();
  76. /* disable all IRQs */
  77. ADS_INT_EN1 = 0;
  78. ADS_INT_EN2 = 0;
  79. /* clear all IRQs */
  80. ADS_INT_ST1 = 0xff;
  81. ADS_INT_ST2 = 0xff;
  82. for (irq = ADS_EXT_IRQ(0); irq <= ADS_EXT_IRQ(7); irq++) {
  83. irq_desc[irq].valid = 1;
  84. irq_desc[irq].probe_ok = 1;
  85. irq_desc[irq].mask_ack = ADS_mask_and_ack_irq0;
  86. irq_desc[irq].mask = ADS_mask_irq0;
  87. irq_desc[irq].unmask = ADS_unmask_irq0;
  88. }
  89. for (irq = ADS_EXT_IRQ(8); irq <= ADS_EXT_IRQ(15); irq++) {
  90. irq_desc[irq].valid = 1;
  91. irq_desc[irq].probe_ok = 1;
  92. irq_desc[irq].mask_ack = ADS_mask_and_ack_irq1;
  93. irq_desc[irq].mask = ADS_mask_irq1;
  94. irq_desc[irq].unmask = ADS_unmask_irq1;
  95. }
  96. set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_FALLING_EDGE);
  97. setup_arm_irq( IRQ_GPIO0, &ADS_ext_irq );
  98. }
  99. /*
  100.  * Initialization fixup
  101.  */
  102. static void __init
  103. fixup_graphicsclient(struct machine_desc *desc, struct param_struct *params,
  104.      char **cmdline, struct meminfo *mi)
  105. {
  106. SET_BANK( 0, 0xc0000000, 16*1024*1024 );
  107. SET_BANK( 1, 0xc8000000, 16*1024*1024 );
  108. mi->nr_banks = 2;
  109. ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
  110. setup_ramdisk( 1, 0, 0, 8192 );
  111. setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
  112. }
  113. static struct map_desc graphicsclient_io_desc[] __initdata = {
  114.  /* virtual     physical    length      domain     r  w  c  b */
  115.   { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */
  116.   { 0xf0000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */
  117.   { 0xf1000000, 0x18000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CAN */
  118.   LAST_DESC
  119. };
  120. static struct gc_uart_ctrl_data_t gc_uart_ctrl_data[] = {
  121.   { GPIO_GC_UART0_CTS, 0, NULL,NULL },
  122.   { GPIO_GC_UART1_CTS, 0, NULL,NULL },
  123.   { GPIO_GC_UART2_CTS, 0, NULL,NULL }
  124. };
  125. static void
  126. graphicsclient_cts_intr(int irq, void *dev_id, struct pt_regs *regs)
  127. {
  128. struct gc_uart_ctrl_data_t * uart_data = (struct gc_uart_ctrl_data_t *)dev_id;
  129. int cts = !(GPLR & uart_data->cts_gpio);
  130. /* NOTE: I supose that we will no get any interrupt
  131.    if the GPIO is not changed, so maybe
  132.    the cts_prev_state can be removed ... */
  133. if (cts != uart_data->cts_prev_state) {
  134. uart_data->cts_prev_state = cts;
  135. uart_handle_cts_change(uart_data->info, cts);
  136. }
  137. }
  138. static int
  139. graphicsclient_register_cts_intr(int gpio, int irq,
  140.  struct gc_uart_ctrl_data_t *uart_data)
  141. {
  142. int ret = 0;
  143. set_GPIO_IRQ_edge(gpio, GPIO_BOTH_EDGES);
  144. ret = request_irq(irq, graphicsclient_cts_intr,
  145.   0, "GC RS232 CTS", uart_data);
  146. if (ret) {
  147. printk(KERN_ERR "uart_open: failed to register CTS irq (%d)n",
  148.        ret);
  149. free_irq(irq, uart_data);
  150. }
  151. return ret;
  152. }
  153. static int
  154. graphicsclient_uart_open(struct uart_port *port, struct uart_info *info)
  155. {
  156. int ret = 0;
  157. if (port->mapbase == _Ser1UTCR0) {
  158. Ser1SDCR0 |= SDCR0_UART;
  159. /* Set RTS Output */
  160. GPSR  = GPIO_GC_UART0_RTS;
  161. gc_uart_ctrl_data[0].cts_prev_state = 0;
  162. gc_uart_ctrl_data[0].info = info;
  163. gc_uart_ctrl_data[0].port = port;
  164. /* register uart0 CTS irq */
  165. ret = graphicsclient_register_cts_intr(GPIO_GC_UART0_CTS,
  166. IRQ_GC_UART0_CTS,
  167. &gc_uart_ctrl_data[0]);
  168. } else if (port->mapbase == _Ser2UTCR0) {
  169. Ser2UTCR4 = Ser2HSCR0 = 0;
  170. /* Set RTS Output */
  171. GPSR  = GPIO_GC_UART1_RTS;
  172. gc_uart_ctrl_data[1].cts_prev_state = 0;
  173. gc_uart_ctrl_data[1].info = info;
  174. gc_uart_ctrl_data[1].port = port;
  175. /* register uart1 CTS irq */
  176. ret = graphicsclient_register_cts_intr(GPIO_GC_UART1_CTS,
  177. IRQ_GC_UART1_CTS,
  178. &gc_uart_ctrl_data[1]);
  179. } else if (port->mapbase == _Ser3UTCR0) {
  180. /* Set RTS Output */
  181. GPSR = GPIO_GC_UART2_RTS;
  182. gc_uart_ctrl_data[2].cts_prev_state = 0;
  183. gc_uart_ctrl_data[2].info = info;
  184. gc_uart_ctrl_data[2].port = port;
  185. /* register uart2 CTS irq */
  186. ret = graphicsclient_register_cts_intr(GPIO_GC_UART2_CTS,
  187. IRQ_GC_UART2_CTS,
  188. &gc_uart_ctrl_data[2]);
  189. }
  190. return ret;
  191. }
  192. static int
  193. graphicsclient_uart_close(struct uart_port *port, struct uart_info *info)
  194. {
  195. if (port->mapbase == _Ser1UTCR0) {
  196. free_irq(IRQ_GC_UART0_CTS, &gc_uart_ctrl_data[0]);
  197. } else if (port->mapbase == _Ser2UTCR0) {
  198. free_irq(IRQ_GC_UART1_CTS, &gc_uart_ctrl_data[1]);
  199. } else if (port->mapbase == _Ser3UTCR0) {
  200. free_irq(IRQ_GC_UART2_CTS, &gc_uart_ctrl_data[2]);
  201. }
  202. return 0;
  203. }
  204. static u_int graphicsclient_get_mctrl(struct uart_port *port)
  205. {
  206. u_int result = TIOCM_CD | TIOCM_DSR;
  207. if (port->mapbase == _Ser1UTCR0) {
  208. if (!(GPLR & GPIO_GC_UART0_CTS))
  209. result |= TIOCM_CTS;
  210. } else if (port->mapbase == _Ser2UTCR0) {
  211. if (!(GPLR & GPIO_GC_UART1_CTS))
  212. result |= TIOCM_CTS;
  213. } else if (port->mapbase == _Ser3UTCR0) {
  214. if (!(GPLR & GPIO_GC_UART2_CTS))
  215. result |= TIOCM_CTS;
  216. } else {
  217. result = TIOCM_CTS;
  218. }
  219. return result;
  220. }
  221. static void graphicsclient_set_mctrl(struct uart_port *port, u_int mctrl)
  222. {
  223. if (port->mapbase == _Ser1UTCR0) {
  224. if (mctrl & TIOCM_RTS)
  225. GPCR = GPIO_GC_UART0_RTS;
  226. else
  227. GPSR = GPIO_GC_UART0_RTS;
  228. } else if (port->mapbase == _Ser2UTCR0) {
  229. if (mctrl & TIOCM_RTS)
  230. GPCR = GPIO_GC_UART1_RTS;
  231. else
  232. GPSR = GPIO_GC_UART1_RTS;
  233. } else if (port->mapbase == _Ser3UTCR0) {
  234. if (mctrl & TIOCM_RTS)
  235. GPCR = GPIO_GC_UART2_RTS;
  236. else
  237. GPSR = GPIO_GC_UART2_RTS;
  238. }
  239. }
  240. static void
  241. graphicsclient_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
  242. {
  243. if (!state) {
  244. /* make serial ports work ... */
  245. Ser2UTCR4 = 0;
  246. Ser2HSCR0 = 0; 
  247. Ser1SDCR0 |= SDCR0_UART;
  248. }
  249. }
  250. static struct sa1100_port_fns graphicsclient_port_fns __initdata = {
  251. open: graphicsclient_uart_open,
  252. close: graphicsclient_uart_close,
  253. get_mctrl: graphicsclient_get_mctrl,
  254. set_mctrl: graphicsclient_set_mctrl,
  255. pm: graphicsclient_uart_pm,
  256. };
  257. static void __init graphicsclient_map_io(void)
  258. {
  259. sa1100_map_io();
  260. iotable_init(graphicsclient_io_desc);
  261. sa1100_register_uart_fns(&graphicsclient_port_fns);
  262. sa1100_register_uart(0, 3);
  263. sa1100_register_uart(1, 1);
  264. sa1100_register_uart(2, 2);
  265. GPDR |= GPIO_GC_UART0_RTS | GPIO_GC_UART1_RTS | GPIO_GC_UART2_RTS;
  266. GPDR &= ~(GPIO_GC_UART0_CTS | GPIO_GC_UART1_RTS | GPIO_GC_UART2_RTS);
  267. }
  268. MACHINE_START(GRAPHICSCLIENT, "ADS GraphicsClient")
  269. BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
  270. FIXUP(fixup_graphicsclient)
  271. MAPIO(graphicsclient_map_io)
  272. INITIRQ(graphicsclient_init_irq)
  273. MACHINE_END