aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Iglesias Gonsalvez <siglesias@igalia.com>2012-09-12 08:55:43 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-09-12 12:56:02 -0400
commitab0a71f06d44334154091c6cdc823f908398623e (patch)
treea31d2a85f26c70c3d37f19ddafe1818b06d9ad91
parent9c1d784afc6fc37d328623d1adf503031b524788 (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>
-rw-r--r--drivers/staging/ipack/devices/ipoctal.c60
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,
134static void ipoctal_irq_rx(struct ipoctal_channel *channel, 134static void ipoctal_irq_rx(struct ipoctal_channel *channel,
135 struct tty_struct *tty, u8 sr) 135 struct tty_struct *tty, u8 sr)
136{ 136{
137 unsigned char value = ioread8(&channel->regs->r.rhr); 137 unsigned char value;
138 unsigned char flag = TTY_NORMAL; 138 unsigned char flag = TTY_NORMAL;
139 139 u8 isr;
140 /* Error: count statistics */ 140
141 if (sr & SR_ERROR) { 141 do {
142 iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr); 142 value = ioread8(&channel->regs->r.rhr);
143 143 /* Error: count statistics */
144 if (sr & SR_OVERRUN_ERROR) { 144 if (sr & SR_ERROR) {
145 channel->stats.overrun_err++; 145 iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr);
146 /* Overrun doesn't affect the current character*/ 146
147 tty_insert_flip_char(tty, 0, TTY_OVERRUN); 147 if (sr & SR_OVERRUN_ERROR) {
148 } 148 channel->stats.overrun_err++;
149 if (sr & SR_PARITY_ERROR) { 149 /* Overrun doesn't affect the current character*/
150 channel->stats.parity_err++; 150 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
151 flag = TTY_PARITY; 151 }
152 } 152 if (sr & SR_PARITY_ERROR) {
153 if (sr & SR_FRAMING_ERROR) { 153 channel->stats.parity_err++;
154 channel->stats.framing_err++; 154 flag = TTY_PARITY;
155 flag = TTY_FRAME; 155 }
156 if (sr & SR_FRAMING_ERROR) {
157 channel->stats.framing_err++;
158 flag = TTY_FRAME;
159 }
160 if (sr & SR_RECEIVED_BREAK) {
161 channel->stats.rcv_break++;
162 flag = TTY_BREAK;
163 }
156 } 164 }
157 if (sr & SR_RECEIVED_BREAK) { 165 tty_insert_flip_char(tty, value, flag);
158 channel->stats.rcv_break++;
159 flag = TTY_BREAK;
160 }
161 }
162 166
163 tty_insert_flip_char(tty, value, flag); 167 /* Check if there are more characters in RX FIFO
168 * If there are more, the isr register for this channel
169 * has enabled the RxRDY|FFULL bit.
170 */
171 isr = ioread8(&channel->block_regs->r.isr);
172 sr = ioread8(&channel->regs->r.sr);
173 } while (isr & channel->isr_rx_rdy_mask);
174
175 tty_flip_buffer_push(tty);
164} 176}
165 177
166static void ipoctal_irq_tx(struct ipoctal_channel *channel) 178static void ipoctal_irq_tx(struct ipoctal_channel *channel)