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

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

authored by

Thomas Gleixner and committed by
Greg Kroah-Hartman
3d728b9e f610d445

+21 -21
+21 -21
drivers/tty/serial/sunzilog.c
··· 531 531 struct tty_port *port; 532 532 unsigned char r3; 533 533 534 - spin_lock(&up->port.lock); 534 + uart_port_lock(&up->port); 535 535 r3 = read_zsreg(channel, R3); 536 536 537 537 /* Channel A */ ··· 548 548 if (r3 & CHATxIP) 549 549 sunzilog_transmit_chars(up, channel); 550 550 } 551 - spin_unlock(&up->port.lock); 551 + uart_port_unlock(&up->port); 552 552 553 553 if (port) 554 554 tty_flip_buffer_push(port); ··· 557 557 up = up->next; 558 558 channel = ZILOG_CHANNEL_FROM_PORT(&up->port); 559 559 560 - spin_lock(&up->port.lock); 560 + uart_port_lock(&up->port); 561 561 port = NULL; 562 562 if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { 563 563 writeb(RES_H_IUS, &channel->control); ··· 571 571 if (r3 & CHBTxIP) 572 572 sunzilog_transmit_chars(up, channel); 573 573 } 574 - spin_unlock(&up->port.lock); 574 + uart_port_unlock(&up->port); 575 575 576 576 if (port) 577 577 tty_flip_buffer_push(port); ··· 604 604 unsigned char status; 605 605 unsigned int ret; 606 606 607 - spin_lock_irqsave(&port->lock, flags); 607 + uart_port_lock_irqsave(port, &flags); 608 608 609 609 status = sunzilog_read_channel_status(port); 610 610 611 - spin_unlock_irqrestore(&port->lock, flags); 611 + uart_port_unlock_irqrestore(port, flags); 612 612 613 613 if (status & Tx_BUF_EMP) 614 614 ret = TIOCSER_TEMT; ··· 764 764 else 765 765 clear_bits |= SND_BRK; 766 766 767 - spin_lock_irqsave(&port->lock, flags); 767 + uart_port_lock_irqsave(port, &flags); 768 768 769 769 new_reg = (up->curregs[R5] | set_bits) & ~clear_bits; 770 770 if (new_reg != up->curregs[R5]) { ··· 774 774 write_zsreg(channel, R5, up->curregs[R5]); 775 775 } 776 776 777 - spin_unlock_irqrestore(&port->lock, flags); 777 + uart_port_unlock_irqrestore(port, flags); 778 778 } 779 779 780 780 static void __sunzilog_startup(struct uart_sunzilog_port *up) ··· 800 800 if (ZS_IS_CONS(up)) 801 801 return 0; 802 802 803 - spin_lock_irqsave(&port->lock, flags); 803 + uart_port_lock_irqsave(port, &flags); 804 804 __sunzilog_startup(up); 805 - spin_unlock_irqrestore(&port->lock, flags); 805 + uart_port_unlock_irqrestore(port, flags); 806 806 return 0; 807 807 } 808 808 ··· 840 840 if (ZS_IS_CONS(up)) 841 841 return; 842 842 843 - spin_lock_irqsave(&port->lock, flags); 843 + uart_port_lock_irqsave(port, &flags); 844 844 845 845 channel = ZILOG_CHANNEL_FROM_PORT(port); 846 846 ··· 853 853 up->curregs[R5] &= ~SND_BRK; 854 854 sunzilog_maybe_update_regs(up, channel); 855 855 856 - spin_unlock_irqrestore(&port->lock, flags); 856 + uart_port_unlock_irqrestore(port, flags); 857 857 } 858 858 859 859 /* Shared by TTY driver and serial console setup. The port lock is held ··· 945 945 946 946 baud = uart_get_baud_rate(port, termios, old, 1200, 76800); 947 947 948 - spin_lock_irqsave(&up->port.lock, flags); 948 + uart_port_lock_irqsave(&up->port, &flags); 949 949 950 950 brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR); 951 951 ··· 962 962 963 963 uart_update_timeout(port, termios->c_cflag, baud); 964 964 965 - spin_unlock_irqrestore(&up->port.lock, flags); 965 + uart_port_unlock_irqrestore(&up->port, flags); 966 966 } 967 967 968 968 static const char *sunzilog_type(struct uart_port *port) ··· 1201 1201 int locked = 1; 1202 1202 1203 1203 if (up->port.sysrq || oops_in_progress) 1204 - locked = spin_trylock_irqsave(&up->port.lock, flags); 1204 + locked = uart_port_trylock_irqsave(&up->port, &flags); 1205 1205 else 1206 - spin_lock_irqsave(&up->port.lock, flags); 1206 + uart_port_lock_irqsave(&up->port, &flags); 1207 1207 1208 1208 uart_console_write(&up->port, s, count, sunzilog_putchar); 1209 1209 udelay(2); 1210 1210 1211 1211 if (locked) 1212 - spin_unlock_irqrestore(&up->port.lock, flags); 1212 + uart_port_unlock_irqrestore(&up->port, flags); 1213 1213 } 1214 1214 1215 1215 static int __init sunzilog_console_setup(struct console *con, char *options) ··· 1244 1244 1245 1245 brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR); 1246 1246 1247 - spin_lock_irqsave(&up->port.lock, flags); 1247 + uart_port_lock_irqsave(&up->port, &flags); 1248 1248 1249 1249 up->curregs[R15] |= BRKIE; 1250 1250 sunzilog_convert_to_zs(up, con->cflag, 0, brg); ··· 1252 1252 sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS); 1253 1253 __sunzilog_startup(up); 1254 1254 1255 - spin_unlock_irqrestore(&up->port.lock, flags); 1255 + uart_port_unlock_irqrestore(&up->port, flags); 1256 1256 1257 1257 return 0; 1258 1258 } ··· 1333 1333 1334 1334 channel = ZILOG_CHANNEL_FROM_PORT(&up->port); 1335 1335 1336 - spin_lock_irqsave(&up->port.lock, flags); 1336 + uart_port_lock_irqsave(&up->port, &flags); 1337 1337 if (ZS_IS_CHANNEL_A(up)) { 1338 1338 write_zsreg(channel, R9, FHWRES); 1339 1339 ZSDELAY_LONG(); ··· 1383 1383 write_zsreg(channel, R9, up->curregs[R9]); 1384 1384 } 1385 1385 1386 - spin_unlock_irqrestore(&up->port.lock, flags); 1386 + uart_port_unlock_irqrestore(&up->port, flags); 1387 1387 1388 1388 #ifdef CONFIG_SERIO 1389 1389 if (up->flags & (SUNZILOG_FLAG_CONS_KEYB |