Re: [PATCH] serial: sifive: Switch to nbcon console
From: Ryo Takakura
Date: Tue Mar 25 2025 - 07:01:19 EST
Hi John,
On Mon, 24 Mar 2025 16:30:20 +0106, John Ogness wrote:
>On 2025-03-23, Ryo Takakura <ryotkkr98@xxxxxxxxx> wrote:
>> Add the necessary callbacks(write_atomic, write_thread, device_lock
>> and device_unlock) and CON_NBCON flag to switch the sifive console
>> driver to perform as nbcon console.
>>
>> Both ->write_atomic() and ->write_thread() will check for console
>> ownership whenever they are accessing registers.
>>
>> The ->device_lock()/unlock() will provide the additional serilization
>> necessary for ->write_thread() which is called from dedicated printing
>> thread.
>>
>> Signed-off-by: Ryo Takakura <ryotkkr98@xxxxxxxxx>
>
>This driver has the same issue that the 8250 previously had. The
>->startup() and ->shutdown() callbacks are called without the port
>lock. However, the sifive driver is accessing SIFIVE_SERIAL_IE_OFFS in
>these callbacks and this register is also accessed by the ->write()
>callback. This needs to be synchronized.
I see. Thanks for pointing out.
(I didn't know about console_on_rootfs() and what it does. Interesting!)
>The related 8250 patches fixing this are startup [0] and shutdown [1]. I
>am assuming the following change would be sufficient:
>
>diff --git a/drivers/tty/serial/sifive.c b/drivers/tty/serial/sifive.c
>index d032de6199af..1de1b2a5833d 100644
>--- a/drivers/tty/serial/sifive.c
>+++ b/drivers/tty/serial/sifive.c
>@@ -564,8 +564,11 @@ static void sifive_serial_break_ctl(struct uart_port *port, int break_state)
> static int sifive_serial_startup(struct uart_port *port)
> {
> struct sifive_serial_port *ssp = port_to_sifive_serial_port(port);
>+ unsigned long flags;
>
>+ uart_port_lock_irqsave(&ssp->port, &flags);
> __ssp_enable_rxwm(ssp);
>+ uart_port_unlock_irqrestore(&ssp->port, flags);
>
> return 0;
> }
>@@ -573,9 +576,12 @@ static int sifive_serial_startup(struct uart_port *port)
> static void sifive_serial_shutdown(struct uart_port *port)
> {
> struct sifive_serial_port *ssp = port_to_sifive_serial_port(port);
>+ unsigned long flags;
>
>+ uart_port_lock_irqsave(&ssp->port, &flags);
> __ssp_disable_rxwm(ssp);
> __ssp_disable_txwm(ssp);
>+ uart_port_unlock_irqrestore(&ssp->port, flags);
> }
>
> /**
>
>The fix should be applied first (and likely Cc stable) since it is
>fixing an existing mainline problem.
Ok, I will add a patch in the next version and cc stable.
>Your patch also needs the synchronization. The ->write_atomic() callback
>does not use the port lock. However, the uart_port_*() functions also
>take the nbcon console ownership, so they synchronize against
>->write_atomic() callbacks.
I see, nice!
>Otherwise, this patch looks good. If the ->startup() and ->shutdown()
>callbacks are fixed in a previous patch, feel free to add:
>
>Reviewed-by: John Ogness <john.ogness@xxxxxxxxxxxxx>
>
>to this patch.
I'll add in the next verison.
Thanks for reviewing!
Sincerely,
Ryo Takakura
>John Ogness
>
>[0] https://lore.kernel.org/lkml/20230525093159.223817-2-john.ogness@xxxxxxxxxxxxx
>[1] https://lore.kernel.org/lkml/20230525093159.223817-9-john.ogness@xxxxxxxxxxxxx