diff options
author | Samuel Iglesias Gonsalvez <siglesias@igalia.com> | 2012-09-12 14:55:43 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-09-12 09:56:02 -0700 |
commit | ab0a71f06d44334154091c6cdc823f908398623e (patch) | |
tree | a31d2a85f26c70c3d37f19ddafe1818b06d9ad91 /drivers/staging/ipack | |
parent | 9c1d784afc6fc37d328623d1adf503031b524788 (diff) |
Staging: ipack/devices/ipoctal: read more than one character from RX FIFO.
The RX FIFO has a size of 3 characters. Check if when we are picking the
oldest one, we have more to read.
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/ipack')
-rw-r--r-- | drivers/staging/ipack/devices/ipoctal.c | 60 |
1 files changed, 36 insertions, 24 deletions
diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 8b2be618fc9e..4f79fad7598d 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -134,33 +134,45 @@ static int ipoctal_get_icount(struct tty_struct *tty, static void ipoctal_irq_rx(struct ipoctal_channel *channel, struct tty_struct *tty, u8 sr) { - unsigned char value = ioread8(&channel->regs->r.rhr); + unsigned char value; unsigned char flag = TTY_NORMAL; - - /* Error: count statistics */ - if (sr & SR_ERROR) { - iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr); - - if (sr & SR_OVERRUN_ERROR) { - channel->stats.overrun_err++; - /* Overrun doesn't affect the current character*/ - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - } - if (sr & SR_PARITY_ERROR) { - channel->stats.parity_err++; - flag = TTY_PARITY; - } - if (sr & SR_FRAMING_ERROR) { - channel->stats.framing_err++; - flag = TTY_FRAME; + u8 isr; + + do { + value = ioread8(&channel->regs->r.rhr); + /* Error: count statistics */ + if (sr & SR_ERROR) { + iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr); + + if (sr & SR_OVERRUN_ERROR) { + channel->stats.overrun_err++; + /* Overrun doesn't affect the current character*/ + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + } + if (sr & SR_PARITY_ERROR) { + channel->stats.parity_err++; + flag = TTY_PARITY; + } + if (sr & SR_FRAMING_ERROR) { + channel->stats.framing_err++; + flag = TTY_FRAME; + } + if (sr & SR_RECEIVED_BREAK) { + channel->stats.rcv_break++; + flag = TTY_BREAK; + } } - if (sr & SR_RECEIVED_BREAK) { - channel->stats.rcv_break++; - flag = TTY_BREAK; - } - } + tty_insert_flip_char(tty, value, flag); - tty_insert_flip_char(tty, value, flag); + /* Check if there are more characters in RX FIFO + * If there are more, the isr register for this channel + * has enabled the RxRDY|FFULL bit. + */ + isr = ioread8(&channel->block_regs->r.isr); + sr = ioread8(&channel->regs->r.sr); + } while (isr & channel->isr_rx_rdy_mask); + + tty_flip_buffer_push(tty); } static void ipoctal_irq_tx(struct ipoctal_channel *channel) |