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

serial: fsl_lpuart: 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-28-john.ogness@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Thomas Gleixner and committed by
Greg Kroah-Hartman
92f4e05b 7c6725ff

+44 -44
+44 -44
drivers/tty/serial/fsl_lpuart.c
··· 532 532 struct dma_chan *chan = sport->dma_tx_chan; 533 533 unsigned long flags; 534 534 535 - spin_lock_irqsave(&sport->port.lock, flags); 535 + uart_port_lock_irqsave(&sport->port, &flags); 536 536 if (!sport->dma_tx_in_progress) { 537 - spin_unlock_irqrestore(&sport->port.lock, flags); 537 + uart_port_unlock_irqrestore(&sport->port, flags); 538 538 return; 539 539 } 540 540 ··· 543 543 544 544 uart_xmit_advance(&sport->port, sport->dma_tx_bytes); 545 545 sport->dma_tx_in_progress = false; 546 - spin_unlock_irqrestore(&sport->port.lock, flags); 546 + uart_port_unlock_irqrestore(&sport->port, flags); 547 547 548 548 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 549 549 uart_write_wakeup(&sport->port); ··· 553 553 return; 554 554 } 555 555 556 - spin_lock_irqsave(&sport->port.lock, flags); 556 + uart_port_lock_irqsave(&sport->port, &flags); 557 557 558 558 if (!lpuart_stopped_or_empty(&sport->port)) 559 559 lpuart_dma_tx(sport); 560 560 561 - spin_unlock_irqrestore(&sport->port.lock, flags); 561 + uart_port_unlock_irqrestore(&sport->port, flags); 562 562 } 563 563 564 564 static dma_addr_t lpuart_dma_datareg_addr(struct lpuart_port *sport) ··· 651 651 652 652 sport->port.fifosize = 0; 653 653 654 - spin_lock_irqsave(&sport->port.lock, flags); 654 + uart_port_lock_irqsave(&sport->port, &flags); 655 655 /* Disable Rx & Tx */ 656 656 writeb(0, sport->port.membase + UARTCR2); 657 657 ··· 675 675 676 676 /* Enable Rx and Tx */ 677 677 writeb(UARTCR2_RE | UARTCR2_TE, sport->port.membase + UARTCR2); 678 - spin_unlock_irqrestore(&sport->port.lock, flags); 678 + uart_port_unlock_irqrestore(&sport->port, flags); 679 679 680 680 return 0; 681 681 } ··· 703 703 704 704 sport->port.fifosize = 0; 705 705 706 - spin_lock_irqsave(&sport->port.lock, flags); 706 + uart_port_lock_irqsave(&sport->port, &flags); 707 707 708 708 /* Disable Rx & Tx */ 709 709 lpuart32_write(&sport->port, 0, UARTCTRL); ··· 724 724 725 725 /* Enable Rx and Tx */ 726 726 lpuart32_write(&sport->port, UARTCTRL_RE | UARTCTRL_TE, UARTCTRL); 727 - spin_unlock_irqrestore(&sport->port.lock, flags); 727 + uart_port_unlock_irqrestore(&sport->port, flags); 728 728 729 729 return 0; 730 730 } ··· 879 879 880 880 static void lpuart_txint(struct lpuart_port *sport) 881 881 { 882 - spin_lock(&sport->port.lock); 882 + uart_port_lock(&sport->port); 883 883 lpuart_transmit_buffer(sport); 884 - spin_unlock(&sport->port.lock); 884 + uart_port_unlock(&sport->port); 885 885 } 886 886 887 887 static void lpuart_rxint(struct lpuart_port *sport) ··· 890 890 struct tty_port *port = &sport->port.state->port; 891 891 unsigned char rx, sr; 892 892 893 - spin_lock(&sport->port.lock); 893 + uart_port_lock(&sport->port); 894 894 895 895 while (!(readb(sport->port.membase + UARTSFIFO) & UARTSFIFO_RXEMPT)) { 896 896 flg = TTY_NORMAL; ··· 956 956 957 957 static void lpuart32_txint(struct lpuart_port *sport) 958 958 { 959 - spin_lock(&sport->port.lock); 959 + uart_port_lock(&sport->port); 960 960 lpuart32_transmit_buffer(sport); 961 - spin_unlock(&sport->port.lock); 961 + uart_port_unlock(&sport->port); 962 962 } 963 963 964 964 static void lpuart32_rxint(struct lpuart_port *sport) ··· 968 968 unsigned long rx, sr; 969 969 bool is_break; 970 970 971 - spin_lock(&sport->port.lock); 971 + uart_port_lock(&sport->port); 972 972 973 973 while (!(lpuart32_read(&sport->port, UARTFIFO) & UARTFIFO_RXEMPT)) { 974 974 flg = TTY_NORMAL; ··· 1170 1170 1171 1171 async_tx_ack(sport->dma_rx_desc); 1172 1172 1173 - spin_lock_irqsave(&sport->port.lock, flags); 1173 + uart_port_lock_irqsave(&sport->port, &flags); 1174 1174 1175 1175 dmastat = dmaengine_tx_status(chan, sport->dma_rx_cookie, &state); 1176 1176 if (dmastat == DMA_ERROR) { 1177 1177 dev_err(sport->port.dev, "Rx DMA transfer failed!\n"); 1178 - spin_unlock_irqrestore(&sport->port.lock, flags); 1178 + uart_port_unlock_irqrestore(&sport->port, flags); 1179 1179 return; 1180 1180 } 1181 1181 ··· 1244 1244 dma_sync_sg_for_device(chan->device->dev, &sport->rx_sgl, 1, 1245 1245 DMA_FROM_DEVICE); 1246 1246 1247 - spin_unlock_irqrestore(&sport->port.lock, flags); 1247 + uart_port_unlock_irqrestore(&sport->port, flags); 1248 1248 1249 1249 tty_flip_buffer_push(port); 1250 1250 if (!sport->dma_idle_int) ··· 1335 1335 mod_timer(&sport->lpuart_timer, 1336 1336 jiffies + sport->dma_rx_timeout); 1337 1337 1338 - if (spin_trylock_irqsave(&sport->port.lock, flags)) { 1338 + if (uart_port_trylock_irqsave(&sport->port, &flags)) { 1339 1339 sport->last_residue = state.residue; 1340 - spin_unlock_irqrestore(&sport->port.lock, flags); 1340 + uart_port_unlock_irqrestore(&sport->port, flags); 1341 1341 } 1342 1342 } 1343 1343 ··· 1802 1802 { 1803 1803 unsigned long flags; 1804 1804 1805 - spin_lock_irqsave(&sport->port.lock, flags); 1805 + uart_port_lock_irqsave(&sport->port, &flags); 1806 1806 1807 1807 lpuart_setup_watermark_enable(sport); 1808 1808 1809 1809 lpuart_rx_dma_startup(sport); 1810 1810 lpuart_tx_dma_startup(sport); 1811 1811 1812 - spin_unlock_irqrestore(&sport->port.lock, flags); 1812 + uart_port_unlock_irqrestore(&sport->port, flags); 1813 1813 } 1814 1814 1815 1815 static int lpuart_startup(struct uart_port *port) ··· 1859 1859 { 1860 1860 unsigned long flags; 1861 1861 1862 - spin_lock_irqsave(&sport->port.lock, flags); 1862 + uart_port_lock_irqsave(&sport->port, &flags); 1863 1863 1864 1864 lpuart32_hw_disable(sport); 1865 1865 ··· 1869 1869 lpuart32_setup_watermark_enable(sport); 1870 1870 lpuart32_configure(sport); 1871 1871 1872 - spin_unlock_irqrestore(&sport->port.lock, flags); 1872 + uart_port_unlock_irqrestore(&sport->port, flags); 1873 1873 } 1874 1874 1875 1875 static int lpuart32_startup(struct uart_port *port) ··· 1932 1932 unsigned char temp; 1933 1933 unsigned long flags; 1934 1934 1935 - spin_lock_irqsave(&port->lock, flags); 1935 + uart_port_lock_irqsave(port, &flags); 1936 1936 1937 1937 /* disable Rx/Tx and interrupts */ 1938 1938 temp = readb(port->membase + UARTCR2); ··· 1940 1940 UARTCR2_TIE | UARTCR2_TCIE | UARTCR2_RIE); 1941 1941 writeb(temp, port->membase + UARTCR2); 1942 1942 1943 - spin_unlock_irqrestore(&port->lock, flags); 1943 + uart_port_unlock_irqrestore(port, flags); 1944 1944 1945 1945 lpuart_dma_shutdown(sport); 1946 1946 } ··· 1952 1952 unsigned long temp; 1953 1953 unsigned long flags; 1954 1954 1955 - spin_lock_irqsave(&port->lock, flags); 1955 + uart_port_lock_irqsave(port, &flags); 1956 1956 1957 1957 /* clear status */ 1958 1958 temp = lpuart32_read(&sport->port, UARTSTAT); ··· 1969 1969 UARTCTRL_TIE | UARTCTRL_TCIE | UARTCTRL_RIE | UARTCTRL_SBK); 1970 1970 lpuart32_write(port, temp, UARTCTRL); 1971 1971 1972 - spin_unlock_irqrestore(&port->lock, flags); 1972 + uart_port_unlock_irqrestore(port, flags); 1973 1973 1974 1974 lpuart_dma_shutdown(sport); 1975 1975 } ··· 2069 2069 if (old && sport->lpuart_dma_rx_use) 2070 2070 lpuart_dma_rx_free(&sport->port); 2071 2071 2072 - spin_lock_irqsave(&sport->port.lock, flags); 2072 + uart_port_lock_irqsave(&sport->port, &flags); 2073 2073 2074 2074 sport->port.read_status_mask = 0; 2075 2075 if (termios->c_iflag & INPCK) ··· 2124 2124 sport->lpuart_dma_rx_use = false; 2125 2125 } 2126 2126 2127 - spin_unlock_irqrestore(&sport->port.lock, flags); 2127 + uart_port_unlock_irqrestore(&sport->port, flags); 2128 2128 } 2129 2129 2130 2130 static void __lpuart32_serial_setbrg(struct uart_port *port, ··· 2304 2304 if (old && sport->lpuart_dma_rx_use) 2305 2305 lpuart_dma_rx_free(&sport->port); 2306 2306 2307 - spin_lock_irqsave(&sport->port.lock, flags); 2307 + uart_port_lock_irqsave(&sport->port, &flags); 2308 2308 2309 2309 sport->port.read_status_mask = 0; 2310 2310 if (termios->c_iflag & INPCK) ··· 2359 2359 sport->lpuart_dma_rx_use = false; 2360 2360 } 2361 2361 2362 - spin_unlock_irqrestore(&sport->port.lock, flags); 2362 + uart_port_unlock_irqrestore(&sport->port, flags); 2363 2363 } 2364 2364 2365 2365 static const char *lpuart_type(struct uart_port *port) ··· 2477 2477 int locked = 1; 2478 2478 2479 2479 if (oops_in_progress) 2480 - locked = spin_trylock_irqsave(&sport->port.lock, flags); 2480 + locked = uart_port_trylock_irqsave(&sport->port, &flags); 2481 2481 else 2482 - spin_lock_irqsave(&sport->port.lock, flags); 2482 + uart_port_lock_irqsave(&sport->port, &flags); 2483 2483 2484 2484 /* first save CR2 and then disable interrupts */ 2485 2485 cr2 = old_cr2 = readb(sport->port.membase + UARTCR2); ··· 2495 2495 writeb(old_cr2, sport->port.membase + UARTCR2); 2496 2496 2497 2497 if (locked) 2498 - spin_unlock_irqrestore(&sport->port.lock, flags); 2498 + uart_port_unlock_irqrestore(&sport->port, flags); 2499 2499 } 2500 2500 2501 2501 static void ··· 2507 2507 int locked = 1; 2508 2508 2509 2509 if (oops_in_progress) 2510 - locked = spin_trylock_irqsave(&sport->port.lock, flags); 2510 + locked = uart_port_trylock_irqsave(&sport->port, &flags); 2511 2511 else 2512 - spin_lock_irqsave(&sport->port.lock, flags); 2512 + uart_port_lock_irqsave(&sport->port, &flags); 2513 2513 2514 2514 /* first save CR2 and then disable interrupts */ 2515 2515 cr = old_cr = lpuart32_read(&sport->port, UARTCTRL); ··· 2525 2525 lpuart32_write(&sport->port, old_cr, UARTCTRL); 2526 2526 2527 2527 if (locked) 2528 - spin_unlock_irqrestore(&sport->port.lock, flags); 2528 + uart_port_unlock_irqrestore(&sport->port, flags); 2529 2529 } 2530 2530 2531 2531 /* ··· 3089 3089 uart_suspend_port(&lpuart_reg, &sport->port); 3090 3090 3091 3091 if (lpuart_uport_is_active(sport)) { 3092 - spin_lock_irqsave(&sport->port.lock, flags); 3092 + uart_port_lock_irqsave(&sport->port, &flags); 3093 3093 if (lpuart_is_32(sport)) { 3094 3094 /* disable Rx/Tx and interrupts */ 3095 3095 temp = lpuart32_read(&sport->port, UARTCTRL); ··· 3101 3101 temp &= ~(UARTCR2_TE | UARTCR2_TIE | UARTCR2_TCIE); 3102 3102 writeb(temp, sport->port.membase + UARTCR2); 3103 3103 } 3104 - spin_unlock_irqrestore(&sport->port.lock, flags); 3104 + uart_port_unlock_irqrestore(&sport->port, flags); 3105 3105 3106 3106 if (sport->lpuart_dma_rx_use) { 3107 3107 /* ··· 3114 3114 lpuart_dma_rx_free(&sport->port); 3115 3115 3116 3116 /* Disable Rx DMA to use UART port as wakeup source */ 3117 - spin_lock_irqsave(&sport->port.lock, flags); 3117 + uart_port_lock_irqsave(&sport->port, &flags); 3118 3118 if (lpuart_is_32(sport)) { 3119 3119 temp = lpuart32_read(&sport->port, UARTBAUD); 3120 3120 lpuart32_write(&sport->port, temp & ~UARTBAUD_RDMAE, ··· 3123 3123 writeb(readb(sport->port.membase + UARTCR5) & 3124 3124 ~UARTCR5_RDMAS, sport->port.membase + UARTCR5); 3125 3125 } 3126 - spin_unlock_irqrestore(&sport->port.lock, flags); 3126 + uart_port_unlock_irqrestore(&sport->port, flags); 3127 3127 } 3128 3128 3129 3129 if (sport->lpuart_dma_tx_use) { 3130 - spin_lock_irqsave(&sport->port.lock, flags); 3130 + uart_port_lock_irqsave(&sport->port, &flags); 3131 3131 if (lpuart_is_32(sport)) { 3132 3132 temp = lpuart32_read(&sport->port, UARTBAUD); 3133 3133 temp &= ~UARTBAUD_TDMAE; ··· 3137 3137 temp &= ~UARTCR5_TDMAS; 3138 3138 writeb(temp, sport->port.membase + UARTCR5); 3139 3139 } 3140 - spin_unlock_irqrestore(&sport->port.lock, flags); 3140 + uart_port_unlock_irqrestore(&sport->port, flags); 3141 3141 sport->dma_tx_in_progress = false; 3142 3142 dmaengine_terminate_sync(sport->dma_tx_chan); 3143 3143 }