Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Thomas Gleixner and committed by
Greg Kroah-Hartman
68ca3e72 01d6461a

+36 -36
+36 -36
drivers/tty/serial/amba-pl011.c
··· 345 345 flag = TTY_FRAME; 346 346 } 347 347 348 - spin_unlock(&uap->port.lock); 348 + uart_port_unlock(&uap->port); 349 349 sysrq = uart_handle_sysrq_char(&uap->port, ch & 255); 350 - spin_lock(&uap->port.lock); 350 + uart_port_lock(&uap->port); 351 351 352 352 if (!sysrq) 353 353 uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag); ··· 550 550 unsigned long flags; 551 551 u16 dmacr; 552 552 553 - spin_lock_irqsave(&uap->port.lock, flags); 553 + uart_port_lock_irqsave(&uap->port, &flags); 554 554 if (uap->dmatx.queued) 555 555 dma_unmap_sg(dmatx->chan->device->dev, &dmatx->sg, 1, 556 556 DMA_TO_DEVICE); ··· 571 571 if (!(dmacr & UART011_TXDMAE) || uart_tx_stopped(&uap->port) || 572 572 uart_circ_empty(&uap->port.state->xmit)) { 573 573 uap->dmatx.queued = false; 574 - spin_unlock_irqrestore(&uap->port.lock, flags); 574 + uart_port_unlock_irqrestore(&uap->port, flags); 575 575 return; 576 576 } 577 577 ··· 582 582 */ 583 583 pl011_start_tx_pio(uap); 584 584 585 - spin_unlock_irqrestore(&uap->port.lock, flags); 585 + uart_port_unlock_irqrestore(&uap->port, flags); 586 586 } 587 587 588 588 /* ··· 1009 1009 * routine to flush out the secondary DMA buffer while 1010 1010 * we immediately trigger the next DMA job. 1011 1011 */ 1012 - spin_lock_irq(&uap->port.lock); 1012 + uart_port_lock_irq(&uap->port); 1013 1013 /* 1014 1014 * Rx data can be taken by the UART interrupts during 1015 1015 * the DMA irq handler. So we check the residue here. ··· 1025 1025 ret = pl011_dma_rx_trigger_dma(uap); 1026 1026 1027 1027 pl011_dma_rx_chars(uap, pending, lastbuf, false); 1028 - spin_unlock_irq(&uap->port.lock); 1028 + uart_port_unlock_irq(&uap->port); 1029 1029 /* 1030 1030 * Do this check after we picked the DMA chars so we don't 1031 1031 * get some IRQ immediately from RX. ··· 1091 1091 if (jiffies_to_msecs(jiffies - dmarx->last_jiffies) 1092 1092 > uap->dmarx.poll_timeout) { 1093 1093 1094 - spin_lock_irqsave(&uap->port.lock, flags); 1094 + uart_port_lock_irqsave(&uap->port, &flags); 1095 1095 pl011_dma_rx_stop(uap); 1096 1096 uap->im |= UART011_RXIM; 1097 1097 pl011_write(uap->im, uap, REG_IMSC); 1098 - spin_unlock_irqrestore(&uap->port.lock, flags); 1098 + uart_port_unlock_irqrestore(&uap->port, flags); 1099 1099 1100 1100 uap->dmarx.running = false; 1101 1101 dmaengine_terminate_all(rxchan); ··· 1191 1191 while (pl011_read(uap, REG_FR) & uap->vendor->fr_busy) 1192 1192 cpu_relax(); 1193 1193 1194 - spin_lock_irq(&uap->port.lock); 1194 + uart_port_lock_irq(&uap->port); 1195 1195 uap->dmacr &= ~(UART011_DMAONERR | UART011_RXDMAE | UART011_TXDMAE); 1196 1196 pl011_write(uap->dmacr, uap, REG_DMACR); 1197 - spin_unlock_irq(&uap->port.lock); 1197 + uart_port_unlock_irq(&uap->port); 1198 1198 1199 1199 if (uap->using_tx_dma) { 1200 1200 /* In theory, this should already be done by pl011_dma_flush_buffer */ ··· 1374 1374 { 1375 1375 unsigned long flags; 1376 1376 1377 - spin_lock_irqsave(&port->lock, flags); 1377 + uart_port_lock_irqsave(port, &flags); 1378 1378 pl011_stop_rx(port); 1379 - spin_unlock_irqrestore(&port->lock, flags); 1379 + uart_port_unlock_irqrestore(port, flags); 1380 1380 } 1381 1381 1382 1382 static void pl011_enable_ms(struct uart_port *port) ··· 1394 1394 { 1395 1395 pl011_fifo_to_tty(uap); 1396 1396 1397 - spin_unlock(&uap->port.lock); 1397 + uart_port_unlock(&uap->port); 1398 1398 tty_flip_buffer_push(&uap->port.state->port); 1399 1399 /* 1400 1400 * If we were temporarily out of DMA mode for a while, ··· 1419 1419 #endif 1420 1420 } 1421 1421 } 1422 - spin_lock(&uap->port.lock); 1422 + uart_port_lock(&uap->port); 1423 1423 } 1424 1424 1425 1425 static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c, ··· 1555 1555 unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT; 1556 1556 int handled = 0; 1557 1557 1558 - spin_lock_irqsave(&uap->port.lock, flags); 1558 + uart_port_lock_irqsave(&uap->port, &flags); 1559 1559 status = pl011_read(uap, REG_RIS) & uap->im; 1560 1560 if (status) { 1561 1561 do { ··· 1585 1585 handled = 1; 1586 1586 } 1587 1587 1588 - spin_unlock_irqrestore(&uap->port.lock, flags); 1588 + uart_port_unlock_irqrestore(&uap->port, flags); 1589 1589 1590 1590 return IRQ_RETVAL(handled); 1591 1591 } ··· 1657 1657 unsigned long flags; 1658 1658 unsigned int lcr_h; 1659 1659 1660 - spin_lock_irqsave(&uap->port.lock, flags); 1660 + uart_port_lock_irqsave(&uap->port, &flags); 1661 1661 lcr_h = pl011_read(uap, REG_LCRH_TX); 1662 1662 if (break_state == -1) 1663 1663 lcr_h |= UART01x_LCRH_BRK; 1664 1664 else 1665 1665 lcr_h &= ~UART01x_LCRH_BRK; 1666 1666 pl011_write(lcr_h, uap, REG_LCRH_TX); 1667 - spin_unlock_irqrestore(&uap->port.lock, flags); 1667 + uart_port_unlock_irqrestore(&uap->port, flags); 1668 1668 } 1669 1669 1670 1670 #ifdef CONFIG_CONSOLE_POLL ··· 1803 1803 unsigned long flags; 1804 1804 unsigned int i; 1805 1805 1806 - spin_lock_irqsave(&uap->port.lock, flags); 1806 + uart_port_lock_irqsave(&uap->port, &flags); 1807 1807 1808 1808 /* Clear out any spuriously appearing RX interrupts */ 1809 1809 pl011_write(UART011_RTIS | UART011_RXIS, uap, REG_ICR); ··· 1825 1825 if (!pl011_dma_rx_running(uap)) 1826 1826 uap->im |= UART011_RXIM; 1827 1827 pl011_write(uap->im, uap, REG_IMSC); 1828 - spin_unlock_irqrestore(&uap->port.lock, flags); 1828 + uart_port_unlock_irqrestore(&uap->port, flags); 1829 1829 } 1830 1830 1831 1831 static void pl011_unthrottle_rx(struct uart_port *port) ··· 1833 1833 struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port); 1834 1834 unsigned long flags; 1835 1835 1836 - spin_lock_irqsave(&uap->port.lock, flags); 1836 + uart_port_lock_irqsave(&uap->port, &flags); 1837 1837 1838 1838 uap->im = UART011_RTIM; 1839 1839 if (!pl011_dma_rx_running(uap)) ··· 1841 1841 1842 1842 pl011_write(uap->im, uap, REG_IMSC); 1843 1843 1844 - spin_unlock_irqrestore(&uap->port.lock, flags); 1844 + uart_port_unlock_irqrestore(&uap->port, flags); 1845 1845 } 1846 1846 1847 1847 static int pl011_startup(struct uart_port *port) ··· 1861 1861 1862 1862 pl011_write(uap->vendor->ifls, uap, REG_IFLS); 1863 1863 1864 - spin_lock_irq(&uap->port.lock); 1864 + uart_port_lock_irq(&uap->port); 1865 1865 1866 1866 cr = pl011_read(uap, REG_CR); 1867 1867 cr &= UART011_CR_RTS | UART011_CR_DTR; ··· 1872 1872 1873 1873 pl011_write(cr, uap, REG_CR); 1874 1874 1875 - spin_unlock_irq(&uap->port.lock); 1875 + uart_port_unlock_irq(&uap->port); 1876 1876 1877 1877 /* 1878 1878 * initialise the old status of the modem signals ··· 1933 1933 unsigned int cr; 1934 1934 1935 1935 uap->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS); 1936 - spin_lock_irq(&uap->port.lock); 1936 + uart_port_lock_irq(&uap->port); 1937 1937 cr = pl011_read(uap, REG_CR); 1938 1938 cr &= UART011_CR_RTS | UART011_CR_DTR; 1939 1939 cr |= UART01x_CR_UARTEN | UART011_CR_TXE; 1940 1940 pl011_write(cr, uap, REG_CR); 1941 - spin_unlock_irq(&uap->port.lock); 1941 + uart_port_unlock_irq(&uap->port); 1942 1942 1943 1943 /* 1944 1944 * disable break condition and fifos ··· 1950 1950 1951 1951 static void pl011_disable_interrupts(struct uart_amba_port *uap) 1952 1952 { 1953 - spin_lock_irq(&uap->port.lock); 1953 + uart_port_lock_irq(&uap->port); 1954 1954 1955 1955 /* mask all interrupts and clear all pending ones */ 1956 1956 uap->im = 0; 1957 1957 pl011_write(uap->im, uap, REG_IMSC); 1958 1958 pl011_write(0xffff, uap, REG_ICR); 1959 1959 1960 - spin_unlock_irq(&uap->port.lock); 1960 + uart_port_unlock_irq(&uap->port); 1961 1961 } 1962 1962 1963 1963 static void pl011_shutdown(struct uart_port *port) ··· 2102 2102 2103 2103 bits = tty_get_frame_size(termios->c_cflag); 2104 2104 2105 - spin_lock_irqsave(&port->lock, flags); 2105 + uart_port_lock_irqsave(port, &flags); 2106 2106 2107 2107 /* 2108 2108 * Update the per-port timeout. ··· 2176 2176 old_cr |= UART011_CR_RXE; 2177 2177 pl011_write(old_cr, uap, REG_CR); 2178 2178 2179 - spin_unlock_irqrestore(&port->lock, flags); 2179 + uart_port_unlock_irqrestore(port, flags); 2180 2180 } 2181 2181 2182 2182 static void ··· 2194 2194 termios->c_cflag &= ~(CMSPAR | CRTSCTS); 2195 2195 termios->c_cflag |= CS8 | CLOCAL; 2196 2196 2197 - spin_lock_irqsave(&port->lock, flags); 2197 + uart_port_lock_irqsave(port, &flags); 2198 2198 uart_update_timeout(port, CS8, uap->fixed_baud); 2199 2199 pl011_setup_status_masks(port, termios); 2200 - spin_unlock_irqrestore(&port->lock, flags); 2200 + uart_port_unlock_irqrestore(port, flags); 2201 2201 } 2202 2202 2203 2203 static const char *pl011_type(struct uart_port *port) ··· 2336 2336 if (uap->port.sysrq) 2337 2337 locked = 0; 2338 2338 else if (oops_in_progress) 2339 - locked = spin_trylock(&uap->port.lock); 2339 + locked = uart_port_trylock(&uap->port); 2340 2340 else 2341 - spin_lock(&uap->port.lock); 2341 + uart_port_lock(&uap->port); 2342 2342 2343 2343 /* 2344 2344 * First save the CR then disable the interrupts ··· 2364 2364 pl011_write(old_cr, uap, REG_CR); 2365 2365 2366 2366 if (locked) 2367 - spin_unlock(&uap->port.lock); 2367 + uart_port_unlock(&uap->port); 2368 2368 local_irq_restore(flags); 2369 2369 2370 2370 clk_disable(uap->clk);