diff options
author | Mike Frysinger <michael.frysinger@analog.com> | 2007-12-24 19:40:05 +0800 |
---|---|---|
committer | Bryan Wu <cooloney@kernel.org> | 2007-12-24 19:40:05 +0800 |
commit | 0bcfd70ea11a5d6f2362be463513a60245a62baf (patch) | |
tree | fdf47e68cc5fc916da5d985f797b262c36997c4e /drivers/serial/bfin_5xx.c | |
parent | 4c195ad88b7df54b2e7340dec3446aee6ca84cd1 (diff) |
[Blackfin] serial driver: fix bug - cache the bits of the LSR on systems where the LSR is read-to-clear
Cache the bits of the LSR on systems where the LSR is read-to-clear
so that we can safely read the LSR in random places. this fixes
older parts where break/framing/parity/overflow was not being detected
at all in PIO mode, and this fixes newer parts where
break/framing/parity/overflow was being reported all the time
without being cleared.
Signed-off-by: Mike Frysinger <michael.frysinger@analog.com>
Signed-off-by: Bryan Wu <bryan.wu@analog.com>
Diffstat (limited to 'drivers/serial/bfin_5xx.c')
-rw-r--r-- | drivers/serial/bfin_5xx.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index ca9ceaa113a..af84984df77 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -216,8 +216,10 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) struct pt_regs *regs = get_irq_regs(); #endif - ch = UART_GET_CHAR(uart); status = UART_GET_LSR(uart); + UART_CLEAR_LSR(uart); + + ch = UART_GET_CHAR(uart); uart->port.icount.rx++; #ifdef CONFIG_KGDB_UART @@ -335,7 +337,7 @@ static irqreturn_t bfin_serial_rx_int(int irq, void *dev_id) struct bfin_serial_port *uart = dev_id; spin_lock(&uart->port.lock); - while ((UART_GET_IER(uart) & ERBFI) && (UART_GET_LSR(uart) & DR)) + while (UART_GET_LSR(uart) & DR) bfin_serial_rx_chars(uart); spin_unlock(&uart->port.lock); @@ -347,7 +349,7 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id) struct bfin_serial_port *uart = dev_id; spin_lock(&uart->port.lock); - if ((UART_GET_IER(uart) & ETBEI) && (UART_GET_LSR(uart) & THRE)) + if (UART_GET_LSR(uart) & THRE) bfin_serial_tx_chars(uart); spin_unlock(&uart->port.lock); @@ -428,6 +430,8 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) int i, flg, status; status = UART_GET_LSR(uart); + UART_CLEAR_LSR(uart); + uart->port.icount.rx += CIRC_CNT(uart->rx_dma_buf.head, uart->rx_dma_buf.tail, UART_XMIT_SIZE);; if (status & BI) { |