mirror of
https://github.com/OpenVoiceOS/OpenVoiceOS
synced 2025-02-23 15:17:39 +01:00
333 lines
11 KiB
Diff
333 lines
11 KiB
Diff
From 7ee23cef36f815349c95b29497c35bda97eba2c4 Mon Sep 17 00:00:00 2001
|
|
From: Thomas Gleixner <tglx@linutronix.de>
|
|
Date: Thu, 14 Sep 2023 20:43:34 +0206
|
|
Subject: [PATCH 043/196] serial: amba-pl011: 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-18-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/amba-pl011.c | 72 ++++++++++++++++-----------------
|
|
1 file changed, 36 insertions(+), 36 deletions(-)
|
|
|
|
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
|
|
index 362bbcdece0d..16c770311069 100644
|
|
--- a/drivers/tty/serial/amba-pl011.c
|
|
+++ b/drivers/tty/serial/amba-pl011.c
|
|
@@ -347,9 +347,9 @@ static int pl011_fifo_to_tty(struct uart_amba_port *uap)
|
|
flag = TTY_FRAME;
|
|
}
|
|
|
|
- spin_unlock(&uap->port.lock);
|
|
+ uart_port_unlock(&uap->port);
|
|
sysrq = uart_handle_sysrq_char(&uap->port, ch & 255);
|
|
- spin_lock(&uap->port.lock);
|
|
+ uart_port_lock(&uap->port);
|
|
|
|
if (!sysrq)
|
|
uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag);
|
|
@@ -544,7 +544,7 @@ static void pl011_dma_tx_callback(void *data)
|
|
unsigned long flags;
|
|
u16 dmacr;
|
|
|
|
- spin_lock_irqsave(&uap->port.lock, flags);
|
|
+ uart_port_lock_irqsave(&uap->port, &flags);
|
|
if (uap->dmatx.queued)
|
|
dma_unmap_single(dmatx->chan->device->dev, dmatx->dma,
|
|
dmatx->len, DMA_TO_DEVICE);
|
|
@@ -565,7 +565,7 @@ static void pl011_dma_tx_callback(void *data)
|
|
if (!(dmacr & UART011_TXDMAE) || uart_tx_stopped(&uap->port) ||
|
|
uart_circ_empty(&uap->port.state->xmit)) {
|
|
uap->dmatx.queued = false;
|
|
- spin_unlock_irqrestore(&uap->port.lock, flags);
|
|
+ uart_port_unlock_irqrestore(&uap->port, flags);
|
|
return;
|
|
}
|
|
|
|
@@ -576,7 +576,7 @@ static void pl011_dma_tx_callback(void *data)
|
|
*/
|
|
pl011_start_tx_pio(uap);
|
|
|
|
- spin_unlock_irqrestore(&uap->port.lock, flags);
|
|
+ uart_port_unlock_irqrestore(&uap->port, flags);
|
|
}
|
|
|
|
/*
|
|
@@ -1004,7 +1004,7 @@ static void pl011_dma_rx_callback(void *data)
|
|
* routine to flush out the secondary DMA buffer while
|
|
* we immediately trigger the next DMA job.
|
|
*/
|
|
- spin_lock_irq(&uap->port.lock);
|
|
+ uart_port_lock_irq(&uap->port);
|
|
/*
|
|
* Rx data can be taken by the UART interrupts during
|
|
* the DMA irq handler. So we check the residue here.
|
|
@@ -1020,7 +1020,7 @@ static void pl011_dma_rx_callback(void *data)
|
|
ret = pl011_dma_rx_trigger_dma(uap);
|
|
|
|
pl011_dma_rx_chars(uap, pending, lastbuf, false);
|
|
- spin_unlock_irq(&uap->port.lock);
|
|
+ uart_port_unlock_irq(&uap->port);
|
|
/*
|
|
* Do this check after we picked the DMA chars so we don't
|
|
* get some IRQ immediately from RX.
|
|
@@ -1086,11 +1086,11 @@ static void pl011_dma_rx_poll(struct timer_list *t)
|
|
if (jiffies_to_msecs(jiffies - dmarx->last_jiffies)
|
|
> uap->dmarx.poll_timeout) {
|
|
|
|
- spin_lock_irqsave(&uap->port.lock, flags);
|
|
+ uart_port_lock_irqsave(&uap->port, &flags);
|
|
pl011_dma_rx_stop(uap);
|
|
uap->im |= UART011_RXIM;
|
|
pl011_write(uap->im, uap, REG_IMSC);
|
|
- spin_unlock_irqrestore(&uap->port.lock, flags);
|
|
+ uart_port_unlock_irqrestore(&uap->port, flags);
|
|
|
|
uap->dmarx.running = false;
|
|
dmaengine_terminate_all(rxchan);
|
|
@@ -1186,10 +1186,10 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap)
|
|
while (pl011_read(uap, REG_FR) & uap->vendor->fr_busy)
|
|
cpu_relax();
|
|
|
|
- spin_lock_irq(&uap->port.lock);
|
|
+ uart_port_lock_irq(&uap->port);
|
|
uap->dmacr &= ~(UART011_DMAONERR | UART011_RXDMAE | UART011_TXDMAE);
|
|
pl011_write(uap->dmacr, uap, REG_DMACR);
|
|
- spin_unlock_irq(&uap->port.lock);
|
|
+ uart_port_unlock_irq(&uap->port);
|
|
|
|
if (uap->using_tx_dma) {
|
|
/* In theory, this should already be done by pl011_dma_flush_buffer */
|
|
@@ -1400,9 +1400,9 @@ static void pl011_throttle_rx(struct uart_port *port)
|
|
{
|
|
unsigned long flags;
|
|
|
|
- spin_lock_irqsave(&port->lock, flags);
|
|
+ uart_port_lock_irqsave(port, &flags);
|
|
pl011_stop_rx(port);
|
|
- spin_unlock_irqrestore(&port->lock, flags);
|
|
+ uart_port_unlock_irqrestore(port, flags);
|
|
}
|
|
|
|
static void pl011_enable_ms(struct uart_port *port)
|
|
@@ -1420,7 +1420,7 @@ __acquires(&uap->port.lock)
|
|
{
|
|
pl011_fifo_to_tty(uap);
|
|
|
|
- spin_unlock(&uap->port.lock);
|
|
+ uart_port_unlock(&uap->port);
|
|
tty_flip_buffer_push(&uap->port.state->port);
|
|
/*
|
|
* If we were temporarily out of DMA mode for a while,
|
|
@@ -1445,7 +1445,7 @@ __acquires(&uap->port.lock)
|
|
#endif
|
|
}
|
|
}
|
|
- spin_lock(&uap->port.lock);
|
|
+ uart_port_lock(&uap->port);
|
|
}
|
|
|
|
static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c,
|
|
@@ -1551,7 +1551,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
|
|
unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
|
|
int handled = 0;
|
|
|
|
- spin_lock_irqsave(&uap->port.lock, flags);
|
|
+ uart_port_lock_irqsave(&uap->port, &flags);
|
|
status = pl011_read(uap, REG_RIS) & uap->im;
|
|
if (status) {
|
|
do {
|
|
@@ -1581,7 +1581,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
|
|
handled = 1;
|
|
}
|
|
|
|
- spin_unlock_irqrestore(&uap->port.lock, flags);
|
|
+ uart_port_unlock_irqrestore(&uap->port, flags);
|
|
|
|
return IRQ_RETVAL(handled);
|
|
}
|
|
@@ -1653,14 +1653,14 @@ static void pl011_break_ctl(struct uart_port *port, int break_state)
|
|
unsigned long flags;
|
|
unsigned int lcr_h;
|
|
|
|
- spin_lock_irqsave(&uap->port.lock, flags);
|
|
+ uart_port_lock_irqsave(&uap->port, &flags);
|
|
lcr_h = pl011_read(uap, REG_LCRH_TX);
|
|
if (break_state == -1)
|
|
lcr_h |= UART01x_LCRH_BRK;
|
|
else
|
|
lcr_h &= ~UART01x_LCRH_BRK;
|
|
pl011_write(lcr_h, uap, REG_LCRH_TX);
|
|
- spin_unlock_irqrestore(&uap->port.lock, flags);
|
|
+ uart_port_unlock_irqrestore(&uap->port, flags);
|
|
}
|
|
|
|
#ifdef CONFIG_CONSOLE_POLL
|
|
@@ -1799,7 +1799,7 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap)
|
|
unsigned long flags;
|
|
unsigned int i;
|
|
|
|
- spin_lock_irqsave(&uap->port.lock, flags);
|
|
+ uart_port_lock_irqsave(&uap->port, &flags);
|
|
|
|
/* Clear out any spuriously appearing RX interrupts */
|
|
pl011_write(UART011_RTIS | UART011_RXIS, uap, REG_ICR);
|
|
@@ -1821,7 +1821,7 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap)
|
|
if (!pl011_dma_rx_running(uap))
|
|
uap->im |= UART011_RXIM;
|
|
pl011_write(uap->im, uap, REG_IMSC);
|
|
- spin_unlock_irqrestore(&uap->port.lock, flags);
|
|
+ uart_port_unlock_irqrestore(&uap->port, flags);
|
|
}
|
|
|
|
static void pl011_unthrottle_rx(struct uart_port *port)
|
|
@@ -1829,7 +1829,7 @@ static void pl011_unthrottle_rx(struct uart_port *port)
|
|
struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port);
|
|
unsigned long flags;
|
|
|
|
- spin_lock_irqsave(&uap->port.lock, flags);
|
|
+ uart_port_lock_irqsave(&uap->port, &flags);
|
|
|
|
uap->im = UART011_RTIM;
|
|
if (!pl011_dma_rx_running(uap))
|
|
@@ -1837,7 +1837,7 @@ static void pl011_unthrottle_rx(struct uart_port *port)
|
|
|
|
pl011_write(uap->im, uap, REG_IMSC);
|
|
|
|
- spin_unlock_irqrestore(&uap->port.lock, flags);
|
|
+ uart_port_unlock_irqrestore(&uap->port, flags);
|
|
}
|
|
|
|
static int pl011_startup(struct uart_port *port)
|
|
@@ -1857,7 +1857,7 @@ static int pl011_startup(struct uart_port *port)
|
|
|
|
pl011_write(uap->vendor->ifls, uap, REG_IFLS);
|
|
|
|
- spin_lock_irq(&uap->port.lock);
|
|
+ uart_port_lock_irq(&uap->port);
|
|
|
|
cr = pl011_read(uap, REG_CR);
|
|
cr &= UART011_CR_RTS | UART011_CR_DTR;
|
|
@@ -1868,7 +1868,7 @@ static int pl011_startup(struct uart_port *port)
|
|
|
|
pl011_write(cr, uap, REG_CR);
|
|
|
|
- spin_unlock_irq(&uap->port.lock);
|
|
+ uart_port_unlock_irq(&uap->port);
|
|
|
|
/*
|
|
* initialise the old status of the modem signals
|
|
@@ -1929,12 +1929,12 @@ static void pl011_disable_uart(struct uart_amba_port *uap)
|
|
unsigned int cr;
|
|
|
|
uap->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS);
|
|
- spin_lock_irq(&uap->port.lock);
|
|
+ uart_port_lock_irq(&uap->port);
|
|
cr = pl011_read(uap, REG_CR);
|
|
cr &= UART011_CR_RTS | UART011_CR_DTR;
|
|
cr |= UART01x_CR_UARTEN | UART011_CR_TXE;
|
|
pl011_write(cr, uap, REG_CR);
|
|
- spin_unlock_irq(&uap->port.lock);
|
|
+ uart_port_unlock_irq(&uap->port);
|
|
|
|
/*
|
|
* disable break condition and fifos
|
|
@@ -1946,14 +1946,14 @@ static void pl011_disable_uart(struct uart_amba_port *uap)
|
|
|
|
static void pl011_disable_interrupts(struct uart_amba_port *uap)
|
|
{
|
|
- spin_lock_irq(&uap->port.lock);
|
|
+ uart_port_lock_irq(&uap->port);
|
|
|
|
/* mask all interrupts and clear all pending ones */
|
|
uap->im = 0;
|
|
pl011_write(uap->im, uap, REG_IMSC);
|
|
pl011_write(0xffff, uap, REG_ICR);
|
|
|
|
- spin_unlock_irq(&uap->port.lock);
|
|
+ uart_port_unlock_irq(&uap->port);
|
|
}
|
|
|
|
static void pl011_shutdown(struct uart_port *port)
|
|
@@ -2098,7 +2098,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
|
|
|
|
bits = tty_get_frame_size(termios->c_cflag);
|
|
|
|
- spin_lock_irqsave(&port->lock, flags);
|
|
+ uart_port_lock_irqsave(port, &flags);
|
|
|
|
/*
|
|
* Update the per-port timeout.
|
|
@@ -2172,7 +2172,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
|
|
old_cr |= UART011_CR_RXE;
|
|
pl011_write(old_cr, uap, REG_CR);
|
|
|
|
- spin_unlock_irqrestore(&port->lock, flags);
|
|
+ uart_port_unlock_irqrestore(port, flags);
|
|
}
|
|
|
|
static void
|
|
@@ -2190,10 +2190,10 @@ sbsa_uart_set_termios(struct uart_port *port, struct ktermios *termios,
|
|
termios->c_cflag &= ~(CMSPAR | CRTSCTS);
|
|
termios->c_cflag |= CS8 | CLOCAL;
|
|
|
|
- spin_lock_irqsave(&port->lock, flags);
|
|
+ uart_port_lock_irqsave(port, &flags);
|
|
uart_update_timeout(port, CS8, uap->fixed_baud);
|
|
pl011_setup_status_masks(port, termios);
|
|
- spin_unlock_irqrestore(&port->lock, flags);
|
|
+ uart_port_unlock_irqrestore(port, flags);
|
|
}
|
|
|
|
static const char *pl011_type(struct uart_port *port)
|
|
@@ -2332,9 +2332,9 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
|
|
if (uap->port.sysrq)
|
|
locked = 0;
|
|
else if (oops_in_progress)
|
|
- locked = spin_trylock(&uap->port.lock);
|
|
+ locked = uart_port_trylock(&uap->port);
|
|
else
|
|
- spin_lock(&uap->port.lock);
|
|
+ uart_port_lock(&uap->port);
|
|
|
|
/*
|
|
* First save the CR then disable the interrupts
|
|
@@ -2360,7 +2360,7 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
|
|
pl011_write(old_cr, uap, REG_CR);
|
|
|
|
if (locked)
|
|
- spin_unlock(&uap->port.lock);
|
|
+ uart_port_unlock(&uap->port);
|
|
local_irq_restore(flags);
|
|
|
|
clk_disable(uap->clk);
|
|
--
|
|
2.45.1
|
|
|