diff options
author | codeworkx <daniel.hillenbrand@codeworkx.de> | 2012-06-02 13:09:29 +0200 |
---|---|---|
committer | codeworkx <daniel.hillenbrand@codeworkx.de> | 2012-06-02 13:09:29 +0200 |
commit | c6da2cfeb05178a11c6d062a06f8078150ee492f (patch) | |
tree | f3b4021d252c52d6463a9b3c1bb7245e399b009c /drivers/tty/serial/serial_core.c | |
parent | c6d7c4dbff353eac7919342ae6b3299a378160a6 (diff) | |
download | kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.zip kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.tar.gz kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.tar.bz2 |
samsung update 1
Diffstat (limited to 'drivers/tty/serial/serial_core.c')
-rw-r--r-- | drivers/tty/serial/serial_core.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 6bc20d7..65db939 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -91,6 +91,9 @@ static void __uart_start(struct tty_struct *tty) struct uart_state *state = tty->driver_data; struct uart_port *port = state->uart_port; + if (port->ops->wake_peer) + port->ops->wake_peer(port); + if (!uart_circ_empty(&state->xmit) && state->xmit.buf && !tty->stopped && !tty->hw_stopped) port->ops->start_tx(port); @@ -159,13 +162,17 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, int in * buffer. */ if (!state->xmit.buf) { + unsigned long flags; + /* This is protected by the per port mutex */ page = get_zeroed_page(GFP_KERNEL); if (!page) return -ENOMEM; + spin_lock_irqsave(&uport->lock, flags); state->xmit.buf = (unsigned char *) page; uart_circ_clear(&state->xmit); + spin_unlock_irqrestore(&uport->lock, flags); } retval = uport->ops->startup(uport); @@ -258,8 +265,11 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) * Free the transmit buffer page. */ if (state->xmit.buf) { + unsigned long flags; + spin_lock_irqsave(&uport->lock, flags); free_page((unsigned long)state->xmit.buf); state->xmit.buf = NULL; + spin_unlock_irqrestore(&uport->lock, flags); } } @@ -468,10 +478,12 @@ static inline int __uart_put_char(struct uart_port *port, unsigned long flags; int ret = 0; - if (!circ->buf) + spin_lock_irqsave(&port->lock, flags); + if (!circ->buf) { + spin_unlock_irqrestore(&port->lock, flags); return 0; + } - spin_lock_irqsave(&port->lock, flags); if (uart_circ_chars_free(circ) != 0) { circ->buf[circ->head] = c; circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1); @@ -514,10 +526,12 @@ static int uart_write(struct tty_struct *tty, port = state->uart_port; circ = &state->xmit; - if (!circ->buf) + spin_lock_irqsave(&port->lock, flags); + if (!circ->buf) { + spin_unlock_irqrestore(&port->lock, flags); return 0; + } - spin_lock_irqsave(&port->lock, flags); while (1) { c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE); if (count < c) |