diff options
Diffstat (limited to 'drivers/tty/serial/ip22zilog.c')
-rw-r--r-- | drivers/tty/serial/ip22zilog.c | 30 |
1 files changed, 12 insertions, 18 deletions
diff --git a/drivers/tty/serial/ip22zilog.c b/drivers/tty/serial/ip22zilog.c index 7b1cda59ebb5..cb3c81eb0996 100644 --- a/drivers/tty/serial/ip22zilog.c +++ b/drivers/tty/serial/ip22zilog.c | |||
@@ -248,17 +248,12 @@ static void ip22zilog_maybe_update_regs(struct uart_ip22zilog_port *up, | |||
248 | #define Rx_BRK 0x0100 /* BREAK event software flag. */ | 248 | #define Rx_BRK 0x0100 /* BREAK event software flag. */ |
249 | #define Rx_SYS 0x0200 /* SysRq event software flag. */ | 249 | #define Rx_SYS 0x0200 /* SysRq event software flag. */ |
250 | 250 | ||
251 | static struct tty_struct *ip22zilog_receive_chars(struct uart_ip22zilog_port *up, | 251 | static bool ip22zilog_receive_chars(struct uart_ip22zilog_port *up, |
252 | struct zilog_channel *channel) | 252 | struct zilog_channel *channel) |
253 | { | 253 | { |
254 | struct tty_struct *tty; | ||
255 | unsigned char ch, flag; | 254 | unsigned char ch, flag; |
256 | unsigned int r1; | 255 | unsigned int r1; |
257 | 256 | bool push = up->port.state != NULL; | |
258 | tty = NULL; | ||
259 | if (up->port.state != NULL && | ||
260 | up->port.state->port.tty != NULL) | ||
261 | tty = up->port.state->port.tty; | ||
262 | 257 | ||
263 | for (;;) { | 258 | for (;;) { |
264 | ch = readb(&channel->control); | 259 | ch = readb(&channel->control); |
@@ -312,10 +307,10 @@ static struct tty_struct *ip22zilog_receive_chars(struct uart_ip22zilog_port *up | |||
312 | if (uart_handle_sysrq_char(&up->port, ch)) | 307 | if (uart_handle_sysrq_char(&up->port, ch)) |
313 | continue; | 308 | continue; |
314 | 309 | ||
315 | if (tty) | 310 | if (push) |
316 | uart_insert_char(&up->port, r1, Rx_OVR, ch, flag); | 311 | uart_insert_char(&up->port, r1, Rx_OVR, ch, flag); |
317 | } | 312 | } |
318 | return tty; | 313 | return push; |
319 | } | 314 | } |
320 | 315 | ||
321 | static void ip22zilog_status_handle(struct uart_ip22zilog_port *up, | 316 | static void ip22zilog_status_handle(struct uart_ip22zilog_port *up, |
@@ -438,21 +433,20 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) | |||
438 | while (up) { | 433 | while (up) { |
439 | struct zilog_channel *channel | 434 | struct zilog_channel *channel |
440 | = ZILOG_CHANNEL_FROM_PORT(&up->port); | 435 | = ZILOG_CHANNEL_FROM_PORT(&up->port); |
441 | struct tty_struct *tty; | ||
442 | unsigned char r3; | 436 | unsigned char r3; |
437 | bool push = false; | ||
443 | 438 | ||
444 | spin_lock(&up->port.lock); | 439 | spin_lock(&up->port.lock); |
445 | r3 = read_zsreg(channel, R3); | 440 | r3 = read_zsreg(channel, R3); |
446 | 441 | ||
447 | /* Channel A */ | 442 | /* Channel A */ |
448 | tty = NULL; | ||
449 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { | 443 | if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { |
450 | writeb(RES_H_IUS, &channel->control); | 444 | writeb(RES_H_IUS, &channel->control); |
451 | ZSDELAY(); | 445 | ZSDELAY(); |
452 | ZS_WSYNC(channel); | 446 | ZS_WSYNC(channel); |
453 | 447 | ||
454 | if (r3 & CHARxIP) | 448 | if (r3 & CHARxIP) |
455 | tty = ip22zilog_receive_chars(up, channel); | 449 | push = ip22zilog_receive_chars(up, channel); |
456 | if (r3 & CHAEXT) | 450 | if (r3 & CHAEXT) |
457 | ip22zilog_status_handle(up, channel); | 451 | ip22zilog_status_handle(up, channel); |
458 | if (r3 & CHATxIP) | 452 | if (r3 & CHATxIP) |
@@ -460,22 +454,22 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) | |||
460 | } | 454 | } |
461 | spin_unlock(&up->port.lock); | 455 | spin_unlock(&up->port.lock); |
462 | 456 | ||
463 | if (tty) | 457 | if (push) |
464 | tty_flip_buffer_push(tty); | 458 | tty_flip_buffer_push(&up->port.state->port); |
465 | 459 | ||
466 | /* Channel B */ | 460 | /* Channel B */ |
467 | up = up->next; | 461 | up = up->next; |
468 | channel = ZILOG_CHANNEL_FROM_PORT(&up->port); | 462 | channel = ZILOG_CHANNEL_FROM_PORT(&up->port); |
463 | push = false; | ||
469 | 464 | ||
470 | spin_lock(&up->port.lock); | 465 | spin_lock(&up->port.lock); |
471 | tty = NULL; | ||
472 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { | 466 | if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { |
473 | writeb(RES_H_IUS, &channel->control); | 467 | writeb(RES_H_IUS, &channel->control); |
474 | ZSDELAY(); | 468 | ZSDELAY(); |
475 | ZS_WSYNC(channel); | 469 | ZS_WSYNC(channel); |
476 | 470 | ||
477 | if (r3 & CHBRxIP) | 471 | if (r3 & CHBRxIP) |
478 | tty = ip22zilog_receive_chars(up, channel); | 472 | push = ip22zilog_receive_chars(up, channel); |
479 | if (r3 & CHBEXT) | 473 | if (r3 & CHBEXT) |
480 | ip22zilog_status_handle(up, channel); | 474 | ip22zilog_status_handle(up, channel); |
481 | if (r3 & CHBTxIP) | 475 | if (r3 & CHBTxIP) |
@@ -483,8 +477,8 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id) | |||
483 | } | 477 | } |
484 | spin_unlock(&up->port.lock); | 478 | spin_unlock(&up->port.lock); |
485 | 479 | ||
486 | if (tty) | 480 | if (push) |
487 | tty_flip_buffer_push(tty); | 481 | tty_flip_buffer_push(&up->port.state->port); |
488 | 482 | ||
489 | up = up->next; | 483 | up = up->next; |
490 | } | 484 | } |