X-Git-Url: http://git.onelab.eu/?p=linux-2.6.git;a=blobdiff_plain;f=drivers%2Fserial%2Fsunsu.c;h=d72a7aaf280a8d7d05a97d715d43e59f07cdb1f1;hp=dffd7b67e227db805e075e3883e3348f960aad07;hb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;hpb=c449269f45c2cdf53af08c8d0af37472f66539d9 diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index dffd7b67e..d72a7aaf2 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -310,7 +310,7 @@ static void sunsu_enable_ms(struct uart_port *port) spin_unlock_irqrestore(&up->port.lock, flags); } -static _INLINE_ void +static _INLINE_ struct tty_struct * receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs *regs) { struct tty_struct *tty = up->port.info->tty; @@ -322,7 +322,7 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) { tty->flip.work.func((void *)tty); if (tty->flip.count >= TTY_FLIPBUF_SIZE) - return; // if TTY_DONT_FLIP is set + return tty; // if TTY_DONT_FLIP is set } ch = serial_inp(up, UART_RX); *tty->flip.char_buf_ptr = ch; @@ -396,10 +396,11 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs ignore_char: *status = serial_inp(up, UART_LSR); } while ((*status & UART_LSR_DR) && (max_count-- > 0)); - tty_flip_buffer_push(tty); if (saw_console_brk) sun_do_break(); + + return tty; } static _INLINE_ void transmit_chars(struct uart_sunsu_port *up) @@ -464,12 +465,23 @@ static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id, struct pt_regs spin_lock_irqsave(&up->port.lock, flags); do { + struct tty_struct *tty; + status = serial_inp(up, UART_LSR); + tty = NULL; if (status & UART_LSR_DR) - receive_chars(up, &status, regs); + tty = receive_chars(up, &status, regs); check_modem_status(up); if (status & UART_LSR_THRE) transmit_chars(up); + + spin_unlock_irqrestore(&up->port.lock, flags); + + if (tty) + tty_flip_buffer_push(tty); + + spin_lock_irqsave(&up->port.lock, flags); + } while (!(serial_in(up, UART_IIR) & UART_IIR_NO_INT)); spin_unlock_irqrestore(&up->port.lock, flags);