summaryrefslogtreecommitdiff
path: root/drivers/tty/serial/serial_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/serial_core.c')
-rw-r--r--drivers/tty/serial/serial_core.c82
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);