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

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

authored by

Thomas Gleixner and committed by
Greg Kroah-Hartman
b4c7ba24 92f4e05b

+13 -13
+13 -13
drivers/tty/serial/icom.c
··· 929 929 char delta_status; 930 930 unsigned char status; 931 931 932 - spin_lock(&icom_port->uart_port.lock); 932 + uart_port_lock(&icom_port->uart_port); 933 933 934 934 /*modem input register */ 935 935 status = readb(&icom_port->dram->isr); ··· 951 951 port.delta_msr_wait); 952 952 old_status = status; 953 953 } 954 - spin_unlock(&icom_port->uart_port.lock); 954 + uart_port_unlock(&icom_port->uart_port); 955 955 } 956 956 957 957 static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port) ··· 1093 1093 struct icom_port *icom_port) 1094 1094 { 1095 1095 1096 - spin_lock(&icom_port->uart_port.lock); 1096 + uart_port_lock(&icom_port->uart_port); 1097 1097 trace(icom_port, "INTERRUPT", port_int_reg); 1098 1098 1099 1099 if (port_int_reg & (INT_XMIT_COMPLETED | INT_XMIT_DISABLED)) ··· 1102 1102 if (port_int_reg & INT_RCV_COMPLETED) 1103 1103 recv_interrupt(port_int_reg, icom_port); 1104 1104 1105 - spin_unlock(&icom_port->uart_port.lock); 1105 + uart_port_unlock(&icom_port->uart_port); 1106 1106 } 1107 1107 1108 1108 static irqreturn_t icom_interrupt(int irq, void *dev_id) ··· 1186 1186 int ret; 1187 1187 unsigned long flags; 1188 1188 1189 - spin_lock_irqsave(&port->lock, flags); 1189 + uart_port_lock_irqsave(port, &flags); 1190 1190 if (le16_to_cpu(icom_port->statStg->xmit[0].flags) & 1191 1191 SA_FLAGS_READY_TO_XMIT) 1192 1192 ret = TIOCSER_TEMT; 1193 1193 else 1194 1194 ret = 0; 1195 1195 1196 - spin_unlock_irqrestore(&port->lock, flags); 1196 + uart_port_unlock_irqrestore(port, flags); 1197 1197 return ret; 1198 1198 } 1199 1199 ··· 1276 1276 1277 1277 /* wait .1 sec to send char */ 1278 1278 for (index = 0; index < 10; index++) { 1279 - spin_lock_irqsave(&port->lock, flags); 1279 + uart_port_lock_irqsave(port, &flags); 1280 1280 xdata = readb(&icom_port->dram->xchar); 1281 1281 if (xdata == 0x00) { 1282 1282 trace(icom_port, "QUICK_WRITE", 0); ··· 1284 1284 1285 1285 /* flush write operation */ 1286 1286 xdata = readb(&icom_port->dram->xchar); 1287 - spin_unlock_irqrestore(&port->lock, flags); 1287 + uart_port_unlock_irqrestore(port, flags); 1288 1288 break; 1289 1289 } 1290 - spin_unlock_irqrestore(&port->lock, flags); 1290 + uart_port_unlock_irqrestore(port, flags); 1291 1291 msleep(10); 1292 1292 } 1293 1293 } ··· 1307 1307 unsigned char cmdReg; 1308 1308 unsigned long flags; 1309 1309 1310 - spin_lock_irqsave(&port->lock, flags); 1310 + uart_port_lock_irqsave(port, &flags); 1311 1311 trace(icom_port, "BREAK", 0); 1312 1312 cmdReg = readb(&icom_port->dram->CmdReg); 1313 1313 if (break_state == -1) { ··· 1315 1315 } else { 1316 1316 writeb(cmdReg & ~CMD_SND_BREAK, &icom_port->dram->CmdReg); 1317 1317 } 1318 - spin_unlock_irqrestore(&port->lock, flags); 1318 + uart_port_unlock_irqrestore(port, flags); 1319 1319 } 1320 1320 1321 1321 static int icom_open(struct uart_port *port) ··· 1365 1365 unsigned long offset; 1366 1366 unsigned long flags; 1367 1367 1368 - spin_lock_irqsave(&port->lock, flags); 1368 + uart_port_lock_irqsave(port, &flags); 1369 1369 trace(icom_port, "CHANGE_SPEED", 0); 1370 1370 1371 1371 cflag = termios->c_cflag; ··· 1516 1516 trace(icom_port, "XR_ENAB", 0); 1517 1517 writeb(CMD_XMIT_RCV_ENABLE, &icom_port->dram->CmdReg); 1518 1518 1519 - spin_unlock_irqrestore(&port->lock, flags); 1519 + uart_port_unlock_irqrestore(port, flags); 1520 1520 } 1521 1521 1522 1522 static const char *icom_type(struct uart_port *port)