aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/pmac_zilog.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial/pmac_zilog.c')
-rw-r--r--drivers/serial/pmac_zilog.c39
1 files changed, 8 insertions, 31 deletions
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index ea24129eb6b9..f330d6c0e0df 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -210,10 +210,9 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap,
210 struct pt_regs *regs) 210 struct pt_regs *regs)
211{ 211{
212 struct tty_struct *tty = NULL; 212 struct tty_struct *tty = NULL;
213 unsigned char ch, r1, drop, error; 213 unsigned char ch, r1, drop, error, flag;
214 int loops = 0; 214 int loops = 0;
215 215
216 retry:
217 /* The interrupt can be enabled when the port isn't open, typically 216 /* The interrupt can be enabled when the port isn't open, typically
218 * that happens when using one port is open and the other closed (stale 217 * that happens when using one port is open and the other closed (stale
219 * interrupt) or when one port is used as a console. 218 * interrupt) or when one port is used as a console.
@@ -246,20 +245,6 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap,
246 error = 0; 245 error = 0;
247 drop = 0; 246 drop = 0;
248 247
249 if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
250 /* Have to drop the lock here */
251 pmz_debug("pmz: flip overflow\n");
252 spin_unlock(&uap->port.lock);
253 tty->flip.work.func((void *)tty);
254 spin_lock(&uap->port.lock);
255 if (tty->flip.count >= TTY_FLIPBUF_SIZE)
256 drop = 1;
257 if (ZS_IS_ASLEEP(uap))
258 return NULL;
259 if (!ZS_IS_OPEN(uap))
260 goto retry;
261 }
262
263 r1 = read_zsreg(uap, R1); 248 r1 = read_zsreg(uap, R1);
264 ch = read_zsdata(uap); 249 ch = read_zsdata(uap);
265 250
@@ -295,8 +280,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap,
295 if (drop) 280 if (drop)
296 goto next_char; 281 goto next_char;
297 282
298 *tty->flip.char_buf_ptr = ch; 283 flag = TTY_NORMAL;
299 *tty->flip.flag_buf_ptr = TTY_NORMAL;
300 uap->port.icount.rx++; 284 uap->port.icount.rx++;
301 285
302 if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR | BRK_ABRT)) { 286 if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR | BRK_ABRT)) {
@@ -316,26 +300,19 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap,
316 uap->port.icount.overrun++; 300 uap->port.icount.overrun++;
317 r1 &= uap->port.read_status_mask; 301 r1 &= uap->port.read_status_mask;
318 if (r1 & BRK_ABRT) 302 if (r1 & BRK_ABRT)
319 *tty->flip.flag_buf_ptr = TTY_BREAK; 303 flag = TTY_BREAK;
320 else if (r1 & PAR_ERR) 304 else if (r1 & PAR_ERR)
321 *tty->flip.flag_buf_ptr = TTY_PARITY; 305 flag = TTY_PARITY;
322 else if (r1 & CRC_ERR) 306 else if (r1 & CRC_ERR)
323 *tty->flip.flag_buf_ptr = TTY_FRAME; 307 flag = TTY_FRAME;
324 } 308 }
325 309
326 if (uap->port.ignore_status_mask == 0xff || 310 if (uap->port.ignore_status_mask == 0xff ||
327 (r1 & uap->port.ignore_status_mask) == 0) { 311 (r1 & uap->port.ignore_status_mask) == 0) {
328 tty->flip.flag_buf_ptr++; 312 tty_insert_flip_char(tty, ch, flag);
329 tty->flip.char_buf_ptr++;
330 tty->flip.count++;
331 }
332 if ((r1 & Rx_OVR) &&
333 tty->flip.count < TTY_FLIPBUF_SIZE) {
334 *tty->flip.flag_buf_ptr = TTY_OVERRUN;
335 tty->flip.flag_buf_ptr++;
336 tty->flip.char_buf_ptr++;
337 tty->flip.count++;
338 } 313 }
314 if (r1 & Rx_OVR)
315 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
339 next_char: 316 next_char:
340 /* We can get stuck in an infinite loop getting char 0 when the 317 /* We can get stuck in an infinite loop getting char 0 when the
341 * line is in a wrong HW state, we break that here. 318 * line is in a wrong HW state, we break that here.