Skip to content

Commit f79b163

Browse files
committed
Revert "serial: 8250: Switch to nbcon console"
This reverts commit b63e6f6. kernel test robot has found problems with this commit so revert it for now. Link: https://lore.kernel.org/r/202501221029.fb0d574d-lkp@intel.com Reported-by: kernel test robot <oliver.sang@intel.com> Closes: https://lore.kernel.org/oe-lkp/202501221029.fb0d574d-lkp@intel.com Cc: John Ogness <john.ogness@linutronix.de> Cc: Petr Mladek <pmladek@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 244eb5c commit f79b163

File tree

3 files changed

+41
-187
lines changed

3 files changed

+41
-187
lines changed

drivers/tty/serial/8250/8250_core.c

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -388,34 +388,12 @@ void __init serial8250_register_ports(struct uart_driver *drv, struct device *de
388388

389389
#ifdef CONFIG_SERIAL_8250_CONSOLE
390390

391-
static void univ8250_console_write_atomic(struct console *co,
392-
struct nbcon_write_context *wctxt)
391+
static void univ8250_console_write(struct console *co, const char *s,
392+
unsigned int count)
393393
{
394394
struct uart_8250_port *up = &serial8250_ports[co->index];
395395

396-
serial8250_console_write(up, wctxt, true);
397-
}
398-
399-
static void univ8250_console_write_thread(struct console *co,
400-
struct nbcon_write_context *wctxt)
401-
{
402-
struct uart_8250_port *up = &serial8250_ports[co->index];
403-
404-
serial8250_console_write(up, wctxt, false);
405-
}
406-
407-
static void univ8250_console_device_lock(struct console *co, unsigned long *flags)
408-
{
409-
struct uart_port *up = &serial8250_ports[co->index].port;
410-
411-
__uart_port_lock_irqsave(up, flags);
412-
}
413-
414-
static void univ8250_console_device_unlock(struct console *co, unsigned long flags)
415-
{
416-
struct uart_port *up = &serial8250_ports[co->index].port;
417-
418-
__uart_port_unlock_irqrestore(up, flags);
396+
serial8250_console_write(up, s, count);
419397
}
420398

421399
static int univ8250_console_setup(struct console *co, char *options)
@@ -516,15 +494,12 @@ static int univ8250_console_match(struct console *co, char *name, int idx,
516494

517495
static struct console univ8250_console = {
518496
.name = "ttyS",
519-
.write_atomic = univ8250_console_write_atomic,
520-
.write_thread = univ8250_console_write_thread,
521-
.device_lock = univ8250_console_device_lock,
522-
.device_unlock = univ8250_console_device_unlock,
497+
.write = univ8250_console_write,
523498
.device = uart_console_device,
524499
.setup = univ8250_console_setup,
525500
.exit = univ8250_console_exit,
526501
.match = univ8250_console_match,
527-
.flags = CON_PRINTBUFFER | CON_ANYTIME | CON_NBCON,
502+
.flags = CON_PRINTBUFFER | CON_ANYTIME,
528503
.index = -1,
529504
.data = &serial8250_reg,
530505
};

drivers/tty/serial/8250/8250_port.c

Lines changed: 34 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -711,24 +711,14 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
711711
serial8250_rpm_put(p);
712712
}
713713

714-
/*
715-
* Only to be used directly by the callback helper serial8250_console_write(),
716-
* which may not require the port lock. Use serial8250_clear_IER() instead for
717-
* all other cases.
718-
*/
719-
static void __serial8250_clear_IER(struct uart_8250_port *up)
714+
static void serial8250_clear_IER(struct uart_8250_port *up)
720715
{
721716
if (up->capabilities & UART_CAP_UUE)
722717
serial_out(up, UART_IER, UART_IER_UUE);
723718
else
724719
serial_out(up, UART_IER, 0);
725720
}
726721

727-
static inline void serial8250_clear_IER(struct uart_8250_port *up)
728-
{
729-
__serial8250_clear_IER(up);
730-
}
731-
732722
#ifdef CONFIG_SERIAL_8250_RSA
733723
/*
734724
* Attempts to turn on the RSA FIFO. Returns zero on failure.
@@ -1416,6 +1406,9 @@ void serial8250_em485_stop_tx(struct uart_8250_port *p, bool toggle_ier)
14161406
{
14171407
unsigned char mcr = serial8250_in_MCR(p);
14181408

1409+
/* Port locked to synchronize UART_IER access against the console. */
1410+
lockdep_assert_held_once(&p->port.lock);
1411+
14191412
if (p->port.rs485.flags & SER_RS485_RTS_AFTER_SEND)
14201413
mcr |= UART_MCR_RTS;
14211414
else
@@ -1431,16 +1424,6 @@ void serial8250_em485_stop_tx(struct uart_8250_port *p, bool toggle_ier)
14311424
serial8250_clear_and_reinit_fifos(p);
14321425

14331426
if (toggle_ier) {
1434-
/*
1435-
* Port locked to synchronize UART_IER access against
1436-
* the console. The lockdep_assert must be restricted
1437-
* to this condition because only here is it
1438-
* guaranteed that the port lock is held. The other
1439-
* hardware access in this function is synchronized
1440-
* by console ownership.
1441-
*/
1442-
lockdep_assert_held_once(&p->port.lock);
1443-
14441427
p->ier |= UART_IER_RLSI | UART_IER_RDI;
14451428
serial_port_out(&p->port, UART_IER, p->ier);
14461429
}
@@ -3320,11 +3303,7 @@ EXPORT_SYMBOL_GPL(serial8250_set_defaults);
33203303

33213304
static void serial8250_console_putchar(struct uart_port *port, unsigned char ch)
33223305
{
3323-
struct uart_8250_port *up = up_to_u8250p(port);
3324-
33253306
serial_port_out(port, UART_TX, ch);
3326-
3327-
up->console_line_ended = (ch == '\n');
33283307
}
33293308

33303309
static void serial8250_console_wait_putchar(struct uart_port *port, unsigned char ch)
@@ -3361,22 +3340,11 @@ static void serial8250_console_restore(struct uart_8250_port *up)
33613340
serial8250_out_MCR(up, up->mcr | UART_MCR_DTR | UART_MCR_RTS);
33623341
}
33633342

3364-
static void fifo_wait_for_lsr(struct uart_8250_port *up,
3365-
struct nbcon_write_context *wctxt,
3366-
unsigned int count)
3343+
static void fifo_wait_for_lsr(struct uart_8250_port *up, unsigned int count)
33673344
{
33683345
unsigned int i;
33693346

33703347
for (i = 0; i < count; i++) {
3371-
/*
3372-
* Pass the ownership as quickly as possible to a higher
3373-
* priority context. Otherwise, its attempt to take over
3374-
* the ownership might timeout. The new owner will wait
3375-
* for UART_LSR_THRE before reusing the fifo.
3376-
*/
3377-
if (!nbcon_can_proceed(wctxt))
3378-
return;
3379-
33803348
if (wait_for_lsr(up, UART_LSR_THRE))
33813349
return;
33823350
}
@@ -3389,38 +3357,27 @@ static void fifo_wait_for_lsr(struct uart_8250_port *up,
33893357
* to get empty.
33903358
*/
33913359
static void serial8250_console_fifo_write(struct uart_8250_port *up,
3392-
struct nbcon_write_context *wctxt)
3360+
const char *s, unsigned int count)
33933361
{
3362+
const char *end = s + count;
33943363
unsigned int fifosize = up->tx_loadsz;
33953364
struct uart_port *port = &up->port;
3396-
const char *s = wctxt->outbuf;
3397-
const char *end = s + wctxt->len;
33983365
unsigned int tx_count = 0;
33993366
bool cr_sent = false;
34003367
unsigned int i;
34013368

34023369
while (s != end) {
34033370
/* Allow timeout for each byte of a possibly full FIFO */
3404-
fifo_wait_for_lsr(up, wctxt, fifosize);
3371+
fifo_wait_for_lsr(up, fifosize);
34053372

3406-
/*
3407-
* Fill the FIFO. If a handover or takeover occurs, writing
3408-
* must be aborted since wctxt->outbuf and wctxt->len are no
3409-
* longer valid.
3410-
*/
34113373
for (i = 0; i < fifosize && s != end; ++i) {
3412-
if (!nbcon_enter_unsafe(wctxt))
3413-
return;
3414-
34153374
if (*s == '\n' && !cr_sent) {
34163375
serial8250_console_putchar(port, '\r');
34173376
cr_sent = true;
34183377
} else {
34193378
serial8250_console_putchar(port, *s++);
34203379
cr_sent = false;
34213380
}
3422-
3423-
nbcon_exit_unsafe(wctxt);
34243381
}
34253382
tx_count = i;
34263383
}
@@ -3429,57 +3386,39 @@ static void serial8250_console_fifo_write(struct uart_8250_port *up,
34293386
* Allow timeout for each byte written since the caller will only wait
34303387
* for UART_LSR_BOTH_EMPTY using the timeout of a single character
34313388
*/
3432-
fifo_wait_for_lsr(up, wctxt, tx_count);
3433-
}
3434-
3435-
static void serial8250_console_byte_write(struct uart_8250_port *up,
3436-
struct nbcon_write_context *wctxt)
3437-
{
3438-
struct uart_port *port = &up->port;
3439-
const char *s = wctxt->outbuf;
3440-
const char *end = s + wctxt->len;
3441-
3442-
/*
3443-
* Write out the message. If a handover or takeover occurs, writing
3444-
* must be aborted since wctxt->outbuf and wctxt->len are no longer
3445-
* valid.
3446-
*/
3447-
while (s != end) {
3448-
if (!nbcon_enter_unsafe(wctxt))
3449-
return;
3450-
3451-
uart_console_write(port, s++, 1, serial8250_console_wait_putchar);
3452-
3453-
nbcon_exit_unsafe(wctxt);
3454-
}
3389+
fifo_wait_for_lsr(up, tx_count);
34553390
}
34563391

34573392
/*
3458-
* Print a string to the serial port trying not to disturb
3459-
* any possible real use of the port...
3393+
* Print a string to the serial port trying not to disturb
3394+
* any possible real use of the port...
3395+
*
3396+
* The console_lock must be held when we get here.
34603397
*
3461-
* Doing runtime PM is really a bad idea for the kernel console.
3462-
* Thus, assume it is called when device is powered up.
3398+
* Doing runtime PM is really a bad idea for the kernel console.
3399+
* Thus, we assume the function is called when device is powered up.
34633400
*/
3464-
void serial8250_console_write(struct uart_8250_port *up,
3465-
struct nbcon_write_context *wctxt,
3466-
bool is_atomic)
3401+
void serial8250_console_write(struct uart_8250_port *up, const char *s,
3402+
unsigned int count)
34673403
{
34683404
struct uart_8250_em485 *em485 = up->em485;
34693405
struct uart_port *port = &up->port;
3470-
unsigned int ier;
3471-
bool use_fifo;
3406+
unsigned long flags;
3407+
unsigned int ier, use_fifo;
3408+
int locked = 1;
34723409

3473-
if (!nbcon_enter_unsafe(wctxt))
3474-
return;
3410+
touch_nmi_watchdog();
3411+
3412+
if (oops_in_progress)
3413+
locked = uart_port_trylock_irqsave(port, &flags);
3414+
else
3415+
uart_port_lock_irqsave(port, &flags);
34753416

34763417
/*
3477-
* First, save the IER, then disable the interrupts. The special
3478-
* variant to clear the IER is used because console printing may
3479-
* occur without holding the port lock.
3418+
* First save the IER then disable the interrupts
34803419
*/
34813420
ier = serial_port_in(port, UART_IER);
3482-
__serial8250_clear_IER(up);
3421+
serial8250_clear_IER(up);
34833422

34843423
/* check scratch reg to see if port powered off during system sleep */
34853424
if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) {
@@ -3493,18 +3432,6 @@ void serial8250_console_write(struct uart_8250_port *up,
34933432
mdelay(port->rs485.delay_rts_before_send);
34943433
}
34953434

3496-
/* If ownership was lost, no writing is allowed */
3497-
if (!nbcon_can_proceed(wctxt))
3498-
goto skip_write;
3499-
3500-
/*
3501-
* If console printer did not fully output the previous line, it must
3502-
* have been handed or taken over. Insert a newline in order to
3503-
* maintain clean output.
3504-
*/
3505-
if (!up->console_line_ended)
3506-
uart_console_write(port, "\n", 1, serial8250_console_wait_putchar);
3507-
35083435
use_fifo = (up->capabilities & UART_CAP_FIFO) &&
35093436
/*
35103437
* BCM283x requires to check the fifo
@@ -3525,23 +3452,10 @@ void serial8250_console_write(struct uart_8250_port *up,
35253452
*/
35263453
!(up->port.flags & UPF_CONS_FLOW);
35273454

3528-
nbcon_exit_unsafe(wctxt);
3529-
35303455
if (likely(use_fifo))
3531-
serial8250_console_fifo_write(up, wctxt);
3456+
serial8250_console_fifo_write(up, s, count);
35323457
else
3533-
serial8250_console_byte_write(up, wctxt);
3534-
skip_write:
3535-
/*
3536-
* If ownership was lost, this context must reacquire ownership and
3537-
* re-enter the unsafe section in order to perform final actions
3538-
* (such as re-enabling interrupts).
3539-
*/
3540-
if (!nbcon_can_proceed(wctxt)) {
3541-
do {
3542-
nbcon_reacquire_nobuf(wctxt);
3543-
} while (!nbcon_enter_unsafe(wctxt));
3544-
}
3458+
uart_console_write(port, s, count, serial8250_console_wait_putchar);
35453459

35463460
/*
35473461
* Finally, wait for transmitter to become empty
@@ -3564,18 +3478,11 @@ void serial8250_console_write(struct uart_8250_port *up,
35643478
* call it if we have saved something in the saved flags
35653479
* while processing with interrupts off.
35663480
*/
3567-
if (up->msr_saved_flags) {
3568-
/*
3569-
* For atomic, it must be deferred to irq_work because this
3570-
* may be a context that does not permit waking up tasks.
3571-
*/
3572-
if (is_atomic)
3573-
irq_work_queue(&up->modem_status_work);
3574-
else
3575-
serial8250_modem_status(up);
3576-
}
3481+
if (up->msr_saved_flags)
3482+
serial8250_modem_status(up);
35773483

3578-
nbcon_exit_unsafe(wctxt);
3484+
if (locked)
3485+
uart_port_unlock_irqrestore(port, flags);
35793486
}
35803487

35813488
static unsigned int probe_baud(struct uart_port *port)
@@ -3593,24 +3500,8 @@ static unsigned int probe_baud(struct uart_port *port)
35933500
return (port->uartclk / 16) / quot;
35943501
}
35953502

3596-
/*
3597-
* irq_work handler to perform modem control. Only triggered via
3598-
* ->write_atomic() callback because it may be in a scheduler or
3599-
* NMI context, unable to wake tasks.
3600-
*/
3601-
static void modem_status_handler(struct irq_work *iwp)
3602-
{
3603-
struct uart_8250_port *up = container_of(iwp, struct uart_8250_port, modem_status_work);
3604-
struct uart_port *port = &up->port;
3605-
3606-
uart_port_lock(port);
3607-
serial8250_modem_status(up);
3608-
uart_port_unlock(port);
3609-
}
3610-
36113503
int serial8250_console_setup(struct uart_port *port, char *options, bool probe)
36123504
{
3613-
struct uart_8250_port *up = up_to_u8250p(port);
36143505
int baud = 9600;
36153506
int bits = 8;
36163507
int parity = 'n';
@@ -3620,9 +3511,6 @@ int serial8250_console_setup(struct uart_port *port, char *options, bool probe)
36203511
if (!port->iobase && !port->membase)
36213512
return -ENODEV;
36223513

3623-
up->console_line_ended = true;
3624-
init_irq_work(&up->modem_status_work, modem_status_handler);
3625-
36263514
if (options)
36273515
uart_parse_options(options, &baud, &parity, &bits, &flow);
36283516
else if (probe)

include/linux/serial_8250.h

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -150,17 +150,8 @@ struct uart_8250_port {
150150
#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
151151
u16 lsr_saved_flags;
152152
u16 lsr_save_mask;
153-
154-
/*
155-
* Track when a console line has been fully written to the
156-
* hardware, i.e. true when the most recent byte written to
157-
* UART_TX by the console was '\n'.
158-
*/
159-
bool console_line_ended;
160-
161153
#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
162154
unsigned char msr_saved_flags;
163-
struct irq_work modem_status_work;
164155

165156
struct uart_8250_dma *dma;
166157
const struct uart_8250_ops *ops;
@@ -211,8 +202,8 @@ void serial8250_tx_chars(struct uart_8250_port *up);
211202
unsigned int serial8250_modem_status(struct uart_8250_port *up);
212203
void serial8250_init_port(struct uart_8250_port *up);
213204
void serial8250_set_defaults(struct uart_8250_port *up);
214-
void serial8250_console_write(struct uart_8250_port *up,
215-
struct nbcon_write_context *wctxt, bool in_atomic);
205+
void serial8250_console_write(struct uart_8250_port *up, const char *s,
206+
unsigned int count);
216207
int serial8250_console_setup(struct uart_port *port, char *options, bool probe);
217208
int serial8250_console_exit(struct uart_port *port);
218209

0 commit comments

Comments
 (0)