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

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

authored by

Thomas Gleixner and committed by
Greg Kroah-Hartman
b9cedc02 b4a88fae

+10 -10
+10 -10
drivers/tty/serial/sa1100.c
··· 115 115 unsigned long flags; 116 116 117 117 if (sport->port.state) { 118 - spin_lock_irqsave(&sport->port.lock, flags); 118 + uart_port_lock_irqsave(&sport->port, &flags); 119 119 sa1100_mctrl_check(sport); 120 - spin_unlock_irqrestore(&sport->port.lock, flags); 120 + uart_port_unlock_irqrestore(&sport->port, flags); 121 121 122 122 mod_timer(&sport->timer, jiffies + MCTRL_TIMEOUT); 123 123 } ··· 247 247 struct sa1100_port *sport = dev_id; 248 248 unsigned int status, pass_counter = 0; 249 249 250 - spin_lock(&sport->port.lock); 250 + uart_port_lock(&sport->port); 251 251 status = UART_GET_UTSR0(sport); 252 252 status &= SM_TO_UTSR0(sport->port.read_status_mask) | ~UTSR0_TFS; 253 253 do { ··· 276 276 status &= SM_TO_UTSR0(sport->port.read_status_mask) | 277 277 ~UTSR0_TFS; 278 278 } while (status & (UTSR0_TFS | UTSR0_RFS | UTSR0_RID)); 279 - spin_unlock(&sport->port.lock); 279 + uart_port_unlock(&sport->port); 280 280 281 281 return IRQ_HANDLED; 282 282 } ··· 321 321 unsigned long flags; 322 322 unsigned int utcr3; 323 323 324 - spin_lock_irqsave(&sport->port.lock, flags); 324 + uart_port_lock_irqsave(&sport->port, &flags); 325 325 utcr3 = UART_GET_UTCR3(sport); 326 326 if (break_state == -1) 327 327 utcr3 |= UTCR3_BRK; 328 328 else 329 329 utcr3 &= ~UTCR3_BRK; 330 330 UART_PUT_UTCR3(sport, utcr3); 331 - spin_unlock_irqrestore(&sport->port.lock, flags); 331 + uart_port_unlock_irqrestore(&sport->port, flags); 332 332 } 333 333 334 334 static int sa1100_startup(struct uart_port *port) ··· 354 354 /* 355 355 * Enable modem status interrupts 356 356 */ 357 - spin_lock_irq(&sport->port.lock); 357 + uart_port_lock_irq(&sport->port); 358 358 sa1100_enable_ms(&sport->port); 359 - spin_unlock_irq(&sport->port.lock); 359 + uart_port_unlock_irq(&sport->port); 360 360 361 361 return 0; 362 362 } ··· 423 423 424 424 del_timer_sync(&sport->timer); 425 425 426 - spin_lock_irqsave(&sport->port.lock, flags); 426 + uart_port_lock_irqsave(&sport->port, &flags); 427 427 428 428 sport->port.read_status_mask &= UTSR0_TO_SM(UTSR0_TFS); 429 429 sport->port.read_status_mask |= UTSR1_TO_SM(UTSR1_ROR); ··· 485 485 if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) 486 486 sa1100_enable_ms(&sport->port); 487 487 488 - spin_unlock_irqrestore(&sport->port.lock, flags); 488 + uart_port_unlock_irqrestore(&sport->port, flags); 489 489 } 490 490 491 491 static const char *sa1100_type(struct uart_port *port)