diff options
Diffstat (limited to 'debian/patches-rt/0017-serial-amba-pl011-Use-port-lock-wrappers.patch')
-rw-r--r-- | debian/patches-rt/0017-serial-amba-pl011-Use-port-lock-wrappers.patch | 327 |
1 files changed, 327 insertions, 0 deletions
diff --git a/debian/patches-rt/0017-serial-amba-pl011-Use-port-lock-wrappers.patch b/debian/patches-rt/0017-serial-amba-pl011-Use-port-lock-wrappers.patch new file mode 100644 index 0000000000..2a5e3a85ea --- /dev/null +++ b/debian/patches-rt/0017-serial-amba-pl011-Use-port-lock-wrappers.patch @@ -0,0 +1,327 @@ +From: Thomas Gleixner <tglx@linutronix.de> +Date: Thu, 14 Sep 2023 20:43:34 +0206 +Subject: [PATCH 017/134] serial: amba-pl011: Use port lock wrappers +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.6/older/patches-6.6.7-rt18.tar.xz + +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(-) + +--- 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 + 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 * + 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 * + 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 * + */ + 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 * + * 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 * + 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 tim + 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 ua + 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 */ +@@ -1370,9 +1370,9 @@ static void pl011_throttle_rx(struct uar + { + 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) +@@ -1390,7 +1390,7 @@ static void pl011_rx_chars(struct uart_a + { + 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, +@@ -1415,7 +1415,7 @@ static void pl011_rx_chars(struct uart_a + #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, vo + 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, vo + 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_ + 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(stru + 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(stru + 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 u + 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 u + + 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_por + + 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_por + + 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 ua + 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 ua + + 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 + + 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 + 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 * + 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, + 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, + 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); |