Commit 56609c05 authored by Jiri Slaby (SUSE)'s avatar Jiri Slaby (SUSE) Committed by Greg Kroah-Hartman
Browse files

serial: serial_core: use guard()s



Having all the new guards, use them in the serial_core code. This
improves readability, makes error handling easier, and marks locked
portions of code explicit.

Signed-off-by: default avatar"Jiri Slaby (SUSE)" <jirislaby@kernel.org>
Link: https://lore.kernel.org/r/20250814072456.182853-9-jirislaby@kernel.org


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 793b4501
Loading
Loading
Loading
Loading
+59 −84
Original line number Diff line number Diff line
@@ -177,15 +177,13 @@ static void uart_start(struct tty_struct *tty)
static void
uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)
{
	unsigned long flags;
	unsigned int old;

	uart_port_lock_irqsave(port, &flags);
	guard(uart_port_lock_irqsave)(port);
	old = port->mctrl;
	port->mctrl = (old & ~clear) | set;
	if (old != port->mctrl && !(port->rs485.flags & SER_RS485_ENABLED))
		port->ops->set_mctrl(port, port->mctrl);
	uart_port_unlock_irqrestore(port, flags);
}

#define uart_set_mctrl(port, set)	uart_update_mctrl(port, set, 0)
@@ -220,7 +218,7 @@ static void uart_change_line_settings(struct tty_struct *tty, struct uart_state
	/*
	 * Set modem status enables based on termios cflag
	 */
	uart_port_lock_irq(uport);
	guard(uart_port_lock_irq)(uport);
	if (termios->c_cflag & CRTSCTS)
		uport->status |= UPSTAT_CTS_ENABLE;
	else
@@ -241,7 +239,6 @@ static void uart_change_line_settings(struct tty_struct *tty, struct uart_state
		else
			__uart_start(state);
	}
	uart_port_unlock_irq(uport);
}

static int uart_alloc_xmit_buf(struct tty_port *port)
@@ -711,7 +708,6 @@ static void uart_send_xchar(struct tty_struct *tty, u8 ch)
{
	struct uart_state *state = tty->driver_data;
	struct uart_port *port;
	unsigned long flags;

	port = uart_port_ref(state);
	if (!port)
@@ -720,11 +716,10 @@ static void uart_send_xchar(struct tty_struct *tty, u8 ch)
	if (port->ops->send_xchar)
		port->ops->send_xchar(port, ch);
	else {
		uart_port_lock_irqsave(port, &flags);
		guard(uart_port_lock_irqsave)(port);
		port->x_char = ch;
		if (ch)
			port->ops->start_tx(port);
		uart_port_unlock_irqrestore(port, flags);
	}
	uart_port_deref(port);
}
@@ -1089,7 +1084,6 @@ static int uart_tiocmget(struct tty_struct *tty)
	struct uart_state *state = tty->driver_data;
	struct tty_port *port = &state->port;
	struct uart_port *uport;
	int result;

	guard(mutex)(&port->mutex);

@@ -1097,12 +1091,9 @@ static int uart_tiocmget(struct tty_struct *tty)
	if (!uport || tty_io_error(tty))
		return -EIO;

	uart_port_lock_irq(uport);
	result = uport->mctrl;
	result |= uport->ops->get_mctrl(uport);
	uart_port_unlock_irq(uport);
	guard(uart_port_lock_irq)(uport);

	return result;
	return uport->mctrl | uport->ops->get_mctrl(uport);
}

static int
@@ -1226,16 +1217,15 @@ static int uart_wait_modem_status(struct uart_state *state, unsigned long arg)
	uport = uart_port_ref(state);
	if (!uport)
		return -EIO;
	uart_port_lock_irq(uport);
	scoped_guard(uart_port_lock_irq, uport) {
		memcpy(&cprev, &uport->icount, sizeof(struct uart_icount));
		uart_enable_ms(uport);
	uart_port_unlock_irq(uport);
	}

	add_wait_queue(&port->delta_msr_wait, &wait);
	for (;;) {
		uart_port_lock_irq(uport);
		scoped_guard(uart_port_lock_irq, uport)
			memcpy(&cnow, &uport->icount, sizeof(struct uart_icount));
		uart_port_unlock_irq(uport);

		set_current_state(TASK_INTERRUPTIBLE);

@@ -1430,7 +1420,6 @@ static void uart_set_rs485_rx_during_tx(struct uart_port *port,
static int uart_rs485_config(struct uart_port *port)
{
	struct serial_rs485 *rs485 = &port->rs485;
	unsigned long flags;
	int ret;

	if (!(rs485->flags & SER_RS485_ENABLED))
@@ -1440,9 +1429,8 @@ static int uart_rs485_config(struct uart_port *port)
	uart_set_rs485_termination(port, rs485);
	uart_set_rs485_rx_during_tx(port, rs485);

	uart_port_lock_irqsave(port, &flags);
	scoped_guard(uart_port_lock_irqsave, port)
		ret = port->rs485_config(port, NULL, rs485);
	uart_port_unlock_irqrestore(port, flags);
	if (ret) {
		memset(rs485, 0, sizeof(*rs485));
		/* unset GPIOs */
@@ -1456,12 +1444,10 @@ static int uart_rs485_config(struct uart_port *port)
static int uart_get_rs485_config(struct uart_port *port,
			 struct serial_rs485 __user *rs485)
{
	unsigned long flags;
	struct serial_rs485 aux;

	uart_port_lock_irqsave(port, &flags);
	scoped_guard(uart_port_lock_irqsave, port)
		aux = port->rs485;
	uart_port_unlock_irqrestore(port, flags);

	if (copy_to_user(rs485, &aux, sizeof(aux)))
		return -EFAULT;
@@ -1474,7 +1460,6 @@ static int uart_set_rs485_config(struct tty_struct *tty, struct uart_port *port,
{
	struct serial_rs485 rs485;
	int ret;
	unsigned long flags;

	if (!(port->rs485_supported.flags & SER_RS485_ENABLED))
		return -ENOTTY;
@@ -1489,7 +1474,7 @@ static int uart_set_rs485_config(struct tty_struct *tty, struct uart_port *port,
	uart_set_rs485_termination(port, &rs485);
	uart_set_rs485_rx_during_tx(port, &rs485);

	uart_port_lock_irqsave(port, &flags);
	scoped_guard(uart_port_lock_irqsave, port) {
		ret = port->rs485_config(port, &tty->termios, &rs485);
		if (!ret) {
			port->rs485 = rs485;
@@ -1498,7 +1483,7 @@ static int uart_set_rs485_config(struct tty_struct *tty, struct uart_port *port,
			if (!(rs485.flags & SER_RS485_ENABLED))
				port->ops->set_mctrl(port, port->mctrl);
		}
	uart_port_unlock_irqrestore(port, flags);
	}
	if (ret) {
		/* restore old GPIO settings */
		gpiod_set_value_cansleep(port->rs485_term_gpio,
@@ -1517,15 +1502,13 @@ static int uart_set_rs485_config(struct tty_struct *tty, struct uart_port *port,
static int uart_get_iso7816_config(struct uart_port *port,
				   struct serial_iso7816 __user *iso7816)
{
	unsigned long flags;
	struct serial_iso7816 aux;

	if (!port->iso7816_config)
		return -ENOTTY;

	uart_port_lock_irqsave(port, &flags);
	scoped_guard(uart_port_lock_irqsave, port)
		aux = port->iso7816;
	uart_port_unlock_irqrestore(port, flags);

	if (copy_to_user(iso7816, &aux, sizeof(aux)))
		return -EFAULT;
@@ -1537,8 +1520,7 @@ static int uart_set_iso7816_config(struct uart_port *port,
				   struct serial_iso7816 __user *iso7816_user)
{
	struct serial_iso7816 iso7816;
	int i, ret;
	unsigned long flags;
	int i;

	if (!port->iso7816_config)
		return -ENOTTY;
@@ -1554,11 +1536,11 @@ static int uart_set_iso7816_config(struct uart_port *port,
		if (iso7816.reserved[i])
			return -EINVAL;

	uart_port_lock_irqsave(port, &flags);
	ret = port->iso7816_config(port, &iso7816);
	uart_port_unlock_irqrestore(port, flags);
	scoped_guard(uart_port_lock_irqsave, port) {
		int ret = port->iso7816_config(port, &iso7816);
		if (ret)
			return ret;
	}

	if (copy_to_user(iso7816_user, &port->iso7816, sizeof(port->iso7816)))
		return -EFAULT;
@@ -1770,9 +1752,8 @@ static void uart_tty_port_shutdown(struct tty_port *port)
	if (WARN(!uport, "detached port still initialized!\n"))
		return;

	uart_port_lock_irq(uport);
	scoped_guard(uart_port_lock_irq, uport)
		uport->ops->stop_rx(uport);
	uart_port_unlock_irq(uport);

	serial_base_port_shutdown(uport);
	uart_port_shutdown(port);
@@ -2044,9 +2025,8 @@ static void uart_line_info(struct seq_file *m, struct uart_state *state)
		pm_state = state->pm_state;
		if (pm_state != UART_PM_STATE_ON)
			uart_change_pm(state, UART_PM_STATE_ON);
		uart_port_lock_irq(uport);
		scoped_guard(uart_port_lock_irq, uport)
			status = uport->ops->get_mctrl(uport);
		uart_port_unlock_irq(uport);
		if (pm_state != UART_PM_STATE_ON)
			uart_change_pm(state, pm_state);

@@ -2355,9 +2335,8 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
	 */
	if (!console_suspend_enabled && uart_console(uport)) {
		if (uport->ops->start_rx) {
			uart_port_lock_irq(uport);
			guard(uart_port_lock_irq)(uport);
			uport->ops->stop_rx(uport);
			uart_port_unlock_irq(uport);
		}
		device_set_awake_path(uport->dev);
		return 0;
@@ -2373,7 +2352,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
		tty_port_set_suspended(port, true);
		tty_port_set_initialized(port, false);

		uart_port_lock_irq(uport);
		scoped_guard(uart_port_lock_irq, uport) {
			ops->stop_tx(uport);
			if (!(uport->rs485.flags & SER_RS485_ENABLED))
				ops->set_mctrl(uport, 0);
@@ -2381,7 +2360,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
			mctrl = uport->mctrl;
			uport->mctrl = 0;
			ops->stop_rx(uport);
		uart_port_unlock_irq(uport);
		}

		/*
		 * Wait for the transmitter to empty.
@@ -2450,9 +2429,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
			uart_change_pm(state, UART_PM_STATE_ON);
		uport->ops->set_termios(uport, &termios, NULL);
		if (!console_suspend_enabled && uport->ops->start_rx) {
			uart_port_lock_irq(uport);
			guard(uart_port_lock_irq)(uport);
			uport->ops->start_rx(uport);
			uart_port_unlock_irq(uport);
		}
		if (console_suspend_enabled)
			console_resume(uport->cons);
@@ -2463,10 +2441,9 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
		int ret;

		uart_change_pm(state, UART_PM_STATE_ON);
		uart_port_lock_irq(uport);
		scoped_guard(uart_port_lock_irq, uport)
			if (!(uport->rs485.flags & SER_RS485_ENABLED))
				ops->set_mctrl(uport, 0);
		uart_port_unlock_irq(uport);
		if (console_suspend_enabled || !uart_console(uport)) {
			/* Protected by port mutex for now */
			struct tty_struct *tty = port->tty;
@@ -2476,11 +2453,11 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
				if (tty)
					uart_change_line_settings(tty, state, NULL);
				uart_rs485_config(uport);
				uart_port_lock_irq(uport);
				scoped_guard(uart_port_lock_irq, uport) {
					if (!(uport->rs485.flags & SER_RS485_ENABLED))
						ops->set_mctrl(uport, uport->mctrl);
					ops->start_tx(uport);
				uart_port_unlock_irq(uport);
				}
				tty_port_set_initialized(port, true);
			} else {
				/*
@@ -2574,8 +2551,6 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
	}

	if (port->type != PORT_UNKNOWN) {
		unsigned long flags;

		uart_report_port(drv, port);

		/* Synchronize with possible boot console. */
@@ -2590,11 +2565,11 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
		 * keep the DTR setting that is set in uart_set_options()
		 * We probably don't need a spinlock around this, but
		 */
		uart_port_lock_irqsave(port, &flags);
		scoped_guard(uart_port_lock_irqsave, port) {
			port->mctrl &= TIOCM_DTR;
			if (!(port->rs485.flags & SER_RS485_ENABLED))
				port->ops->set_mctrl(port, port->mctrl);
		uart_port_unlock_irqrestore(port, flags);
		}

		uart_rs485_config(port);