diff options
author | Samuel Iglesias Gonsalvez <siglesias@igalia.com> | 2012-09-12 08:55:43 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-09-12 12:56:02 -0400 |
commit | ab0a71f06d44334154091c6cdc823f908398623e (patch) | |
tree | a31d2a85f26c70c3d37f19ddafe1818b06d9ad91 | |
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>
-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, | |||
134 | static void ipoctal_irq_rx(struct ipoctal_channel *channel, | 134 | static 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 | ||
166 | static void ipoctal_irq_tx(struct ipoctal_channel *channel) | 178 | static void ipoctal_irq_tx(struct ipoctal_channel *channel) |