diff options
Diffstat (limited to 'drivers/tty/serial/serial_core.c')
| -rw-r--r-- | drivers/tty/serial/serial_core.c | 54 |
1 files changed, 33 insertions, 21 deletions
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index f26834d262b..fbf6c5ad222 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -137,6 +137,11 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, return 1; /* + * Make sure the device is in D0 state. + */ + uart_change_pm(state, UART_PM_STATE_ON); + + /* * Initialise and allocate the transmit and temporary * buffer. */ @@ -169,8 +174,12 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, if (tty->termios.c_cflag & CBAUD) uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR); } - - if (tty_port_cts_enabled(port)) { + /* + * if hw support flow control without software intervention, + * then skip the below check + */ + if (tty_port_cts_enabled(port) && + !(uport->flags & UPF_HARD_FLOW)) { spin_lock_irq(&uport->lock); if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS)) tty->hw_stopped = 1; @@ -825,25 +834,29 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, * If we fail to request resources for the * new port, try to restore the old settings. */ - if (retval && old_type != PORT_UNKNOWN) { + if (retval) { uport->iobase = old_iobase; uport->type = old_type; uport->hub6 = old_hub6; uport->iotype = old_iotype; uport->regshift = old_shift; uport->mapbase = old_mapbase; - retval = uport->ops->request_port(uport); - /* - * If we failed to restore the old settings, - * we fail like this. - */ - if (retval) - uport->type = PORT_UNKNOWN; - /* - * We failed anyway. - */ - retval = -EBUSY; + if (old_type != PORT_UNKNOWN) { + retval = uport->ops->request_port(uport); + /* + * If we failed to restore the old settings, + * we fail like this. + */ + if (retval) + uport->type = PORT_UNKNOWN; + + /* + * We failed anyway. + */ + retval = -EBUSY; + } + /* Added to return the correct error -Ram Gupta */ goto exit; } @@ -1571,12 +1584,6 @@ static int uart_open(struct tty_struct *tty, struct file *filp) } /* - * Make sure the device is in D0 state. - */ - if (port->count == 1) - uart_change_pm(state, UART_PM_STATE_ON); - - /* * Start up the serial port. */ retval = uart_startup(tty, state, 0); @@ -2236,6 +2243,9 @@ static void uart_poll_put_char(struct tty_driver *driver, int line, char ch) return; port = state->uart_port; + + if (ch == '\n') + port->ops->poll_put_char(port, '\r'); port->ops->poll_put_char(port, ch); } #endif @@ -2769,7 +2779,9 @@ void uart_handle_cts_change(struct uart_port *uport, unsigned int status) uport->icount.cts++; - if (tty_port_cts_enabled(port)) { + /* skip below code if the hw flow control is supported */ + if (tty_port_cts_enabled(port) && + !(uport->flags & UPF_HARD_FLOW)) { if (tty->hw_stopped) { if (status) { tty->hw_stopped = 0; |
