diff options
Diffstat (limited to 'drivers/tty/serial/serial_core.c')
-rw-r--r-- | drivers/tty/serial/serial_core.c | 82 |
1 files changed, 49 insertions, 33 deletions
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index b9fbbee598b8..2bd32c8ece39 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -169,9 +169,9 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear) #define uart_set_mctrl(port, set) uart_update_mctrl(port, set, 0) #define uart_clear_mctrl(port, clear) uart_update_mctrl(port, 0, clear) -static void uart_port_dtr_rts(struct uart_port *uport, int raise) +static void uart_port_dtr_rts(struct uart_port *uport, bool active) { - if (raise) + if (active) uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS); else uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); @@ -182,7 +182,7 @@ static void uart_port_dtr_rts(struct uart_port *uport, int raise) * will be serialised by the per-port mutex. */ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, - int init_hw) + bool init_hw) { struct uart_port *uport = uart_port_check(state); unsigned long flags; @@ -239,7 +239,7 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, * port is open and ready to respond. */ if (init_hw && C_BAUD(tty)) - uart_port_dtr_rts(uport, 1); + uart_port_dtr_rts(uport, true); } /* @@ -254,7 +254,7 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, } static int uart_startup(struct tty_struct *tty, struct uart_state *state, - int init_hw) + bool init_hw) { struct tty_port *port = &state->port; int retval; @@ -290,7 +290,7 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) set_bit(TTY_IO_ERROR, &tty->flags); if (tty_port_initialized(port)) { - tty_port_set_initialized(port, 0); + tty_port_set_initialized(port, false); /* * Turn off DTR and RTS early. @@ -302,7 +302,7 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) } if (!tty || C_HUPCL(tty)) - uart_port_dtr_rts(uport, 0); + uart_port_dtr_rts(uport, false); uart_port_shutdown(port); } @@ -312,7 +312,7 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) * a DCD drop (hangup) at just the right time. Clear suspended bit so * we don't try to resume a port that has been shutdown. */ - tty_port_set_suspended(port, 0); + tty_port_set_suspended(port, false); /* * Do not free() the transmit buffer page under the port lock since @@ -997,7 +997,7 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, uart_change_speed(tty, state, NULL); } } else { - retval = uart_startup(tty, state, 1); + retval = uart_startup(tty, state, true); if (retval == 0) tty_port_set_initialized(port, true); if (retval > 0) @@ -1165,7 +1165,7 @@ static int uart_do_autoconfig(struct tty_struct *tty, struct uart_state *state) */ uport->ops->config_port(uport, flags); - ret = uart_startup(tty, state, 1); + ret = uart_startup(tty, state, true); if (ret == 0) tty_port_set_initialized(port, true); if (ret > 0) @@ -1725,7 +1725,7 @@ static void uart_tty_port_shutdown(struct tty_port *port) * a DCD drop (hangup) at just the right time. Clear suspended bit so * we don't try to resume a port that has been shutdown. */ - tty_port_set_suspended(port, 0); + tty_port_set_suspended(port, false); /* * Free the transmit buffer. @@ -1827,7 +1827,7 @@ static void uart_hangup(struct tty_struct *tty) spin_lock_irqsave(&port->lock, flags); port->count = 0; spin_unlock_irqrestore(&port->lock, flags); - tty_port_set_active(port, 0); + tty_port_set_active(port, false); tty_port_tty_set(port, NULL); if (uport && !uart_console(uport)) uart_change_pm(state, UART_PM_STATE_OFF); @@ -1861,7 +1861,7 @@ static void uart_port_shutdown(struct tty_port *port) } } -static int uart_carrier_raised(struct tty_port *port) +static bool uart_carrier_raised(struct tty_port *port) { struct uart_state *state = container_of(port, struct uart_state, port); struct uart_port *uport; @@ -1875,18 +1875,17 @@ static int uart_carrier_raised(struct tty_port *port) * continue and not sleep */ if (WARN_ON(!uport)) - return 1; + return true; spin_lock_irq(&uport->lock); uart_enable_ms(uport); mctrl = uport->ops->get_mctrl(uport); spin_unlock_irq(&uport->lock); uart_port_deref(uport); - if (mctrl & TIOCM_CAR) - return 1; - return 0; + + return mctrl & TIOCM_CAR; } -static void uart_dtr_rts(struct tty_port *port, int raise) +static void uart_dtr_rts(struct tty_port *port, bool active) { struct uart_state *state = container_of(port, struct uart_state, port); struct uart_port *uport; @@ -1894,7 +1893,7 @@ static void uart_dtr_rts(struct tty_port *port, int raise) uport = uart_port_ref(state); if (!uport) return; - uart_port_dtr_rts(uport, raise); + uart_port_dtr_rts(uport, active); uart_port_deref(uport); } @@ -1943,9 +1942,9 @@ static int uart_port_activate(struct tty_port *port, struct tty_struct *tty) /* * Start up the serial port. */ - ret = uart_startup(tty, state, 0); + ret = uart_startup(tty, state, false); if (ret > 0) - tty_port_set_active(port, 1); + tty_port_set_active(port, true); return ret; } @@ -2212,6 +2211,9 @@ EXPORT_SYMBOL_GPL(uart_parse_options); * @parity: parity character - 'n' (none), 'o' (odd), 'e' (even) * @bits: number of data bits * @flow: flow control character - 'r' (rts) + * + * Locking: Caller must hold console_list_lock in order to serialize + * early initialization of the serial-console lock. */ int uart_set_options(struct uart_port *port, struct console *co, @@ -2346,8 +2348,8 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) int tries; unsigned int mctrl; - tty_port_set_suspended(port, 1); - tty_port_set_initialized(port, 0); + tty_port_set_suspended(port, true); + tty_port_set_initialized(port, false); spin_lock_irq(&uport->lock); ops->stop_tx(uport); @@ -2458,7 +2460,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) uart_rs485_config(uport); ops->start_tx(uport); spin_unlock_irq(&uport->lock); - tty_port_set_initialized(port, 1); + tty_port_set_initialized(port, true); } else { /* * Failed to resume - maybe hardware went away? @@ -2469,7 +2471,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) } } - tty_port_set_suspended(port, 0); + tty_port_set_suspended(port, false); } mutex_unlock(&port->mutex); @@ -2619,7 +2621,9 @@ static int uart_poll_init(struct tty_driver *driver, int line, char *options) if (!ret && options) { uart_parse_options(options, &baud, &parity, &bits, &flow); + console_list_lock(); ret = uart_set_options(port, NULL, baud, parity, bits, flow); + console_list_unlock(); } out: mutex_unlock(&tport->mutex); @@ -3253,11 +3257,11 @@ EXPORT_SYMBOL(uart_match_port); /** * uart_handle_dcd_change - handle a change of carrier detect state * @uport: uart_port structure for the open port - * @status: new carrier detect status, nonzero if active + * @active: new carrier detect status * * Caller must hold uport->lock. */ -void uart_handle_dcd_change(struct uart_port *uport, unsigned int status) +void uart_handle_dcd_change(struct uart_port *uport, bool active) { struct tty_port *port = &uport->state->port; struct tty_struct *tty = port->tty; @@ -3269,7 +3273,7 @@ void uart_handle_dcd_change(struct uart_port *uport, unsigned int status) ld = tty_ldisc_ref(tty); if (ld) { if (ld->ops->dcd_change) - ld->ops->dcd_change(tty, status); + ld->ops->dcd_change(tty, active); tty_ldisc_deref(ld); } } @@ -3277,7 +3281,7 @@ void uart_handle_dcd_change(struct uart_port *uport, unsigned int status) uport->icount.dcd++; if (uart_dcd_enabled(uport)) { - if (status) + if (active) wake_up_interruptible(&port->open_wait); else if (tty) tty_hangup(tty); @@ -3288,11 +3292,11 @@ EXPORT_SYMBOL_GPL(uart_handle_dcd_change); /** * uart_handle_cts_change - handle a change of clear-to-send state * @uport: uart_port structure for the open port - * @status: new clear to send status, nonzero if active + * @active: new clear-to-send status * * Caller must hold uport->lock. */ -void uart_handle_cts_change(struct uart_port *uport, unsigned int status) +void uart_handle_cts_change(struct uart_port *uport, bool active) { lockdep_assert_held_once(&uport->lock); @@ -3300,13 +3304,13 @@ void uart_handle_cts_change(struct uart_port *uport, unsigned int status) if (uart_softcts_mode(uport)) { if (uport->hw_stopped) { - if (status) { + if (active) { uport->hw_stopped = 0; uport->ops->start_tx(uport); uart_write_wakeup(uport); } } else { - if (!status) { + if (!active) { uport->hw_stopped = 1; uport->ops->stop_tx(uport); } @@ -3410,6 +3414,7 @@ int uart_get_rs485_mode(struct uart_port *port) struct device *dev = port->dev; u32 rs485_delay[2]; int ret; + int rx_during_tx_gpio_flag; ret = device_property_read_u32_array(dev, "rs485-rts-delay", rs485_delay, 2); @@ -3458,6 +3463,17 @@ int uart_get_rs485_mode(struct uart_port *port) if (port->rs485_term_gpio) port->rs485_supported.flags |= SER_RS485_TERMINATE_BUS; + rx_during_tx_gpio_flag = (rs485conf->flags & SER_RS485_RX_DURING_TX) ? + GPIOD_OUT_HIGH : GPIOD_OUT_LOW; + port->rs485_rx_during_tx_gpio = devm_gpiod_get_optional(dev, + "rs485-rx-during-tx", + rx_during_tx_gpio_flag); + if (IS_ERR(port->rs485_rx_during_tx_gpio)) { + ret = PTR_ERR(port->rs485_rx_during_tx_gpio); + port->rs485_rx_during_tx_gpio = NULL; + return dev_err_probe(dev, ret, "Cannot get rs485-rx-during-tx-gpios\n"); + } + return 0; } EXPORT_SYMBOL_GPL(uart_get_rs485_mode); |