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

serial: meson: 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>
Acked-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: John Ogness <john.ogness@linutronix.de>
Link: https://lore.kernel.org/r/20230914183831.587273-38-john.ogness@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Thomas Gleixner and committed by
Greg Kroah-Hartman
042d7848 6db6bc75

+15 -15
+15 -15
drivers/tty/serial/meson_uart.c
··· 129 129 130 130 free_irq(port->irq, port); 131 131 132 - spin_lock_irqsave(&port->lock, flags); 132 + uart_port_lock_irqsave(port, &flags); 133 133 134 134 val = readl(port->membase + AML_UART_CONTROL); 135 135 val &= ~AML_UART_RX_EN; 136 136 val &= ~(AML_UART_RX_INT_EN | AML_UART_TX_INT_EN); 137 137 writel(val, port->membase + AML_UART_CONTROL); 138 138 139 - spin_unlock_irqrestore(&port->lock, flags); 139 + uart_port_unlock_irqrestore(port, flags); 140 140 } 141 141 142 142 static void meson_uart_start_tx(struct uart_port *port) ··· 238 238 { 239 239 struct uart_port *port = (struct uart_port *)dev_id; 240 240 241 - spin_lock(&port->lock); 241 + uart_port_lock(port); 242 242 243 243 if (!(readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY)) 244 244 meson_receive_chars(port); ··· 248 248 meson_uart_start_tx(port); 249 249 } 250 250 251 - spin_unlock(&port->lock); 251 + uart_port_unlock(port); 252 252 253 253 return IRQ_HANDLED; 254 254 } ··· 284 284 u32 val; 285 285 int ret = 0; 286 286 287 - spin_lock_irqsave(&port->lock, flags); 287 + uart_port_lock_irqsave(port, &flags); 288 288 289 289 val = readl(port->membase + AML_UART_CONTROL); 290 290 val |= AML_UART_CLEAR_ERR; ··· 301 301 val = (AML_UART_RECV_IRQ(1) | AML_UART_XMIT_IRQ(port->fifosize / 2)); 302 302 writel(val, port->membase + AML_UART_MISC); 303 303 304 - spin_unlock_irqrestore(&port->lock, flags); 304 + uart_port_unlock_irqrestore(port, flags); 305 305 306 306 ret = request_irq(port->irq, meson_uart_interrupt, 0, 307 307 port->name, port); ··· 341 341 unsigned long flags; 342 342 u32 val; 343 343 344 - spin_lock_irqsave(&port->lock, flags); 344 + uart_port_lock_irqsave(port, &flags); 345 345 346 346 cflags = termios->c_cflag; 347 347 iflags = termios->c_iflag; ··· 401 401 AML_UART_FRAME_ERR; 402 402 403 403 uart_update_timeout(port, termios->c_cflag, baud); 404 - spin_unlock_irqrestore(&port->lock, flags); 404 + uart_port_unlock_irqrestore(port, flags); 405 405 } 406 406 407 407 static int meson_uart_verify_port(struct uart_port *port, ··· 460 460 u32 c; 461 461 unsigned long flags; 462 462 463 - spin_lock_irqsave(&port->lock, flags); 463 + uart_port_lock_irqsave(port, &flags); 464 464 465 465 if (readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY) 466 466 c = NO_POLL_CHAR; 467 467 else 468 468 c = readl(port->membase + AML_UART_RFIFO); 469 469 470 - spin_unlock_irqrestore(&port->lock, flags); 470 + uart_port_unlock_irqrestore(port, flags); 471 471 472 472 return c; 473 473 } ··· 478 478 u32 reg; 479 479 int ret; 480 480 481 - spin_lock_irqsave(&port->lock, flags); 481 + uart_port_lock_irqsave(port, &flags); 482 482 483 483 /* Wait until FIFO is empty or timeout */ 484 484 ret = readl_poll_timeout_atomic(port->membase + AML_UART_STATUS, reg, ··· 502 502 dev_err(port->dev, "Timeout waiting for UART TX EMPTY\n"); 503 503 504 504 out: 505 - spin_unlock_irqrestore(&port->lock, flags); 505 + uart_port_unlock_irqrestore(port, flags); 506 506 } 507 507 508 508 #endif /* CONFIG_CONSOLE_POLL */ ··· 559 559 if (port->sysrq) { 560 560 locked = 0; 561 561 } else if (oops_in_progress) { 562 - locked = spin_trylock(&port->lock); 562 + locked = uart_port_trylock(port); 563 563 } else { 564 - spin_lock(&port->lock); 564 + uart_port_lock(port); 565 565 locked = 1; 566 566 } 567 567 ··· 573 573 writel(val, port->membase + AML_UART_CONTROL); 574 574 575 575 if (locked) 576 - spin_unlock(&port->lock); 576 + uart_port_unlock(port); 577 577 local_irq_restore(flags); 578 578 } 579 579