summaryrefslogtreecommitdiff
path: root/drivers/tty/serial/8250/8250_omap.c
diff options
context:
space:
mode:
authorJohn Ogness <john.ogness@linutronix.de>2023-05-25 11:37:59 +0206
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-05-30 11:45:42 +0100
commitd0b309a5d3f4648fd4fb1a255a7ae9fb98d87be3 (patch)
tree89d0491d91746e06337ec8e8fc0a1172a7f95494 /drivers/tty/serial/8250/8250_omap.c
parent25614735a647693c1260f253dc3ab32127697806 (diff)
serial: 8250: synchronize and annotate UART_IER access
The UART_IER register is modified twice by each console write (serial8250_console_write()) under the port lock. Any driver code that accesses UART_IER must do so with the port locked in order to ensure consistent values, even when for read accesses. Add locking, lockdep notation, and/or comments everywhere UART_IER is accessed. The added locking is not fixing a real problem because it occurs where the console is not active. However, adding the locking to these non-critical paths greatly simplifies UART_IER access tracking by establishing a general policy that all UART_IER access is performed with the port locked. Signed-off-by: John Ogness <john.ogness@linutronix.de> Link: https://lore.kernel.org/r/20230525093159.223817-9-john.ogness@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/8250/8250_omap.c')
-rw-r--r--drivers/tty/serial/8250/8250_omap.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
index 3225c95fde1d..0498b9b0e4e9 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -533,6 +533,10 @@ static void omap_8250_pm(struct uart_port *port, unsigned int state,
u8 efr;
pm_runtime_get_sync(port->dev);
+
+ /* Synchronize UART_IER access against the console. */
+ spin_lock_irq(&port->lock);
+
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
efr = serial_in(up, UART_EFR);
serial_out(up, UART_EFR, efr | UART_EFR_ECB);
@@ -543,6 +547,8 @@ static void omap_8250_pm(struct uart_port *port, unsigned int state,
serial_out(up, UART_EFR, efr);
serial_out(up, UART_LCR, 0);
+ spin_unlock_irq(&port->lock);
+
pm_runtime_mark_last_busy(port->dev);
pm_runtime_put_autosuspend(port->dev);
}
@@ -760,8 +766,11 @@ static void omap_8250_shutdown(struct uart_port *port)
if (priv->habit & UART_HAS_EFR2)
serial_out(up, UART_OMAP_EFR2, 0x0);
+ /* Synchronize UART_IER access against the console. */
+ spin_lock_irq(&port->lock);
up->ier = 0;
serial_out(up, UART_IER, 0);
+ spin_unlock_irq(&port->lock);
disable_irq_nosync(up->port.irq);
dev_pm_clear_wake_irq(port->dev);
@@ -803,6 +812,7 @@ static void omap_8250_unthrottle(struct uart_port *port)
pm_runtime_get_sync(port->dev);
+ /* Synchronize UART_IER access against the console. */
spin_lock_irqsave(&port->lock, flags);
priv->throttled = false;
if (up->dma)
@@ -953,6 +963,7 @@ static void __dma_rx_complete(void *param)
struct dma_tx_state state;
unsigned long flags;
+ /* Synchronize UART_IER access against the console. */
spin_lock_irqsave(&p->port.lock, flags);
/*
@@ -1227,6 +1238,9 @@ static u16 omap_8250_handle_rx_dma(struct uart_8250_port *up, u8 iir, u16 status
static void am654_8250_handle_rx_dma(struct uart_8250_port *up, u8 iir,
u16 status)
{
+ /* Port locked to synchronize UART_IER access against the console. */
+ lockdep_assert_held_once(&up->port.lock);
+
/*
* Queue a new transfer if FIFO has data.
*/