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

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

authored by

Thomas Gleixner and committed by
Greg Kroah-Hartman
b7d094df 8975ed8c

+26 -26
+26 -26
drivers/tty/serial/pmac_zilog.c
··· 246 246 #endif /* USE_CTRL_O_SYSRQ */ 247 247 if (uap->port.sysrq) { 248 248 int swallow; 249 - spin_unlock(&uap->port.lock); 249 + uart_port_unlock(&uap->port); 250 250 swallow = uart_handle_sysrq_char(&uap->port, ch); 251 - spin_lock(&uap->port.lock); 251 + uart_port_lock(&uap->port); 252 252 if (swallow) 253 253 goto next_char; 254 254 } ··· 435 435 uap_a = pmz_get_port_A(uap); 436 436 uap_b = uap_a->mate; 437 437 438 - spin_lock(&uap_a->port.lock); 438 + uart_port_lock(&uap_a->port); 439 439 r3 = read_zsreg(uap_a, R3); 440 440 441 441 /* Channel A */ ··· 456 456 rc = IRQ_HANDLED; 457 457 } 458 458 skip_a: 459 - spin_unlock(&uap_a->port.lock); 459 + uart_port_unlock(&uap_a->port); 460 460 if (push) 461 461 tty_flip_buffer_push(&uap->port.state->port); 462 462 463 463 if (!uap_b) 464 464 goto out; 465 465 466 - spin_lock(&uap_b->port.lock); 466 + uart_port_lock(&uap_b->port); 467 467 push = false; 468 468 if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { 469 469 if (!ZS_IS_OPEN(uap_b)) { ··· 481 481 rc = IRQ_HANDLED; 482 482 } 483 483 skip_b: 484 - spin_unlock(&uap_b->port.lock); 484 + uart_port_unlock(&uap_b->port); 485 485 if (push) 486 486 tty_flip_buffer_push(&uap->port.state->port); 487 487 ··· 497 497 unsigned long flags; 498 498 u8 status; 499 499 500 - spin_lock_irqsave(&uap->port.lock, flags); 500 + uart_port_lock_irqsave(&uap->port, &flags); 501 501 status = read_zsreg(uap, R0); 502 - spin_unlock_irqrestore(&uap->port.lock, flags); 502 + uart_port_unlock_irqrestore(&uap->port, flags); 503 503 504 504 return status; 505 505 } ··· 685 685 else 686 686 clear_bits |= SND_BRK; 687 687 688 - spin_lock_irqsave(&port->lock, flags); 688 + uart_port_lock_irqsave(port, &flags); 689 689 690 690 new_reg = (uap->curregs[R5] | set_bits) & ~clear_bits; 691 691 if (new_reg != uap->curregs[R5]) { ··· 693 693 write_zsreg(uap, R5, uap->curregs[R5]); 694 694 } 695 695 696 - spin_unlock_irqrestore(&port->lock, flags); 696 + uart_port_unlock_irqrestore(port, flags); 697 697 } 698 698 699 699 #ifdef CONFIG_PPC_PMAC ··· 865 865 { 866 866 unsigned long flags; 867 867 868 - spin_lock_irqsave(&uap->port.lock, flags); 868 + uart_port_lock_irqsave(&uap->port, &flags); 869 869 uap->curregs[R5] |= DTR; 870 870 write_zsreg(uap, R5, uap->curregs[R5]); 871 871 zssync(uap); 872 - spin_unlock_irqrestore(&uap->port.lock, flags); 872 + uart_port_unlock_irqrestore(&uap->port, flags); 873 873 msleep(110); 874 874 875 - spin_lock_irqsave(&uap->port.lock, flags); 875 + uart_port_lock_irqsave(&uap->port, &flags); 876 876 uap->curregs[R5] &= ~DTR; 877 877 write_zsreg(uap, R5, uap->curregs[R5]); 878 878 zssync(uap); 879 - spin_unlock_irqrestore(&uap->port.lock, flags); 879 + uart_port_unlock_irqrestore(&uap->port, flags); 880 880 msleep(10); 881 881 } 882 882 ··· 896 896 * initialize the chip 897 897 */ 898 898 if (!ZS_IS_CONS(uap)) { 899 - spin_lock_irqsave(&port->lock, flags); 899 + uart_port_lock_irqsave(port, &flags); 900 900 pwr_delay = __pmz_startup(uap); 901 - spin_unlock_irqrestore(&port->lock, flags); 901 + uart_port_unlock_irqrestore(port, flags); 902 902 } 903 903 sprintf(uap->irq_name, PMACZILOG_NAME"%d", uap->port.line); 904 904 if (request_irq(uap->port.irq, pmz_interrupt, IRQF_SHARED, ··· 921 921 pmz_irda_reset(uap); 922 922 923 923 /* Enable interrupt requests for the channel */ 924 - spin_lock_irqsave(&port->lock, flags); 924 + uart_port_lock_irqsave(port, &flags); 925 925 pmz_interrupt_control(uap, 1); 926 - spin_unlock_irqrestore(&port->lock, flags); 926 + uart_port_unlock_irqrestore(port, flags); 927 927 928 928 return 0; 929 929 } ··· 933 933 struct uart_pmac_port *uap = to_pmz(port); 934 934 unsigned long flags; 935 935 936 - spin_lock_irqsave(&port->lock, flags); 936 + uart_port_lock_irqsave(port, &flags); 937 937 938 938 /* Disable interrupt requests for the channel */ 939 939 pmz_interrupt_control(uap, 0); ··· 948 948 pmz_maybe_update_regs(uap); 949 949 } 950 950 951 - spin_unlock_irqrestore(&port->lock, flags); 951 + uart_port_unlock_irqrestore(port, flags); 952 952 953 953 /* Release interrupt handler */ 954 954 free_irq(uap->port.irq, uap); 955 955 956 - spin_lock_irqsave(&port->lock, flags); 956 + uart_port_lock_irqsave(port, &flags); 957 957 958 958 uap->flags &= ~PMACZILOG_FLAG_IS_OPEN; 959 959 960 960 if (!ZS_IS_CONS(uap)) 961 961 pmz_set_scc_power(uap, 0); /* Shut the chip down */ 962 962 963 - spin_unlock_irqrestore(&port->lock, flags); 963 + uart_port_unlock_irqrestore(port, flags); 964 964 } 965 965 966 966 /* Shared by TTY driver and serial console setup. The port lock is held ··· 1247 1247 struct uart_pmac_port *uap = to_pmz(port); 1248 1248 unsigned long flags; 1249 1249 1250 - spin_lock_irqsave(&port->lock, flags); 1250 + uart_port_lock_irqsave(port, &flags); 1251 1251 1252 1252 /* Disable IRQs on the port */ 1253 1253 pmz_interrupt_control(uap, 0); ··· 1259 1259 if (ZS_IS_OPEN(uap)) 1260 1260 pmz_interrupt_control(uap, 1); 1261 1261 1262 - spin_unlock_irqrestore(&port->lock, flags); 1262 + uart_port_unlock_irqrestore(port, flags); 1263 1263 } 1264 1264 1265 1265 static const char *pmz_type(struct uart_port *port) ··· 1896 1896 struct uart_pmac_port *uap = &pmz_ports[con->index]; 1897 1897 unsigned long flags; 1898 1898 1899 - spin_lock_irqsave(&uap->port.lock, flags); 1899 + uart_port_lock_irqsave(&uap->port, &flags); 1900 1900 1901 1901 /* Turn of interrupts and enable the transmitter. */ 1902 1902 write_zsreg(uap, R1, uap->curregs[1] & ~TxINT_ENAB); ··· 1908 1908 write_zsreg(uap, R1, uap->curregs[1]); 1909 1909 /* Don't disable the transmitter. */ 1910 1910 1911 - spin_unlock_irqrestore(&uap->port.lock, flags); 1911 + uart_port_unlock_irqrestore(&uap->port, flags); 1912 1912 } 1913 1913 1914 1914 /*