mirror of
https://github.com/OpenVoiceOS/OpenVoiceOS
synced 2025-02-23 07:07:39 +01:00
378 lines
13 KiB
Diff
378 lines
13 KiB
Diff
From 6f61eb0c15964cb8a36dddebdc2c6a2b95f72faa Mon Sep 17 00:00:00 2001
|
|
From: Thomas Gleixner <tglx@linutronix.de>
|
|
Date: Thu, 14 Sep 2023 20:44:14 +0206
|
|
Subject: [PATCH 083/196] serial: core: Use port lock wrappers
|
|
|
|
When a serial port is used for kernel console output, then all
|
|
modifications to the UART registers which are done from other contexts,
|
|
e.g. getty, termios, are interference points for the kernel console.
|
|
|
|
So far this has been ignored and the printk output is based on the
|
|
principle of hope. The rework of the console infrastructure which aims to
|
|
support threaded and atomic consoles, requires to mark sections which
|
|
modify the UART registers as unsafe. This allows the atomic write function
|
|
to make informed decisions and eventually to restore operational state. It
|
|
also allows to prevent the regular UART code from modifying UART registers
|
|
while printk output is in progress.
|
|
|
|
All modifications of UART registers are guarded by the UART port lock,
|
|
which provides an obvious synchronization point with the console
|
|
infrastructure.
|
|
|
|
To avoid adding this functionality to all UART drivers, wrap the
|
|
spin_[un]lock*() invocations for uart_port::lock into helper functions
|
|
which just contain the spin_[un]lock*() invocations for now. In a
|
|
subsequent step these helpers will gain the console synchronization
|
|
mechanisms.
|
|
|
|
Converted with coccinelle. No functional change.
|
|
|
|
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
|
Signed-off-by: John Ogness <john.ogness@linutronix.de>
|
|
Link: https://lore.kernel.org/r/20230914183831.587273-58-john.ogness@linutronix.de
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
|
---
|
|
drivers/tty/serial/serial_core.c | 92 ++++++++++++++++----------------
|
|
drivers/tty/serial/serial_port.c | 4 +-
|
|
2 files changed, 48 insertions(+), 48 deletions(-)
|
|
|
|
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
|
|
index 2eceef54e0b3..6cd64ccc2035 100644
|
|
--- a/drivers/tty/serial/serial_core.c
|
|
+++ b/drivers/tty/serial/serial_core.c
|
|
@@ -79,7 +79,7 @@ static inline void uart_port_deref(struct uart_port *uport)
|
|
({ \
|
|
struct uart_port *__uport = uart_port_ref(state); \
|
|
if (__uport) \
|
|
- spin_lock_irqsave(&__uport->lock, flags); \
|
|
+ uart_port_lock_irqsave(__uport, &flags); \
|
|
__uport; \
|
|
})
|
|
|
|
@@ -87,7 +87,7 @@ static inline void uart_port_deref(struct uart_port *uport)
|
|
({ \
|
|
struct uart_port *__uport = uport; \
|
|
if (__uport) { \
|
|
- spin_unlock_irqrestore(&__uport->lock, flags); \
|
|
+ uart_port_unlock_irqrestore(__uport, flags); \
|
|
uart_port_deref(__uport); \
|
|
} \
|
|
})
|
|
@@ -179,12 +179,12 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)
|
|
unsigned long flags;
|
|
unsigned int old;
|
|
|
|
- spin_lock_irqsave(&port->lock, flags);
|
|
+ uart_port_lock_irqsave(port, &flags);
|
|
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);
|
|
- spin_unlock_irqrestore(&port->lock, flags);
|
|
+ uart_port_unlock_irqrestore(port, flags);
|
|
}
|
|
|
|
#define uart_set_mctrl(port, set) uart_update_mctrl(port, set, 0)
|
|
@@ -219,7 +219,7 @@ static void uart_change_line_settings(struct tty_struct *tty, struct uart_state
|
|
/*
|
|
* Set modem status enables based on termios cflag
|
|
*/
|
|
- spin_lock_irq(&uport->lock);
|
|
+ uart_port_lock_irq(uport);
|
|
if (termios->c_cflag & CRTSCTS)
|
|
uport->status |= UPSTAT_CTS_ENABLE;
|
|
else
|
|
@@ -240,7 +240,7 @@ static void uart_change_line_settings(struct tty_struct *tty, struct uart_state
|
|
else
|
|
__uart_start(state);
|
|
}
|
|
- spin_unlock_irq(&uport->lock);
|
|
+ uart_port_unlock_irq(uport);
|
|
}
|
|
|
|
/*
|
|
@@ -715,11 +715,11 @@ static void uart_send_xchar(struct tty_struct *tty, char ch)
|
|
if (port->ops->send_xchar)
|
|
port->ops->send_xchar(port, ch);
|
|
else {
|
|
- spin_lock_irqsave(&port->lock, flags);
|
|
+ uart_port_lock_irqsave(port, &flags);
|
|
port->x_char = ch;
|
|
if (ch)
|
|
port->ops->start_tx(port);
|
|
- spin_unlock_irqrestore(&port->lock, flags);
|
|
+ uart_port_unlock_irqrestore(port, flags);
|
|
}
|
|
uart_port_deref(port);
|
|
}
|
|
@@ -1098,9 +1098,9 @@ static int uart_tiocmget(struct tty_struct *tty)
|
|
|
|
if (!tty_io_error(tty)) {
|
|
result = uport->mctrl;
|
|
- spin_lock_irq(&uport->lock);
|
|
+ uart_port_lock_irq(uport);
|
|
result |= uport->ops->get_mctrl(uport);
|
|
- spin_unlock_irq(&uport->lock);
|
|
+ uart_port_unlock_irq(uport);
|
|
}
|
|
out:
|
|
mutex_unlock(&port->mutex);
|
|
@@ -1236,16 +1236,16 @@ static int uart_wait_modem_status(struct uart_state *state, unsigned long arg)
|
|
uport = uart_port_ref(state);
|
|
if (!uport)
|
|
return -EIO;
|
|
- spin_lock_irq(&uport->lock);
|
|
+ uart_port_lock_irq(uport);
|
|
memcpy(&cprev, &uport->icount, sizeof(struct uart_icount));
|
|
uart_enable_ms(uport);
|
|
- spin_unlock_irq(&uport->lock);
|
|
+ uart_port_unlock_irq(uport);
|
|
|
|
add_wait_queue(&port->delta_msr_wait, &wait);
|
|
for (;;) {
|
|
- spin_lock_irq(&uport->lock);
|
|
+ uart_port_lock_irq(uport);
|
|
memcpy(&cnow, &uport->icount, sizeof(struct uart_icount));
|
|
- spin_unlock_irq(&uport->lock);
|
|
+ uart_port_unlock_irq(uport);
|
|
|
|
set_current_state(TASK_INTERRUPTIBLE);
|
|
|
|
@@ -1290,9 +1290,9 @@ static int uart_get_icount(struct tty_struct *tty,
|
|
uport = uart_port_ref(state);
|
|
if (!uport)
|
|
return -EIO;
|
|
- spin_lock_irq(&uport->lock);
|
|
+ uart_port_lock_irq(uport);
|
|
memcpy(&cnow, &uport->icount, sizeof(struct uart_icount));
|
|
- spin_unlock_irq(&uport->lock);
|
|
+ uart_port_unlock_irq(uport);
|
|
uart_port_deref(uport);
|
|
|
|
icount->cts = cnow.cts;
|
|
@@ -1445,9 +1445,9 @@ static int uart_rs485_config(struct uart_port *port)
|
|
uart_set_rs485_termination(port, rs485);
|
|
uart_set_rs485_rx_during_tx(port, rs485);
|
|
|
|
- spin_lock_irqsave(&port->lock, flags);
|
|
+ uart_port_lock_irqsave(port, &flags);
|
|
ret = port->rs485_config(port, NULL, rs485);
|
|
- spin_unlock_irqrestore(&port->lock, flags);
|
|
+ uart_port_unlock_irqrestore(port, flags);
|
|
if (ret) {
|
|
memset(rs485, 0, sizeof(*rs485));
|
|
/* unset GPIOs */
|
|
@@ -1464,9 +1464,9 @@ static int uart_get_rs485_config(struct uart_port *port,
|
|
unsigned long flags;
|
|
struct serial_rs485 aux;
|
|
|
|
- spin_lock_irqsave(&port->lock, flags);
|
|
+ uart_port_lock_irqsave(port, &flags);
|
|
aux = port->rs485;
|
|
- spin_unlock_irqrestore(&port->lock, flags);
|
|
+ uart_port_unlock_irqrestore(port, flags);
|
|
|
|
if (copy_to_user(rs485, &aux, sizeof(aux)))
|
|
return -EFAULT;
|
|
@@ -1494,7 +1494,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);
|
|
|
|
- spin_lock_irqsave(&port->lock, flags);
|
|
+ uart_port_lock_irqsave(port, &flags);
|
|
ret = port->rs485_config(port, &tty->termios, &rs485);
|
|
if (!ret) {
|
|
port->rs485 = rs485;
|
|
@@ -1503,7 +1503,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);
|
|
}
|
|
- spin_unlock_irqrestore(&port->lock, flags);
|
|
+ uart_port_unlock_irqrestore(port, flags);
|
|
if (ret) {
|
|
/* restore old GPIO settings */
|
|
gpiod_set_value_cansleep(port->rs485_term_gpio,
|
|
@@ -1528,9 +1528,9 @@ static int uart_get_iso7816_config(struct uart_port *port,
|
|
if (!port->iso7816_config)
|
|
return -ENOTTY;
|
|
|
|
- spin_lock_irqsave(&port->lock, flags);
|
|
+ uart_port_lock_irqsave(port, &flags);
|
|
aux = port->iso7816;
|
|
- spin_unlock_irqrestore(&port->lock, flags);
|
|
+ uart_port_unlock_irqrestore(port, flags);
|
|
|
|
if (copy_to_user(iso7816, &aux, sizeof(aux)))
|
|
return -EFAULT;
|
|
@@ -1559,9 +1559,9 @@ static int uart_set_iso7816_config(struct uart_port *port,
|
|
if (iso7816.reserved[i])
|
|
return -EINVAL;
|
|
|
|
- spin_lock_irqsave(&port->lock, flags);
|
|
+ uart_port_lock_irqsave(port, &flags);
|
|
ret = port->iso7816_config(port, &iso7816);
|
|
- spin_unlock_irqrestore(&port->lock, flags);
|
|
+ uart_port_unlock_irqrestore(port, flags);
|
|
if (ret)
|
|
return ret;
|
|
|
|
@@ -1778,9 +1778,9 @@ static void uart_tty_port_shutdown(struct tty_port *port)
|
|
if (WARN(!uport, "detached port still initialized!\n"))
|
|
return;
|
|
|
|
- spin_lock_irq(&uport->lock);
|
|
+ uart_port_lock_irq(uport);
|
|
uport->ops->stop_rx(uport);
|
|
- spin_unlock_irq(&uport->lock);
|
|
+ uart_port_unlock_irq(uport);
|
|
|
|
serial_base_port_shutdown(uport);
|
|
uart_port_shutdown(port);
|
|
@@ -1795,11 +1795,11 @@ static void uart_tty_port_shutdown(struct tty_port *port)
|
|
/*
|
|
* Free the transmit buffer.
|
|
*/
|
|
- spin_lock_irq(&uport->lock);
|
|
+ uart_port_lock_irq(uport);
|
|
uart_circ_clear(&state->xmit);
|
|
buf = state->xmit.buf;
|
|
state->xmit.buf = NULL;
|
|
- spin_unlock_irq(&uport->lock);
|
|
+ uart_port_unlock_irq(uport);
|
|
|
|
free_page((unsigned long)buf);
|
|
|
|
@@ -1942,10 +1942,10 @@ static bool uart_carrier_raised(struct tty_port *port)
|
|
*/
|
|
if (WARN_ON(!uport))
|
|
return true;
|
|
- spin_lock_irq(&uport->lock);
|
|
+ uart_port_lock_irq(uport);
|
|
uart_enable_ms(uport);
|
|
mctrl = uport->ops->get_mctrl(uport);
|
|
- spin_unlock_irq(&uport->lock);
|
|
+ uart_port_unlock_irq(uport);
|
|
uart_port_deref(uport);
|
|
|
|
return mctrl & TIOCM_CAR;
|
|
@@ -2062,9 +2062,9 @@ static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i)
|
|
pm_state = state->pm_state;
|
|
if (pm_state != UART_PM_STATE_ON)
|
|
uart_change_pm(state, UART_PM_STATE_ON);
|
|
- spin_lock_irq(&uport->lock);
|
|
+ uart_port_lock_irq(uport);
|
|
status = uport->ops->get_mctrl(uport);
|
|
- spin_unlock_irq(&uport->lock);
|
|
+ uart_port_unlock_irq(uport);
|
|
if (pm_state != UART_PM_STATE_ON)
|
|
uart_change_pm(state, pm_state);
|
|
|
|
@@ -2403,9 +2403,9 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
|
|
*/
|
|
if (!console_suspend_enabled && uart_console(uport)) {
|
|
if (uport->ops->start_rx) {
|
|
- spin_lock_irq(&uport->lock);
|
|
+ uart_port_lock_irq(uport);
|
|
uport->ops->stop_rx(uport);
|
|
- spin_unlock_irq(&uport->lock);
|
|
+ uart_port_unlock_irq(uport);
|
|
}
|
|
goto unlock;
|
|
}
|
|
@@ -2420,7 +2420,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);
|
|
|
|
- spin_lock_irq(&uport->lock);
|
|
+ uart_port_lock_irq(uport);
|
|
ops->stop_tx(uport);
|
|
if (!(uport->rs485.flags & SER_RS485_ENABLED))
|
|
ops->set_mctrl(uport, 0);
|
|
@@ -2428,7 +2428,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
|
|
mctrl = uport->mctrl;
|
|
uport->mctrl = 0;
|
|
ops->stop_rx(uport);
|
|
- spin_unlock_irq(&uport->lock);
|
|
+ uart_port_unlock_irq(uport);
|
|
|
|
/*
|
|
* Wait for the transmitter to empty.
|
|
@@ -2500,9 +2500,9 @@ 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) {
|
|
- spin_lock_irq(&uport->lock);
|
|
+ uart_port_lock_irq(uport);
|
|
uport->ops->start_rx(uport);
|
|
- spin_unlock_irq(&uport->lock);
|
|
+ uart_port_unlock_irq(uport);
|
|
}
|
|
if (console_suspend_enabled)
|
|
console_start(uport->cons);
|
|
@@ -2513,10 +2513,10 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
|
|
int ret;
|
|
|
|
uart_change_pm(state, UART_PM_STATE_ON);
|
|
- spin_lock_irq(&uport->lock);
|
|
+ uart_port_lock_irq(uport);
|
|
if (!(uport->rs485.flags & SER_RS485_ENABLED))
|
|
ops->set_mctrl(uport, 0);
|
|
- spin_unlock_irq(&uport->lock);
|
|
+ uart_port_unlock_irq(uport);
|
|
if (console_suspend_enabled || !uart_console(uport)) {
|
|
/* Protected by port mutex for now */
|
|
struct tty_struct *tty = port->tty;
|
|
@@ -2526,11 +2526,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);
|
|
- spin_lock_irq(&uport->lock);
|
|
+ uart_port_lock_irq(uport);
|
|
if (!(uport->rs485.flags & SER_RS485_ENABLED))
|
|
ops->set_mctrl(uport, uport->mctrl);
|
|
ops->start_tx(uport);
|
|
- spin_unlock_irq(&uport->lock);
|
|
+ uart_port_unlock_irq(uport);
|
|
tty_port_set_initialized(port, true);
|
|
} else {
|
|
/*
|
|
@@ -2642,11 +2642,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
|
|
*/
|
|
- spin_lock_irqsave(&port->lock, flags);
|
|
+ uart_port_lock_irqsave(port, &flags);
|
|
port->mctrl &= TIOCM_DTR;
|
|
if (!(port->rs485.flags & SER_RS485_ENABLED))
|
|
port->ops->set_mctrl(port, port->mctrl);
|
|
- spin_unlock_irqrestore(&port->lock, flags);
|
|
+ uart_port_unlock_irqrestore(port, flags);
|
|
|
|
uart_rs485_config(port);
|
|
|
|
diff --git a/drivers/tty/serial/serial_port.c b/drivers/tty/serial/serial_port.c
|
|
index d622a9297f65..7d51e66ec88b 100644
|
|
--- a/drivers/tty/serial/serial_port.c
|
|
+++ b/drivers/tty/serial/serial_port.c
|
|
@@ -35,14 +35,14 @@ static int serial_port_runtime_resume(struct device *dev)
|
|
goto out;
|
|
|
|
/* Flush any pending TX for the port */
|
|
- spin_lock_irqsave(&port->lock, flags);
|
|
+ uart_port_lock_irqsave(port, &flags);
|
|
if (!port_dev->tx_enabled)
|
|
goto unlock;
|
|
if (__serial_port_busy(port))
|
|
port->ops->start_tx(port);
|
|
|
|
unlock:
|
|
- spin_unlock_irqrestore(&port->lock, flags);
|
|
+ uart_port_unlock_irqrestore(port, flags);
|
|
|
|
out:
|
|
pm_runtime_mark_last_busy(dev);
|
|
--
|
|
2.45.1
|
|
|