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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/drivers/char/serial_anakin.c
  3.  *
  4.  *  Based on driver for AMBA serial ports, by ARM Limited,
  5.  *  Deep Blue Solutions Ltd., Linus Torvalds and Theodore Ts'o.
  6.  *
  7.  *  Copyright (C) 2001 Aleph One Ltd. for Acunia N.V.
  8.  *
  9.  *  Copyright (C) 2001 Blue Mug, Inc. for Acunia N.V.
  10.  *
  11.  * This program is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License version 2 as
  13.  * published by the Free Software Foundation.
  14.  *
  15.  *  Changelog:
  16.  *   20-Apr-2001 TTC Created
  17.  *   05-May-2001 W/TTC Updated for serial_core.c
  18.  *   27-Jun-2001 jonm Minor changes; add mctrl support, switch to 
  19.  *    SA_INTERRUPT. Works reliably now. No longer requires
  20.  *    changes to the serial_core API.
  21.  *
  22.  *  $Id: serial_anakin.c,v 1.5.2.1 2001/11/27 17:35:39 rmk Exp $
  23.  */
  24. #include <linux/config.h>
  25. #include <linux/module.h>
  26. #include <linux/errno.h>
  27. #include <linux/signal.h>
  28. #include <linux/sched.h>
  29. #include <linux/interrupt.h>
  30. #include <linux/tty.h>
  31. #include <linux/tty_flip.h>
  32. #include <linux/major.h>
  33. #include <linux/string.h>
  34. #include <linux/fcntl.h>
  35. #include <linux/ptrace.h>
  36. #include <linux/ioport.h>
  37. #include <linux/mm.h>
  38. #include <linux/slab.h>
  39. #include <linux/init.h>
  40. #include <linux/circ_buf.h>
  41. #include <linux/serial.h>
  42. #include <linux/console.h>
  43. #include <linux/sysrq.h>
  44. #include <asm/system.h>
  45. #include <asm/io.h>
  46. #include <asm/irq.h>
  47. #include <asm/uaccess.h>
  48. #include <asm/bitops.h>
  49. #include <linux/serial_core.h>
  50. #include <asm/arch/serial_reg.h>
  51. #define UART_NR 5
  52. #define SERIAL_ANAKIN_NAME "ttyAN"
  53. #define SERIAL_ANAKIN_MAJOR 204
  54. #define SERIAL_ANAKIN_MINOR 32
  55. #define CALLOUT_ANAKIN_NAME "cuaan"
  56. #define CALLOUT_ANAKIN_MAJOR 205
  57. #define CALLOUT_ANAKIN_MINOR 32
  58. static struct tty_driver normal, callout;
  59. static struct tty_struct *anakin_table[UART_NR];
  60. static struct termios *anakin_termios[UART_NR], *anakin_termios_locked[UART_NR];
  61. static struct uart_state anakin_state[UART_NR];
  62. static u_int txenable[NR_IRQS]; /* Software interrupt register */
  63. static inline unsigned int
  64. anakin_in(struct uart_port *port, u_int offset)
  65. {
  66. return __raw_readl(port->base + offset);
  67. }
  68. static inline void
  69. anakin_out(struct uart_port *port, u_int offset, unsigned int value)
  70. {
  71. __raw_writel(value, port->base + offset);
  72. }
  73. static void
  74. anakin_stop_tx(struct uart_port *port, u_int from_tty)
  75. {
  76. txenable[port->irq] = 0;
  77. }
  78. static inline void
  79. anakin_transmit_buffer(struct uart_info *info)
  80. {
  81. struct uart_port *port = info->port;
  82. while (!(anakin_in(port, 0x10) & TXEMPTY));
  83. anakin_out(port, 0x14, info->xmit.buf[info->xmit.tail]);
  84. anakin_out(port, 0x18, anakin_in(port, 0x18) | SENDREQUEST);
  85. info->xmit.tail = (info->xmit.tail + 1) & (UART_XMIT_SIZE-1);
  86.         info->state->icount.tx++;
  87. if (info->xmit.head == info->xmit.tail)
  88. anakin_stop_tx(port, 0); 
  89. }
  90. static inline void
  91. anakin_transmit_x_char(struct uart_info *info)
  92. {
  93. struct uart_port *port = info->port;
  94. anakin_out(port, 0x14, info->x_char);
  95. anakin_out(port, 0x18, anakin_in(port, 0x18) | SENDREQUEST);
  96. info->state->icount.tx++;
  97. info->x_char = 0;
  98. }
  99. static void
  100. anakin_start_tx(struct uart_port *port, u_int nonempty, u_int from_tty)
  101. {
  102. unsigned int flags;
  103. save_flags_cli(flags);
  104. // is it this... or below: if (nonempty
  105. if (!txenable[port->irq]) {
  106. txenable[port->irq] = TXENABLE;
  107. if ((anakin_in(port, 0x10) & TXEMPTY) && nonempty) {
  108.     anakin_transmit_buffer((struct uart_info*)port->unused);
  109. }
  110. }
  111. restore_flags(flags);
  112. }
  113. static void
  114. anakin_stop_rx(struct uart_port *port)
  115. {
  116. unsigned long flags;
  117. save_flags_cli(flags);
  118. while (anakin_in(port, 0x10) & RXRELEASE) 
  119.     anakin_in(port, 0x14);
  120. anakin_out(port, 0x18, anakin_in(port, 0x18) | BLOCKRX);
  121. restore_flags(flags);
  122. }
  123. static void
  124. anakin_enable_ms(struct uart_port *port)
  125. {
  126. }
  127. static inline void
  128. anakin_rx_chars(struct uart_info *info)
  129. {
  130. unsigned int ch;
  131. struct tty_struct *tty = info->tty;
  132. if (!(anakin_in(info->port, 0x10) & RXRELEASE))
  133. return;
  134. ch = anakin_in(info->port, 0x14) & 0xff;
  135. if (tty->flip.count < TTY_FLIPBUF_SIZE) {
  136. *tty->flip.char_buf_ptr++ = ch;
  137. *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
  138. info->state->icount.rx++;
  139. tty->flip.count++;
  140. tty_flip_buffer_push(tty);
  141. }
  142. static inline void
  143. anakin_overrun_chars(struct uart_info *info)
  144. {
  145. unsigned int ch;
  146. ch = anakin_in(info->port, 0x14);
  147. info->state->icount.overrun++;
  148. }
  149. static inline void
  150. anakin_tx_chars(struct uart_info *info)
  151. {
  152. if (info->x_char) {
  153. anakin_transmit_x_char(info);
  154. return; 
  155. }
  156. if (info->xmit.head == info->xmit.tail
  157.     || info->tty->stopped
  158.     || info->tty->hw_stopped) {
  159. anakin_stop_tx(info->port, 0);
  160. return;
  161. }
  162. anakin_transmit_buffer(info);
  163. if (CIRC_CNT(info->xmit.head,
  164.      info->xmit.tail,
  165.      UART_XMIT_SIZE) < WAKEUP_CHARS)
  166. uart_event(info, EVT_WRITE_WAKEUP);
  167. }
  168. static void
  169. anakin_int(int irq, void *dev_id, struct pt_regs *regs)
  170. {
  171. unsigned int status;
  172. struct uart_info *info = dev_id;
  173. status = anakin_in(info->port, 0x1c);
  174. if (status & RX) 
  175. anakin_rx_chars(info);
  176. if (status & OVERRUN) 
  177. anakin_overrun_chars(info);
  178. if (txenable[info->port->irq] && (status & TX)) 
  179. anakin_tx_chars(info);
  180. }
  181. static u_int
  182. anakin_tx_empty(struct uart_port *port)
  183. {
  184. return anakin_in(port, 0x10) & TXEMPTY ? TIOCSER_TEMT : 0;
  185. }
  186. static u_int
  187. anakin_get_mctrl(struct uart_port *port)
  188. {
  189. unsigned int status = 0;
  190. status |= (anakin_in(port, 0x10) & CTS ? TIOCM_CTS : 0);
  191. status |= (anakin_in(port, 0x18) & DCD ? TIOCM_CAR : 0);
  192. status |= (anakin_in(port, 0x18) & DTR ? TIOCM_DTR : 0);
  193. status |= (anakin_in(port, 0x18) & RTS ? TIOCM_RTS : 0);
  194. return status;
  195. }
  196. static void
  197. anakin_set_mctrl(struct uart_port *port, u_int mctrl)
  198. {
  199. unsigned int status;
  200. status = anakin_in(port, 0x18);
  201. if (mctrl & TIOCM_RTS) 
  202. status |= RTS;
  203. else 
  204. status &= ~RTS;
  205. if (mctrl & TIOCM_CAR)
  206. status |= DCD;
  207. else 
  208. status &= ~DCD;
  209. anakin_out(port, 0x18, status);
  210. }
  211. static void
  212. anakin_break_ctl(struct uart_port *port, int break_state)
  213. {
  214. unsigned int status;
  215. status = anakin_in(port, 0x20);
  216. if (break_state == -1)
  217. status |= SETBREAK;
  218. else
  219. status &= ~SETBREAK;
  220. anakin_out(port, 0x20, status);
  221. }
  222. static int
  223. anakin_startup(struct uart_port *port, struct uart_info *info)
  224. {
  225. int retval;
  226. unsigned int read,write;
  227. /*
  228.  * Allocate the IRQ
  229.  */
  230. retval = request_irq(port->irq, anakin_int, SA_INTERRUPT, "serial_anakin", info);
  231. if (retval)
  232. return retval;
  233. port->ops->set_mctrl(port, info->mctrl);
  234. /*
  235.  * initialise the old status of the modem signals
  236.  */
  237. port->old_status = 0;
  238. /*
  239.  * Finally, disable IRQ and softIRQs for first byte)
  240.  */
  241. txenable[port->irq] = 0;
  242. read = anakin_in(port, 0x18);
  243. write = (read & ~(RTS | DTR | BLOCKRX)) | IRQENABLE;
  244. anakin_out(port, 0x18, write);
  245. /* Store the uart_info pointer so we can reference it in 
  246.  * anakin_start_tx() */
  247. port->unused = (u_int)info;
  248. return 0;
  249. }
  250. static void
  251. anakin_shutdown(struct uart_port *port, struct uart_info *info)
  252. {
  253. /*
  254.  * Free the interrupt
  255.  */
  256. free_irq(port->irq, info);
  257. /*
  258.  * disable all interrupts, disable the port
  259.  */
  260. anakin_out(port, 0x18, anakin_in(port, 0x18) & ~IRQENABLE);
  261. }
  262. static void
  263. anakin_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot)
  264. {
  265. unsigned int flags;
  266. save_flags_cli(flags);
  267. while (!(anakin_in(port, 0x10) & TXEMPTY));
  268. anakin_out(port, 0x10, (anakin_in(port, 0x10) & ~PRESCALER)
  269. | (quot << 3));
  270. //parity always set to none
  271. anakin_out(port, 0x18, anakin_in(port, 0x18) & ~PARITY);
  272. restore_flags(flags);
  273. }
  274. static const char *anakin_type(struct port *port)
  275. {
  276. return port->type == PORT_ANAKIN ? "ANAKIN" : NULL;
  277. }
  278. static struct uart_ops anakin_pops = {
  279. tx_empty: anakin_tx_empty,
  280. set_mctrl: anakin_set_mctrl,
  281. get_mctrl: anakin_get_mctrl,
  282. stop_tx: anakin_stop_tx,
  283. start_tx: anakin_start_tx,
  284. stop_rx: anakin_stop_rx,
  285. enable_ms: anakin_enable_ms,
  286. break_ctl: anakin_break_ctl,
  287. startup: anakin_startup,
  288. shutdown: anakin_shutdown,
  289. change_speed: anakin_change_speed,
  290. type: anakin_type,
  291. };
  292. static struct uart_port anakin_ports[UART_NR] = {
  293. {
  294. base: IO_BASE + UART0,
  295. irq: IRQ_UART0,
  296. uartclk: 3686400,
  297. fifosize: 0,
  298. ops: &anakin_pops,
  299. },
  300. {
  301. base: IO_BASE + UART1,
  302. irq: IRQ_UART1,
  303. uartclk: 3686400,
  304. fifosize: 0,
  305. ops: &anakin_pops,
  306. },
  307. {
  308. base: IO_BASE + UART2,
  309. irq: IRQ_UART2,
  310. uartclk: 3686400,
  311. fifosize: 0,
  312. ops: &anakin_pops,
  313. },
  314. {
  315. base: IO_BASE + UART3,
  316. irq: IRQ_UART3,
  317. uartclk: 3686400,
  318. fifosize: 0,
  319. ops: &anakin_pops,
  320. },
  321. {
  322. base: IO_BASE + UART4,
  323. irq: IRQ_UART4,
  324. uartclk: 3686400,
  325. fifosize: 0,
  326. ops: &anakin_pops,
  327. },
  328. };
  329. #ifdef CONFIG_SERIAL_ANAKIN_CONSOLE
  330. static void
  331. anakin_console_write(struct console *co, const char *s, u_int count)
  332. {
  333. struct uart_port *port = anakin_ports + co->index;
  334. unsigned int flags, status, i;
  335. /*
  336.  * First save the status then disable the interrupts
  337.  */
  338. save_flags_cli(flags);
  339. status = anakin_in(port, 0x18);
  340. anakin_out(port, 0x18, status & ~IRQENABLE);
  341. restore_flags(flags);
  342. /*
  343.  * Now, do each character
  344.  */
  345. for (i = 0; i < count; i++, s++) {
  346. while (!(anakin_in(port, 0x10) & TXEMPTY));
  347. /*
  348.  * Send the character out.
  349.  * If a LF, also do CR...
  350.  */
  351. anakin_out(port, 0x14, *s);
  352. anakin_out(port, 0x18, anakin_in(port, 0x18) | SENDREQUEST);
  353. if (*s == 10) {
  354. while (!(anakin_in(port, 0x10) & TXEMPTY));
  355. anakin_out(port, 0x14, 13);
  356. anakin_out(port, 0x18, anakin_in(port, 0x18)
  357. | SENDREQUEST);
  358. }
  359. }
  360. /*
  361.  * Finally, wait for transmitter to become empty
  362.  * and restore the interrupts
  363.  */
  364. while (!(anakin_in(port, 0x10) & TXEMPTY));
  365. if (status & IRQENABLE)
  366. save_flags_cli(flags);
  367.   anakin_out(port, 0x18, anakin_in(port, 0x18) | IRQENABLE);
  368. restore_flags(flags);
  369. }
  370. static kdev_t
  371. anakin_console_device(struct console *co)
  372. {
  373. return MKDEV(SERIAL_ANAKIN_MAJOR, SERIAL_ANAKIN_MINOR + co->index);
  374. }
  375. static int
  376. anakin_console_wait_key(struct console *co)
  377. {
  378. struct uart_port *port = anakin_ports + co->index;
  379. unsigned int flags, status, ch;
  380. save_flags_cli(flags);
  381. status = anakin_in(port, 0x18);
  382. anakin_out(port, 0x18, status & ~IRQENABLE);
  383. restore_flags(flags);
  384. while (!(anakin_in(port, 0x10) & RXRELEASE));
  385. ch = anakin_in(port, 0x14);
  386. if (status & IRQENABLE) {
  387. save_flags_cli(flags);
  388. anakin_out(port, 0x18, anakin_in(port, 0x18) | IRQENABLE);
  389. restore_flags(flags);
  390. }
  391. return ch;
  392. }
  393. /*
  394.  * Read the current UART setup.
  395.  */
  396. static void __init
  397. anakin_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
  398. {
  399. int paritycode;
  400. *baud = GETBAUD (anakin_in(port, 0x10) & PRESCALER);
  401. paritycode = GETPARITY(anakin_in(port, 0x18) & PARITY);
  402. switch (paritycode) {
  403.   case NONEPARITY: *parity = 'n'; break;
  404.   case ODDPARITY: *parity = 'o'; break;
  405.   case EVENPARITY: *parity = 'e'; break;
  406. }
  407. *bits = 8;
  408. }
  409. static int __init
  410. anakin_console_setup(struct console *co, char *options)
  411. {
  412. struct uart_port *port;
  413. int baud = CONFIG_ANAKIN_DEFAULT_BAUDRATE;
  414. int bits = 8;
  415. int parity = 'n';
  416. /*
  417.  * Check whether an invalid uart number has been specified, and
  418.  * if so, search for the first available port that does have
  419.  * console support.
  420.  */
  421. port = uart_get_console(anakin_ports, UART_NR, co);
  422. if (options)
  423. uart_parse_options(options, &baud, &parity, &bits);
  424. else
  425. anakin_console_get_options(port, &baud, &parity, &bits);
  426. return uart_set_options(port, co, baud, parity, bits);
  427. }
  428. static struct console anakin_console = {
  429. name: SERIAL_ANAKIN_NAME,
  430. write: anakin_console_write,
  431. device: anakin_console_device,
  432. wait_key: anakin_console_wait_key,
  433. setup: anakin_console_setup,
  434. flags: CON_PRINTBUFFER,
  435. index: -1,
  436. };
  437. void __init
  438. anakin_console_init(void)
  439. {
  440. register_console(&anakin_console);
  441. }
  442. #define ANAKIN_CONSOLE &anakin_console
  443. #else
  444. #define ANAKIN_CONSOLE NULL
  445. #endif
  446. static struct uart_register anakin_reg = {
  447. normal_major: SERIAL_ANAKIN_MAJOR,
  448. normal_name: SERIAL_ANAKIN_NAME,
  449. normal_driver: &normal,
  450. callout_major: CALLOUT_ANAKIN_MAJOR,
  451. callout_name: CALLOUT_ANAKIN_NAME,
  452. callout_driver: &callout,
  453. table: anakin_table,
  454. termios: anakin_termios,
  455. termios_locked: anakin_termios_locked,
  456. minor: SERIAL_ANAKIN_MINOR,
  457. nr: UART_NR,
  458. state: anakin_state,
  459. port: anakin_ports,
  460. cons: ANAKIN_CONSOLE,
  461. };
  462. static int __init
  463. anakin_init(void)
  464. {
  465. return uart_register_port(&anakin_reg);
  466. }
  467. __initcall(anakin_init);
  468. MODULE_DESCRIPTION("Anakin serial driver");
  469. MODULE_AUTHOR("Tak-Shing Chan <chan@aleph1.co.uk>");
  470. MODULE_SUPPORTED_DEVICE("ttyAN");
  471. MODULE_LICENSE("GPL");
  472. EXPORT_NO_SYMBOLS;