[PATCH] TTY layer buffering revamp
[deliverable/linux.git] / drivers / serial / sunsu.c
index d57a3553aea359ac7a3123ae62261f2ed9abbb0d..9a3665b34d97218dca97b18bbf60740bb45dece7 100644 (file)
@@ -255,21 +255,30 @@ static void disable_rsa(struct uart_sunsu_port *up)
 }
 #endif /* CONFIG_SERIAL_8250_RSA */
 
-static void sunsu_stop_tx(struct uart_port *port, unsigned int tty_stop)
+static inline void __stop_tx(struct uart_sunsu_port *p)
+{
+       if (p->ier & UART_IER_THRI) {
+               p->ier &= ~UART_IER_THRI;
+               serial_out(p, UART_IER, p->ier);
+       }
+}
+
+static void sunsu_stop_tx(struct uart_port *port)
 {
        struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
 
-       if (up->ier & UART_IER_THRI) {
-               up->ier &= ~UART_IER_THRI;
-               serial_out(up, UART_IER, up->ier);
-       }
-       if (up->port.type == PORT_16C950 && tty_stop) {
+       __stop_tx(up);
+
+       /*
+        * We really want to stop the transmitter from sending.
+        */
+       if (up->port.type == PORT_16C950) {
                up->acr |= UART_ACR_TXDIS;
                serial_icr_write(up, UART_ACR, up->acr);
        }
 }
 
-static void sunsu_start_tx(struct uart_port *port, unsigned int tty_start)
+static void sunsu_start_tx(struct uart_port *port)
 {
        struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
 
@@ -277,10 +286,11 @@ static void sunsu_start_tx(struct uart_port *port, unsigned int tty_start)
                up->ier |= UART_IER_THRI;
                serial_out(up, UART_IER, up->ier);
        }
+
        /*
-        * We only do this from uart_start
+        * Re-enable the transmitter if we disabled it.
         */
-       if (tty_start && up->port.type == PORT_16C950) {
+       if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) {
                up->acr &= ~UART_ACR_TXDIS;
                serial_icr_write(up, UART_ACR, up->acr);
        }
@@ -313,19 +323,13 @@ 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;
-       unsigned char ch;
+       unsigned char ch, flag;
        int max_count = 256;
        int saw_console_brk = 0;
 
        do {
-               if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
-                       tty->flip.work.func((void *)tty);
-                       if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-                               return tty; // if TTY_DONT_FLIP is set
-               }
                ch = serial_inp(up, UART_RX);
-               *tty->flip.char_buf_ptr = ch;
-               *tty->flip.flag_buf_ptr = TTY_NORMAL;
+               flag = TTY_NORMAL;
                up->port.icount.rx++;
 
                if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE |
@@ -367,31 +371,23 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs
                        }
 
                        if (*status & UART_LSR_BI) {
-                               *tty->flip.flag_buf_ptr = TTY_BREAK;
+                               flag = TTY_BREAK;
                        } else if (*status & UART_LSR_PE)
-                               *tty->flip.flag_buf_ptr = TTY_PARITY;
+                               flag = TTY_PARITY;
                        else if (*status & UART_LSR_FE)
-                               *tty->flip.flag_buf_ptr = TTY_FRAME;
+                               flag = TTY_FRAME;
                }
                if (uart_handle_sysrq_char(&up->port, ch, regs))
                        goto ignore_char;
-               if ((*status & up->port.ignore_status_mask) == 0) {
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
-               }
-               if ((*status & UART_LSR_OE) &&
-                   tty->flip.count < TTY_FLIPBUF_SIZE) {
+               if ((*status & up->port.ignore_status_mask) == 0)
+                       tty_insert_flip_char(tty, ch, flag);
+               if (*status & UART_LSR_OE)
                        /*
                         * Overrun is special, since it's reported
                         * immediately, and doesn't affect the current
                         * character.
                         */
-                       *tty->flip.flag_buf_ptr = TTY_OVERRUN;
-                       tty->flip.flag_buf_ptr++;
-                       tty->flip.char_buf_ptr++;
-                       tty->flip.count++;
-               }
+                        tty_insert_flip_char(tty, 0, TTY_OVERRUN);
        ignore_char:
                *status = serial_inp(up, UART_LSR);
        } while ((*status & UART_LSR_DR) && (max_count-- > 0));
@@ -413,8 +409,12 @@ static _INLINE_ void transmit_chars(struct uart_sunsu_port *up)
                up->port.x_char = 0;
                return;
        }
-       if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
-               sunsu_stop_tx(&up->port, 0);
+       if (uart_tx_stopped(&up->port)) {
+               sunsu_stop_tx(&up->port);
+               return;
+       }
+       if (uart_circ_empty(xmit)) {
+               __stop_tx(up);
                return;
        }
 
@@ -431,7 +431,7 @@ static _INLINE_ void transmit_chars(struct uart_sunsu_port *up)
                uart_write_wakeup(&up->port);
 
        if (uart_circ_empty(xmit))
-               sunsu_stop_tx(&up->port, 0);
+               __stop_tx(up);
 }
 
 static _INLINE_ void check_modem_status(struct uart_sunsu_port *up)
@@ -504,11 +504,7 @@ static void sunsu_change_mouse_baud(struct uart_sunsu_port *up)
 
        quot = up->port.uartclk / (16 * new_baud);
 
-       spin_unlock(&up->port.lock);
-
        sunsu_change_speed(&up->port, up->cflag, 0, quot);
-
-       spin_lock(&up->port.lock);
 }
 
 static void receive_kbd_ms_chars(struct uart_sunsu_port *up, struct pt_regs *regs, int is_break)
@@ -1431,7 +1427,7 @@ static void sunsu_console_write(struct console *co, const char *s,
  *     - initialize the serial port
  *     Return non-zero if we didn't find a serial port.
  */
-static int __init sunsu_console_setup(struct console *co, char *options)
+static int sunsu_console_setup(struct console *co, char *options)
 {
        struct uart_port *port;
        int baud = 9600;
This page took 0.040665 seconds and 5 git commands to generate.