From 1322b7dcdc8864d2d01de5d328f9884da2c6ac5f Mon Sep 17 00:00:00 2001 From: hhb Date: Tue, 18 Dec 2012 10:35:05 +0800 Subject: [PATCH] UART: fix bug about BOTH_EMPTY V1.3 --- drivers/tty/serial/rk_serial.c | 35 +++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/drivers/tty/serial/rk_serial.c b/drivers/tty/serial/rk_serial.c index c45c927b4899..682e62c04309 100644 --- a/drivers/tty/serial/rk_serial.c +++ b/drivers/tty/serial/rk_serial.c @@ -53,16 +53,19 @@ * *v0.0 : this driver is 2.6.32 kernel driver; *v0.1 : this driver is 3.0.8 kernel driver; -*v1.0 : 2012-08-09 +*v1.0 : 2012-08-09 * 1.modify dma dirver; * 2.enable Programmable THRE Interrupt Mode, so we can just judge ((up->iir & 0x0f) == 0x02) when transmit * 3.reset uart and set it to loopback state to ensure setting baud rate sucessfully *v1.1 : 2012-08-23 * 1. dma driver:make "when tx dma is only enable" work functionally *v1.2 : 2012-08-28 -* 1. dma driver:serial rx use new dma interface rk29_dma_enqueue_ring +* 1. dma driver:serial rx use new dma interface rk29_dma_enqueue_ring +*v1.3 : 2012-12-14 +* 1. When enable Programmable THRE Interrupt Mode, in lsr register, only UART_LSR_TEMT means transmit empty, but + UART_LSR_THRE doesn't. So, the macro BOTH_EMPTY should be replaced with UART_LSR_TEMT. */ -#define VERSION_AND_TIME "rk_serial.c v1.2 2012-08-28" +#define VERSION_AND_TIME "rk_serial.c v1.3 2012-12-14" #define PORT_RK 90 #define UART_USR 0x1F /* UART Status Register */ @@ -72,10 +75,12 @@ #define UART_SRR 0x22 /* software reset register */ #define UART_RESET 0x01 -#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) + +//#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) #define UART_NR 4 //uart port number + /* configurate whether the port transmit-receive by DMA in menuconfig*/ #define OPEN_DMA 1 #define CLOSE_DMA 0 @@ -978,12 +983,12 @@ static void serial_rk_handle_port(struct uart_rk_port *up) DEBUG_INTR("error:lsr=0x%x\n", status); } } - + if(!(up->dma->use_dma & RX_DMA)) { if (status & (UART_LSR_DR | UART_LSR_BI)) { receive_chars(up, &status); } - } + } if ((up->iir & 0x0f) == 0x02) { transmit_chars(up); @@ -1071,7 +1076,7 @@ static unsigned int serial_rk_tx_empty(struct uart_port *port) up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; spin_unlock_irqrestore(&up->port.lock, flags); - return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0; + return (lsr & UART_LSR_TEMT) == UART_LSR_TEMT ? TIOCSER_TEMT : 0; } static unsigned int serial_rk_get_mctrl(struct uart_port *port) @@ -1191,14 +1196,14 @@ static void serial_rk_put_poll_char(struct uart_port *port, ier = serial_in(up, UART_IER); serial_out(up, UART_IER, 0); - wait_for_xmitr(up, BOTH_EMPTY); + wait_for_xmitr(up, UART_LSR_TEMT); /* * Send the character out. * If a LF, also do CR... */ serial_out(up, UART_TX, c); if (c == 10) { - wait_for_xmitr(up, BOTH_EMPTY); + wait_for_xmitr(up, UART_LSR_TEMT); serial_out(up, UART_TX, 13); } @@ -1206,7 +1211,7 @@ static void serial_rk_put_poll_char(struct uart_port *port, * Finally, wait for transmitter to become empty * and restore the IER */ - wait_for_xmitr(up, BOTH_EMPTY); + wait_for_xmitr(up, UART_LSR_TEMT); serial_out(up, UART_IER, ier); } @@ -1530,9 +1535,9 @@ serial_rk_set_termios(struct uart_port *port, struct ktermios *termios, if (up->dma->use_dma) { up->ier |= UART_IER_RLSI; up->ier |= UART_IER_PTIME; //Programmable THRE Interrupt Mode Enable - if (up->dma->use_dma & RX_DMA) - serial_rk_start_rx_dma(&up->port); - else + if (up->dma->use_dma & RX_DMA) + serial_rk_start_rx_dma(&up->port); + else up->ier |= UART_IER_RDI; } else #endif @@ -1702,7 +1707,7 @@ serial_rk_console_write(struct console *co, const char *s, unsigned int count) * Finally, wait for transmitter to become empty * and restore the IER */ - wait_for_xmitr(up, BOTH_EMPTY); + wait_for_xmitr(up, UART_LSR_TEMT); serial_out(up, UART_IER, ier); #if 0 @@ -1841,7 +1846,7 @@ static int __devinit serial_rk_probe(struct platform_device *pdev) up->port.uartclk = clk_get_rate(up->clk); #if USE_DMA - /* set dma config */ + /* set dma config */ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); if(up->dma->use_dma & RX_DMA) { //timer -- 2.34.1