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

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

authored by

Thomas Gleixner and committed by
Greg Kroah-Hartman
893d2251 9067817b

+18 -18
+18 -18
drivers/tty/serial/ip22zilog.c
··· 432 432 unsigned char r3; 433 433 bool push = false; 434 434 435 - spin_lock(&up->port.lock); 435 + uart_port_lock(&up->port); 436 436 r3 = read_zsreg(channel, R3); 437 437 438 438 /* Channel A */ ··· 448 448 if (r3 & CHATxIP) 449 449 ip22zilog_transmit_chars(up, channel); 450 450 } 451 - spin_unlock(&up->port.lock); 451 + uart_port_unlock(&up->port); 452 452 453 453 if (push) 454 454 tty_flip_buffer_push(&up->port.state->port); ··· 458 458 channel = ZILOG_CHANNEL_FROM_PORT(&up->port); 459 459 push = false; 460 460 461 - spin_lock(&up->port.lock); 461 + uart_port_lock(&up->port); 462 462 if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { 463 463 writeb(RES_H_IUS, &channel->control); 464 464 ZSDELAY(); ··· 471 471 if (r3 & CHBTxIP) 472 472 ip22zilog_transmit_chars(up, channel); 473 473 } 474 - spin_unlock(&up->port.lock); 474 + uart_port_unlock(&up->port); 475 475 476 476 if (push) 477 477 tty_flip_buffer_push(&up->port.state->port); ··· 504 504 unsigned char status; 505 505 unsigned int ret; 506 506 507 - spin_lock_irqsave(&port->lock, flags); 507 + uart_port_lock_irqsave(port, &flags); 508 508 509 509 status = ip22zilog_read_channel_status(port); 510 510 511 - spin_unlock_irqrestore(&port->lock, flags); 511 + uart_port_unlock_irqrestore(port, flags); 512 512 513 513 if (status & Tx_BUF_EMP) 514 514 ret = TIOCSER_TEMT; ··· 664 664 else 665 665 clear_bits |= SND_BRK; 666 666 667 - spin_lock_irqsave(&port->lock, flags); 667 + uart_port_lock_irqsave(port, &flags); 668 668 669 669 new_reg = (up->curregs[R5] | set_bits) & ~clear_bits; 670 670 if (new_reg != up->curregs[R5]) { ··· 674 674 write_zsreg(channel, R5, up->curregs[R5]); 675 675 } 676 676 677 - spin_unlock_irqrestore(&port->lock, flags); 677 + uart_port_unlock_irqrestore(port, flags); 678 678 } 679 679 680 680 static void __ip22zilog_reset(struct uart_ip22zilog_port *up) ··· 735 735 if (ZS_IS_CONS(up)) 736 736 return 0; 737 737 738 - spin_lock_irqsave(&port->lock, flags); 738 + uart_port_lock_irqsave(port, &flags); 739 739 __ip22zilog_startup(up); 740 - spin_unlock_irqrestore(&port->lock, flags); 740 + uart_port_unlock_irqrestore(port, flags); 741 741 return 0; 742 742 } 743 743 ··· 775 775 if (ZS_IS_CONS(up)) 776 776 return; 777 777 778 - spin_lock_irqsave(&port->lock, flags); 778 + uart_port_lock_irqsave(port, &flags); 779 779 780 780 channel = ZILOG_CHANNEL_FROM_PORT(port); 781 781 ··· 788 788 up->curregs[R5] &= ~SND_BRK; 789 789 ip22zilog_maybe_update_regs(up, channel); 790 790 791 - spin_unlock_irqrestore(&port->lock, flags); 791 + uart_port_unlock_irqrestore(port, flags); 792 792 } 793 793 794 794 /* Shared by TTY driver and serial console setup. The port lock is held ··· 880 880 881 881 baud = uart_get_baud_rate(port, termios, old, 1200, 76800); 882 882 883 - spin_lock_irqsave(&up->port.lock, flags); 883 + uart_port_lock_irqsave(&up->port, &flags); 884 884 885 885 brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR); 886 886 ··· 894 894 ip22zilog_maybe_update_regs(up, ZILOG_CHANNEL_FROM_PORT(port)); 895 895 uart_update_timeout(port, termios->c_cflag, baud); 896 896 897 - spin_unlock_irqrestore(&up->port.lock, flags); 897 + uart_port_unlock_irqrestore(&up->port, flags); 898 898 } 899 899 900 900 static const char *ip22zilog_type(struct uart_port *port) ··· 1016 1016 struct uart_ip22zilog_port *up = &ip22zilog_port_table[con->index]; 1017 1017 unsigned long flags; 1018 1018 1019 - spin_lock_irqsave(&up->port.lock, flags); 1019 + uart_port_lock_irqsave(&up->port, &flags); 1020 1020 uart_console_write(&up->port, s, count, ip22zilog_put_char); 1021 1021 udelay(2); 1022 - spin_unlock_irqrestore(&up->port.lock, flags); 1022 + uart_port_unlock_irqrestore(&up->port, flags); 1023 1023 } 1024 1024 1025 1025 static int __init ip22zilog_console_setup(struct console *con, char *options) ··· 1034 1034 1035 1035 printk(KERN_INFO "Console: ttyS%d (IP22-Zilog)\n", con->index); 1036 1036 1037 - spin_lock_irqsave(&up->port.lock, flags); 1037 + uart_port_lock_irqsave(&up->port, &flags); 1038 1038 1039 1039 up->curregs[R15] |= BRKIE; 1040 1040 1041 1041 __ip22zilog_startup(up); 1042 1042 1043 - spin_unlock_irqrestore(&up->port.lock, flags); 1043 + uart_port_unlock_irqrestore(&up->port, flags); 1044 1044 1045 1045 if (options) 1046 1046 uart_parse_options(options, &baud, &parity, &bits, &flow);