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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/drivers/char/serial_uart00.c
  3.  *
  4.  *  Driver for UART00 serial ports
  5.  *
  6.  *  Based on drivers/char/serial_amba.c, by ARM Limited & 
  7.  *                                          Deep Blue Solutions Ltd.
  8.  *  Copyright 2001 Altera Corporation
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23.  *
  24.  *  $Id: serial_uart00.c,v 1.3.2.4 2002/03/27 23:32:40 rmk Exp $
  25.  *
  26.  */
  27. #include <linux/config.h>
  28. #include <linux/module.h>
  29. #include <linux/errno.h>
  30. #include <linux/signal.h>
  31. #include <linux/sched.h>
  32. #include <linux/interrupt.h>
  33. #include <linux/tty.h>
  34. #include <linux/tty_flip.h>
  35. #include <linux/major.h>
  36. #include <linux/string.h>
  37. #include <linux/fcntl.h>
  38. #include <linux/ptrace.h>
  39. #include <linux/ioport.h>
  40. #include <linux/mm.h>
  41. #include <linux/slab.h>
  42. #include <linux/init.h>
  43. #include <linux/circ_buf.h>
  44. #include <linux/serial.h>
  45. #include <linux/console.h>
  46. #include <linux/sysrq.h>
  47. #include <asm/system.h>
  48. #include <asm/io.h>
  49. #include <asm/irq.h>
  50. #include <asm/uaccess.h>
  51. #include <asm/bitops.h>
  52. #include <asm/sizes.h>
  53. #if defined(CONFIG_SERIAL_UART00_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
  54. #define SUPPORT_SYSRQ
  55. #endif
  56. #include <linux/serial_core.h>
  57. #include <asm/arch/excalibur.h>
  58. #define UART00_TYPE (volatile unsigned int*)
  59. #include <asm/arch/uart00.h>
  60. #include <asm/arch/int_ctrl00.h>
  61. #undef DEBUG
  62. #define UART_NR 2
  63. #define SERIAL_UART00_NAME "ttyUA"
  64. #define SERIAL_UART00_MAJOR 204
  65. #define SERIAL_UART00_MINOR 16      /* Temporary - will change in future */
  66. #define SERIAL_UART00_NR UART_NR
  67. #define UART_PORT_SIZE 0x50
  68. #define CALLOUT_UART00_NAME "cuaua"
  69. #define CALLOUT_UART00_MAJOR 205
  70. #define CALLOUT_UART00_MINOR 16      /* Temporary - will change in future */
  71. #define CALLOUT_UART00_NR UART_NR
  72. static struct tty_driver normal, callout;
  73. static struct tty_struct *uart00_table[UART_NR];
  74. static struct termios *uart00_termios[UART_NR], *uart00_termios_locked[UART_NR];
  75. //static struct uart_state uart00_state[UART_NR];
  76. static struct console uart00_console;
  77. #define UART00_ISR_PASS_LIMIT 256
  78. /*
  79.  * Access macros for the UART00 UARTs
  80.  */
  81. #define UART_GET_INT_STATUS(p) inl(UART_ISR((p)->membase))
  82. #define UART_PUT_IES(p, c)      outl(c,UART_IES((p)->membase))
  83. #define UART_GET_IES(p)         inl(UART_IES((p)->membase))
  84. #define UART_PUT_IEC(p, c)      outl(c,UART_IEC((p)->membase))
  85. #define UART_GET_IEC(p)         inl(UART_IEC((p)->membase))
  86. #define UART_PUT_CHAR(p, c)     outl(c,UART_TD((p)->membase))
  87. #define UART_GET_CHAR(p)        inl(UART_RD((p)->membase))
  88. #define UART_GET_RSR(p)         inl(UART_RSR((p)->membase))
  89. #define UART_GET_RDS(p)         inl(UART_RDS((p)->membase))
  90. #define UART_GET_MSR(p)         inl(UART_MSR((p)->membase))
  91. #define UART_GET_MCR(p)         inl(UART_MCR((p)->membase))
  92. #define UART_PUT_MCR(p, c)      outl(c,UART_MCR((p)->membase))
  93. #define UART_GET_MC(p)          inl(UART_MC((p)->membase))
  94. #define UART_PUT_MC(p, c)       outl(c,UART_MC((p)->membase))
  95. #define UART_GET_TSR(p)         inl(UART_TSR((p)->membase))
  96. #define UART_GET_DIV_HI(p) inl(UART_DIV_HI((p)->membase))
  97. #define UART_PUT_DIV_HI(p,c) outl(c,UART_DIV_HI((p)->membase))
  98. #define UART_GET_DIV_LO(p) inl(UART_DIV_LO((p)->membase))
  99. #define UART_PUT_DIV_LO(p,c) outl(c,UART_DIV_LO((p)->membase))
  100. #define UART_RX_DATA(s) ((s) & UART_RSR_RX_LEVEL_MSK)
  101. #define UART_TX_READY(s) (((s) & UART_TSR_TX_LEVEL_MSK) < 15)
  102. //#define UART_TX_EMPTY(p) ((UART_GET_FR(p) & UART00_UARTFR_TMSK) == 0)
  103. static void uart00_stop_tx(struct uart_port *port, u_int from_tty)
  104. {
  105. UART_PUT_IEC(port, UART_IEC_TIE_MSK);
  106. }
  107. static void uart00_stop_rx(struct uart_port *port)
  108. {
  109. UART_PUT_IEC(port, UART_IEC_RE_MSK);
  110. }
  111. static void uart00_enable_ms(struct uart_port *port)
  112. {
  113. UART_PUT_IES(port, UART_IES_ME_MSK);
  114. }
  115. static void
  116. uart00_rx_chars(struct uart_info *info, struct pt_regs *regs)
  117. {
  118. struct tty_struct *tty = info->tty;
  119. unsigned int status, ch, rds, flg, ignored = 0;
  120. struct uart_port *port = info->port;
  121. status = UART_GET_RSR(port);
  122. while (UART_RX_DATA(status)) {
  123. /* 
  124.  * We need to read rds before reading the 
  125.  * character from the fifo
  126.  */
  127. rds = UART_GET_RDS(port);
  128. ch = UART_GET_CHAR(port);
  129. port->icount.rx++;
  130. if (tty->flip.count >= TTY_FLIPBUF_SIZE)
  131. goto ignore_char;
  132. flg = TTY_NORMAL;
  133. /*
  134.  * Note that the error handling code is
  135.  * out of the main execution path
  136.  */
  137. if (rds & (UART_RDS_BI_MSK |UART_RDS_FE_MSK|
  138.    UART_RDS_PE_MSK |UART_RDS_PE_MSK))
  139. goto handle_error;
  140. if (uart_handle_sysrq_char(info, ch, regs))
  141. goto ignore_char;
  142. error_return:
  143. *tty->flip.flag_buf_ptr++ = flg;
  144. *tty->flip.char_buf_ptr++ = ch;
  145. tty->flip.count++;
  146. ignore_char:
  147. status = UART_GET_RSR(port);
  148. }
  149. out:
  150. tty_flip_buffer_push(tty);
  151. return;
  152. handle_error:
  153. if (rds & UART_RDS_BI_MSK) {
  154. status &= ~(UART_RDS_FE_MSK | UART_RDS_PE_MSK);
  155. port->icount.brk++;
  156. #ifdef SUPPORT_SYSRQ
  157. if (uart_handle_break(info, &uart00_console))
  158. goto ignore_char;
  159. #endif
  160. } else if (rds & UART_RDS_PE_MSK)
  161. port->icount.parity++;
  162. else if (rds & UART_RDS_PE_MSK)
  163. port->icount.frame++;
  164. if (rds & UART_RDS_OE_MSK)
  165. port->icount.overrun++;
  166. if (rds & port->ignore_status_mask) {
  167. if (++ignored > 100)
  168. goto out;
  169. goto ignore_char;
  170. }
  171. rds &= port->read_status_mask;
  172. if (rds & UART_RDS_BI_MSK)
  173. flg = TTY_BREAK;
  174. else if (rds & UART_RDS_PE_MSK)
  175. flg = TTY_PARITY;
  176. else if (rds & UART_RDS_FE_MSK)
  177. flg = TTY_FRAME;
  178. if (status & UART_RDS_OE_MSK) {
  179. /*
  180.  * CHECK: does overrun affect the current character?
  181.  * ASSUMPTION: it does not.
  182.  */
  183. *tty->flip.flag_buf_ptr++ = flg;
  184. *tty->flip.char_buf_ptr++ = ch;
  185. tty->flip.count++;
  186. if (tty->flip.count >= TTY_FLIPBUF_SIZE)
  187. goto ignore_char;
  188. ch = 0;
  189. flg = TTY_OVERRUN;
  190. }
  191. #ifdef SUPPORT_SYSRQ
  192. info->sysrq = 0;
  193. #endif
  194. goto error_return;
  195. }
  196. static void uart00_tx_chars(struct uart_info *info)
  197. {
  198. int count;
  199. struct uart_port *port=info->port;
  200. if (port->x_char) {
  201. while((UART_GET_TSR(port)& UART_TSR_TX_LEVEL_MSK)==15);
  202. UART_PUT_CHAR(port, port->x_char);
  203. port->icount.tx++;
  204. port->x_char = 0;
  205. return;
  206. }
  207. if (info->xmit.head == info->xmit.tail
  208.     || info->tty->stopped
  209.     || info->tty->hw_stopped) {
  210. uart00_stop_tx(info->port, 0);
  211. return;
  212. }
  213. count = port->fifosize >> 1;
  214. do {
  215. while((UART_GET_TSR(port)& UART_TSR_TX_LEVEL_MSK)==15);
  216. UART_PUT_CHAR(port, info->xmit.buf[info->xmit.tail]);
  217. info->xmit.tail = (info->xmit.tail + 1) & (UART_XMIT_SIZE - 1);
  218. port->icount.tx++;
  219. if (info->xmit.head == info->xmit.tail)
  220. break;
  221. } while (--count > 0);
  222. if (CIRC_CNT(info->xmit.head,
  223.      info->xmit.tail,
  224.      UART_XMIT_SIZE) < WAKEUP_CHARS)
  225. uart_event(info, EVT_WRITE_WAKEUP);
  226. if (info->xmit.head == info->xmit.tail)
  227. uart00_stop_tx(info->port, 0);
  228. }
  229. static void uart00_start_tx(struct uart_port *port, u_int nonempty, u_int from_tty)
  230. {
  231. struct uart_info *info=(struct uart_info*)(port->iobase);
  232. UART_PUT_IES(port,UART_IES_TIE_MSK );
  233. uart00_tx_chars(info);
  234. }
  235. static void uart00_modem_status(struct uart_info *info)
  236. {
  237. unsigned int status;
  238. struct uart_icount *icount = &info->port->icount;
  239. status = UART_GET_MSR(info->port);
  240. if (!status & (UART_MSR_DCTS_MSK | UART_MSR_DDSR_MSK | 
  241.        UART_MSR_TERI_MSK | UART_MSR_DDCD_MSK))
  242. return;
  243. if (status & UART_MSR_DDCD_MSK) {
  244. icount->dcd++;
  245. #ifdef CONFIG_HARD_PPS
  246. if ((info->flags & ASYNC_HARDPPS_CD) &&
  247.     (status & UART_MSR_DCD_MSK))
  248. hardpps();
  249. #endif
  250. if (info->flags & ASYNC_CHECK_CD) {
  251. if (status & UART_MSR_DCD_MSK)
  252. wake_up_interruptible(&info->open_wait);
  253. else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
  254.    (info->flags & ASYNC_CALLOUT_NOHUP))) {
  255. if (info->tty)
  256. tty_hangup(info->tty);
  257. }
  258. }
  259. }
  260. if (status & UART_MSR_DDSR_MSK)
  261. icount->dsr++;
  262. if (status & UART_MSR_DCTS_MSK) {
  263. icount->cts++;
  264. if (info->flags & ASYNC_CTS_FLOW) {
  265. status &= UART_MSR_CTS_MSK;
  266. if (info->tty->hw_stopped) {
  267. if (status) {
  268. info->tty->hw_stopped = 0;
  269. info->ops->start_tx(info->port, 1, 0);
  270. uart_event(info, EVT_WRITE_WAKEUP);
  271. }
  272. } else {
  273. if (!status) {
  274. info->tty->hw_stopped = 1;
  275. info->ops->stop_tx(info->port, 0);
  276. }
  277. }
  278. }
  279. }
  280. wake_up_interruptible(&info->delta_msr_wait);
  281. }
  282. static void uart00_int(int irq, void *dev_id, struct pt_regs *regs)
  283. {
  284. struct uart_info *info = dev_id;
  285. unsigned int status, pass_counter = 0;
  286. status = UART_GET_INT_STATUS(info->port);
  287. do {
  288. if (status & UART_ISR_RI_MSK)
  289. uart00_rx_chars(info, regs);
  290. if (status & (UART_ISR_TI_MSK | UART_ISR_TII_MSK))
  291. uart00_tx_chars(info);
  292. if (status & UART_ISR_MI_MSK)
  293. uart00_modem_status(info);
  294. if (pass_counter++ > UART00_ISR_PASS_LIMIT)
  295. break;
  296. status = UART_GET_INT_STATUS(info->port);
  297. } while (status);
  298. }
  299. static u_int uart00_tx_empty(struct uart_port *port)
  300. {
  301. return UART_GET_TSR(port) & UART_TSR_TX_LEVEL_MSK? 0 : TIOCSER_TEMT;
  302. }
  303. static u_int uart00_get_mctrl(struct uart_port *port)
  304. {
  305. unsigned int result = 0;
  306. unsigned int status;
  307. status = UART_GET_MSR(port);
  308. if (status & UART_MSR_DCD_MSK)
  309. result |= TIOCM_CAR;
  310. if (status & UART_MSR_DSR_MSK)
  311. result |= TIOCM_DSR;
  312. if (status & UART_MSR_CTS_MSK)
  313. result |= TIOCM_CTS;
  314. if (status & UART_MSR_RI_MSK)
  315. result |= TIOCM_RI;
  316. return result;
  317. }
  318. static void uart00_set_mctrl_null(struct uart_port *port, u_int mctrl)
  319. {
  320. }
  321. static void uart00_break_ctl(struct uart_port *port, int break_state)
  322. {
  323. unsigned int mcr;
  324. mcr = UART_GET_MCR(port);
  325. if (break_state == -1)
  326. mcr |= UART_MCR_BR_MSK;
  327. else
  328. mcr &= ~UART_MCR_BR_MSK;
  329. UART_PUT_MCR(port, mcr);
  330. }
  331. static inline u_int uart_calculate_quot(struct uart_info *info, u_int baud)
  332. {
  333. u_int quot;
  334. /* Special case: B0 rate */
  335. if (!baud)
  336. baud = 9600;
  337. quot = (info->port->uartclk / (16 * baud)-1)  ;
  338. return quot;
  339. }
  340. static void uart00_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot)
  341. {
  342. u_int uart_mc=0, old_ies;
  343. unsigned long flags;
  344. #ifdef DEBUG
  345. printk("uart00_set_cflag(0x%x) calledn", cflag);
  346. #endif
  347. /* byte size and parity */
  348. switch (cflag & CSIZE) {
  349. case CS5: uart_mc = UART_MC_CLS_CHARLEN_5; break;
  350. case CS6: uart_mc = UART_MC_CLS_CHARLEN_6; break;
  351. case CS7: uart_mc = UART_MC_CLS_CHARLEN_7; break;
  352. default:  uart_mc = UART_MC_CLS_CHARLEN_8; break; // CS8
  353. }
  354. if (cflag & CSTOPB)
  355. uart_mc|= UART_MC_ST_TWO;
  356. if (cflag & PARENB) {
  357. uart_mc |= UART_MC_PE_MSK;
  358. if (!(cflag & PARODD))
  359. uart_mc |= UART_MC_EP_MSK;
  360. }
  361. port->read_status_mask = UART_RDS_OE_MSK;
  362. if (iflag & INPCK)
  363. port->read_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK;
  364. if (iflag & (BRKINT | PARMRK))
  365. port->read_status_mask |= UART_RDS_BI_MSK;
  366. /*
  367.  * Characters to ignore
  368.  */
  369. port->ignore_status_mask = 0;
  370. if (iflag & IGNPAR)
  371. port->ignore_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK;
  372. if (iflag & IGNBRK) {
  373. port->ignore_status_mask |= UART_RDS_BI_MSK;
  374. /*
  375.  * If we're ignoring parity and break indicators,
  376.  * ignore overruns to (for real raw support).
  377.  */
  378. if (iflag & IGNPAR)
  379. port->ignore_status_mask |= UART_RDS_OE_MSK;
  380. }
  381. /* first, disable everything */
  382. save_flags(flags); cli();
  383. old_ies = UART_GET_IES(port); 
  384. if ((port->flags & ASYNC_HARDPPS_CD) ||
  385.     (cflag & CRTSCTS) || !(cflag & CLOCAL))
  386. old_ies |= UART_IES_ME_MSK;
  387. /* Set baud rate */
  388. UART_PUT_DIV_LO(port, (quot & 0xff));
  389. UART_PUT_DIV_HI(port, ((quot & 0xf00) >> 8));
  390.    
  391. UART_PUT_MC(port, uart_mc);
  392. UART_PUT_IES(port, old_ies);
  393. restore_flags(flags);
  394. }
  395. static int uart00_startup(struct uart_port *port, struct uart_info *info)
  396. {
  397. int retval;
  398. /* 
  399.  * Use iobase to store a pointer to info. We need this to start a 
  400.  * transmission as the tranmittr interrupt is only generated on
  401.  * the transition to the idle state 
  402.  */
  403. port->iobase=(u_int)info;
  404. /*
  405.  * Allocate the IRQ
  406.  */
  407. retval = request_irq(port->irq, uart00_int, 0, "uart00", info);
  408. if (retval)
  409. return retval;
  410. /*
  411.  * Finally, enable interrupts. Use the TII interrupt to minimise 
  412.  * the number of interrupts generated. If higher performance is 
  413.  * needed, consider using the TI interrupt with a suitable FIFO
  414.  * threshold
  415.  */
  416. UART_PUT_IES(port, UART_IES_RE_MSK | UART_IES_TIE_MSK);
  417. return 0;
  418. }
  419. static void uart00_shutdown(struct uart_port *port, struct uart_info *info)
  420. {
  421. /*
  422.  * disable all interrupts, disable the port
  423.  */
  424. UART_PUT_IEC(port, 0xff);
  425. /* disable break condition and fifos */
  426. UART_PUT_MCR(port, UART_GET_MCR(port) &~UART_MCR_BR_MSK);
  427. /*
  428.  * Free the interrupt
  429.  */
  430. free_irq(port->irq, info);
  431. }
  432. static const char *uart00_type(struct uart_port *port)
  433. {
  434. return port->type == PORT_UART00 ? "UART00" : NULL;
  435. }
  436. /*
  437.  * Release the memory region(s) being used by 'port'
  438.  */
  439. static void uart00_release_port(struct uart_port *port)
  440. {
  441. release_mem_region(port->mapbase, UART_PORT_SIZE);
  442. #ifdef CONFIG_ARCH_CAMELOT
  443. if(port->membase!=(void*)IO_ADDRESS(EXC_UART00_BASE)){
  444. iounmap(port->membase);
  445. }
  446. #endif
  447. }
  448. /*
  449.  * Request the memory region(s) being used by 'port'
  450.  */
  451. static int uart00_request_port(struct uart_port *port)
  452. {
  453. int result;
  454. result = request_mem_region(port->mapbase, UART_PORT_SIZE,
  455.     "serial_uart00") != NULL ? 0 : -EBUSY;
  456. if (result)
  457. return result;
  458. port->membase = ioremap(port->mapbase, SZ_4K);
  459. if (!port->membase) {
  460. printk(KERN_ERR "serial00: cannot map io memoryn");
  461. release_mem_region(port->mapbase, UART_PORT_SIZE);
  462. }
  463. return port->membase ? 0 : -ENOMEM;
  464. }
  465. /*
  466.  * Configure/autoconfigure the port.
  467.  */
  468. static void uart00_config_port(struct uart_port *port, int flags)
  469. {
  470. if (flags & UART_CONFIG_TYPE) {
  471. if (uart00_request_port(port) == 0)
  472. port->type = PORT_UART00;
  473. }
  474. }
  475. /*
  476.  * verify the new serial_struct (for TIOCSSERIAL).
  477.  */
  478. static int uart00_verify_port(struct uart_port *port, struct serial_struct *ser)
  479. {
  480. int ret = 0;
  481. if (ser->type != PORT_UNKNOWN && ser->type != PORT_UART00)
  482. ret = -EINVAL;
  483. if (ser->irq < 0 || ser->irq >= NR_IRQS)
  484. ret = -EINVAL;
  485. if (ser->baud_base < 9600)
  486. ret = -EINVAL;
  487. return ret;
  488. }
  489. static struct uart_ops uart00_pops = {
  490. tx_empty: uart00_tx_empty,
  491. set_mctrl: uart00_set_mctrl_null,
  492. get_mctrl: uart00_get_mctrl,
  493. stop_tx: uart00_stop_tx,
  494. start_tx: uart00_start_tx,
  495. stop_rx: uart00_stop_rx,
  496. enable_ms: uart00_enable_ms,
  497. break_ctl: uart00_break_ctl,
  498. startup: uart00_startup,
  499. shutdown: uart00_shutdown,
  500. change_speed: uart00_change_speed,
  501. type: uart00_type,
  502. release_port: uart00_release_port,
  503. request_port: uart00_request_port,
  504. config_port: uart00_config_port,
  505. verify_port: uart00_verify_port,
  506. };
  507. static struct uart_port uart00_ports[UART_NR] = {
  508. #ifdef CONFIG_ARCH_CAMELOT
  509. {
  510. membase: (void*)IO_ADDRESS(EXC_UART00_BASE),
  511. mapbase:        EXC_UART00_BASE,
  512. iotype: SERIAL_IO_MEM,
  513. irq: IRQ_UART,
  514. uartclk: EXC_AHB2_CLK_FREQUENCY,
  515. fifosize: 16,
  516. ops: &uart00_pops,
  517. flags:          ASYNC_BOOT_AUTOCONF,
  518. }
  519. #endif
  520. };
  521. #ifdef CONFIG_SERIAL_UART00_CONSOLE
  522. #ifdef used_and_not_const_char_pointer
  523. static int uart00_console_read(struct uart_port *port, char *s, u_int count)
  524. {
  525. unsigned int status;
  526. int c;
  527. #ifdef DEBUG
  528. printk("uart00_console_read() calledn");
  529. #endif
  530. c = 0;
  531. while (c < count) {
  532. status = UART_GET_RSR(port);
  533.   if (UART_RX_DATA(status)) {
  534. *s++ = UART_GET_CHAR(port);
  535. c++;
  536. } else {
  537. // nothing more to get, return
  538. return c;
  539. }
  540. }
  541. // return the count
  542. return c;
  543. }
  544. #endif
  545. static void uart00_console_write(struct console *co, const char *s, unsigned count)
  546. {
  547. #ifdef CONFIG_ARCH_CAMELOT
  548. struct uart_port *port = &uart00_ports[0];
  549. unsigned int status, old_ies;
  550. int i;
  551. /*
  552.  * First save the CR then disable the interrupts
  553.  */
  554. old_ies = UART_GET_IES(port);
  555. UART_PUT_IEC(port,0xff);
  556. /*
  557.  * Now, do each character
  558.  */
  559. for (i = 0; i < count; i++) {
  560. do {
  561. status = UART_GET_TSR(port);
  562. } while (!UART_TX_READY(status));
  563. UART_PUT_CHAR(port, s[i]);
  564. if (s[i] == 'n') {
  565. do {
  566. status = UART_GET_TSR(port);
  567. } while (!UART_TX_READY(status));
  568. UART_PUT_CHAR(port, 'r');
  569. }
  570. }
  571. /*
  572.  * Finally, wait for transmitter to become empty
  573.  * and restore the IES
  574.  */
  575. do {
  576. status = UART_GET_TSR(port);
  577. } while (status & UART_TSR_TX_LEVEL_MSK);
  578. UART_PUT_IES(port, old_ies);
  579. #endif
  580. }
  581. static kdev_t uart00_console_device(struct console *co)
  582. {
  583. return MKDEV(SERIAL_UART00_MAJOR, SERIAL_UART00_MINOR + co->index);
  584. }
  585. static int uart00_console_wait_key(struct console *co)
  586. {
  587. #ifdef CONFIG_ARCH_CAMELOT
  588. struct uart_port *port = &uart00_ports[0];
  589. unsigned int status;
  590. do {
  591. status = UART_GET_RSR(port);
  592. } while (!UART_RX_DATA(status));
  593. return UART_GET_CHAR(port);
  594. #else
  595. return 0;
  596. #endif
  597. }
  598. static void /*__init*/ uart00_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
  599. {
  600. u_int uart_mc, quot;
  601. uart_mc= UART_GET_MC(port);
  602. *parity = 'n';
  603. if (uart_mc & UART_MC_PE_MSK) {
  604. if (uart_mc & UART_MC_EP_MSK)
  605. *parity = 'e';
  606. else
  607. *parity = 'o';
  608. }
  609. switch (uart_mc & UART_MC_CLS_MSK){
  610. case UART_MC_CLS_CHARLEN_5:
  611. *bits = 5;
  612. break;
  613. case UART_MC_CLS_CHARLEN_6:
  614. *bits = 6;
  615. break;
  616. case UART_MC_CLS_CHARLEN_7:
  617. *bits = 7;
  618. break;
  619. case UART_MC_CLS_CHARLEN_8:
  620. *bits = 8;
  621. break;
  622. }
  623. quot = UART_GET_DIV_LO(port) | (UART_GET_DIV_HI(port) << 8);
  624. *baud = port->uartclk / (16 *quot );
  625. }
  626. static int __init uart00_console_setup(struct console *co, char *options)
  627. {
  628. struct uart_port *port;
  629. int baud = 38400;
  630. int bits = 8;
  631. int parity = 'n';
  632. int flow= 'n';
  633. #ifdef CONFIG_ARCH_CAMELOT
  634. /*
  635.  * Check whether an invalid uart number has been specified, and
  636.  * if so, search for the first available port that does have
  637.  * console support.
  638.  */
  639. port = &uart00_ports[0];
  640. co->index = 0;
  641. #else
  642. return -ENODEV;
  643. #endif
  644. if (options)
  645. uart_parse_options(options, &baud, &parity, &bits, &flow);
  646. else
  647. uart00_console_get_options(port, &baud, &parity, &bits);
  648. return uart_set_options(port, co, baud, parity, bits, flow);
  649. }
  650. static struct console uart00_console = {
  651. name:           SERIAL_UART00_NAME,
  652. write: uart00_console_write,
  653. #ifdef used_and_not_const_char_pointer
  654. read: uart00_console_read,
  655. #endif
  656. device: uart00_console_device,
  657. wait_key: uart00_console_wait_key,
  658. setup: uart00_console_setup,
  659. flags: CON_PRINTBUFFER,
  660. index: 0,
  661. };
  662. void __init uart00_console_init(void)
  663. {
  664. register_console(&uart00_console);
  665. }
  666. #define UART00_CONSOLE &uart00_console
  667. #else
  668. #define UART00_CONSOLE NULL
  669. #endif
  670. static struct uart_driver uart00_reg = {
  671. owner:                  NULL,
  672. normal_major: SERIAL_UART00_MAJOR,
  673. normal_name: SERIAL_UART00_NAME,
  674. normal_driver: &normal,
  675. callout_major: CALLOUT_UART00_MAJOR,
  676. callout_name: CALLOUT_UART00_NAME,
  677. callout_driver: &callout,
  678. table: uart00_table,
  679. termios: uart00_termios,
  680. termios_locked: uart00_termios_locked,
  681. minor: SERIAL_UART00_MINOR,
  682. nr: UART_NR,
  683. port: &uart00_ports,
  684. state: NULL,
  685. cons: UART00_CONSOLE,
  686. };
  687. static int __init uart00_init(void)
  688. {
  689. printk(KERN_WARNING "serial_uart00:Using temporary major/minor pairs - these WILL change in the futuren");
  690. return uart_register_driver(&uart00_reg);
  691. }
  692. __initcall(uart00_init);