drivers/tty/serial/sifive.c | 87 +++++++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 13 deletions(-)
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@gmail.com>
Reviewed-by: John Ogness <john.ogness@linutronix.de>
---
This patch is once again sent as a standalone patch for converting sifive
driver to nbcon. It used to be sent as a part of series. The related fixes
along the way can be found [0].
Sincerely,
Ryo Takakura
[0] https://lore.kernel.org/all/20250405043833.397020-1-ryotkkr98@gmail.com/
---
drivers/tty/serial/sifive.c | 87 +++++++++++++++++++++++++++++++------
1 file changed, 74 insertions(+), 13 deletions(-)
diff --git a/drivers/tty/serial/sifive.c b/drivers/tty/serial/sifive.c
index 054a8e630..8f7f770ec 100644
--- a/drivers/tty/serial/sifive.c
+++ b/drivers/tty/serial/sifive.c
@@ -151,6 +151,7 @@ struct sifive_serial_port {
unsigned long baud_rate;
struct clk *clk;
struct notifier_block clk_notifier;
+ bool console_line_ended;
};
/*
@@ -785,33 +786,88 @@ static void sifive_serial_console_putchar(struct uart_port *port, unsigned char
__ssp_wait_for_xmitr(ssp);
__ssp_transmit_char(ssp, ch);
+
+ ssp->console_line_ended = (ch == '\n');
+}
+
+static void sifive_serial_device_lock(struct console *co, unsigned long *flags)
+{
+ struct uart_port *up = &sifive_serial_console_ports[co->index]->port;
+
+ __uart_port_lock_irqsave(up, flags);
+}
+
+static void sifive_serial_device_unlock(struct console *co, unsigned long flags)
+{
+ struct uart_port *up = &sifive_serial_console_ports[co->index]->port;
+
+ __uart_port_unlock_irqrestore(up, flags);
}
-static void sifive_serial_console_write(struct console *co, const char *s,
- unsigned int count)
+static void sifive_serial_console_write_atomic(struct console *co,
+ struct nbcon_write_context *wctxt)
{
struct sifive_serial_port *ssp = sifive_serial_console_ports[co->index];
- unsigned long flags;
+ struct uart_port *port = &ssp->port;
unsigned int ier;
- int locked = 1;
if (!ssp)
return;
- if (oops_in_progress)
- locked = uart_port_trylock_irqsave(&ssp->port, &flags);
- else
- uart_port_lock_irqsave(&ssp->port, &flags);
+ if (!nbcon_enter_unsafe(wctxt))
+ return;
ier = __ssp_readl(ssp, SIFIVE_SERIAL_IE_OFFS);
__ssp_writel(0, SIFIVE_SERIAL_IE_OFFS, ssp);
- uart_console_write(&ssp->port, s, count, sifive_serial_console_putchar);
+ if (!ssp->console_line_ended)
+ uart_console_write(port, "\n", 1, sifive_serial_console_putchar);
+ uart_console_write(port, wctxt->outbuf, wctxt->len,
+ sifive_serial_console_putchar);
__ssp_writel(ier, SIFIVE_SERIAL_IE_OFFS, ssp);
- if (locked)
- uart_port_unlock_irqrestore(&ssp->port, flags);
+ nbcon_exit_unsafe(wctxt);
+}
+
+static void sifive_serial_console_write_thread(struct console *co,
+ struct nbcon_write_context *wctxt)
+{
+ struct sifive_serial_port *ssp = sifive_serial_console_ports[co->index];
+ struct uart_port *port = &ssp->port;
+ unsigned int ier;
+
+ if (!ssp)
+ return;
+
+ if (!nbcon_enter_unsafe(wctxt))
+ return;
+
+ ier = __ssp_readl(ssp, SIFIVE_SERIAL_IE_OFFS);
+ __ssp_writel(0, SIFIVE_SERIAL_IE_OFFS, ssp);
+
+ if (nbcon_exit_unsafe(wctxt)) {
+ int len = READ_ONCE(wctxt->len);
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (!nbcon_enter_unsafe(wctxt))
+ break;
+
+ uart_console_write(port, wctxt->outbuf + i, 1,
+ sifive_serial_console_putchar);
+
+ if (!nbcon_exit_unsafe(wctxt))
+ break;
+ }
+ }
+
+ while (!nbcon_enter_unsafe(wctxt))
+ nbcon_reacquire_nobuf(wctxt);
+
+ __ssp_writel(ier, SIFIVE_SERIAL_IE_OFFS, ssp);
+
+ nbcon_exit_unsafe(wctxt);
}
static int sifive_serial_console_setup(struct console *co, char *options)
@@ -829,6 +885,8 @@ static int sifive_serial_console_setup(struct console *co, char *options)
if (!ssp)
return -ENODEV;
+ ssp->console_line_ended = true;
+
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
@@ -839,10 +897,13 @@ static struct uart_driver sifive_serial_uart_driver;
static struct console sifive_serial_console = {
.name = SIFIVE_TTY_PREFIX,
- .write = sifive_serial_console_write,
+ .write_atomic = sifive_serial_console_write_atomic,
+ .write_thread = sifive_serial_console_write_thread,
+ .device_lock = sifive_serial_device_lock,
+ .device_unlock = sifive_serial_device_unlock,
.device = uart_console_device,
.setup = sifive_serial_console_setup,
- .flags = CON_PRINTBUFFER,
+ .flags = CON_PRINTBUFFER | CON_NBCON,
.index = -1,
.data = &sifive_serial_uart_driver,
};
--
2.34.1
On Sat 2025-04-05 23:59:15, Ryo Takakura 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@gmail.com> > Reviewed-by: John Ogness <john.ogness@linutronix.de> I do not have the hardware around so I could not test it. But the code looks good. With the added comment (reported by the robot): Reviewed-by: Petr Mladek <pmladek@suse.com> Best Regards, Petr
Hi Petr! On Thu, 10 Apr 2025 14:29:33 +0200, Petr Mladek wrote: >On Sat 2025-04-05 23:59:15, Ryo Takakura 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@gmail.com> >> Reviewed-by: John Ogness <john.ogness@linutronix.de> > >I do not have the hardware around so I could not test it. >But the code looks good. With the added comment (reported >by the robot): > >Reviewed-by: Petr Mladek <pmladek@suse.com> Thanks for reviewing, I appreciate it! I'll add your Reviewed-by with the comment for v3. Sincerely, Ryo Takakura >Best Regards, >Petr
Hi Ryo,
kernel test robot noticed the following build warnings:
[auto build test WARNING on tty/tty-testing]
[also build test WARNING on tty/tty-next tty/tty-linus linus/master v6.14 next-20250404]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Ryo-Takakura/serial-sifive-Switch-to-nbcon-console/20250405-230051
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-testing
patch link: https://lore.kernel.org/r/20250405145915.493173-1-ryotkkr98%40gmail.com
patch subject: [PATCH v2] serial: sifive: Switch to nbcon console
config: arm-randconfig-002-20250406 (https://download.01.org/0day-ci/archive/20250406/202504060816.EWk91sJS-lkp@intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 7.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250406/202504060816.EWk91sJS-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202504060816.EWk91sJS-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/tty/serial/sifive.c:155: warning: Function parameter or struct member 'console_line_ended' not described in 'sifive_serial_port'
vim +155 drivers/tty/serial/sifive.c
45c054d0815b15 Paul Walmsley 2019-04-12 131
45c054d0815b15 Paul Walmsley 2019-04-12 132 /*
45c054d0815b15 Paul Walmsley 2019-04-12 133 *
45c054d0815b15 Paul Walmsley 2019-04-12 134 */
45c054d0815b15 Paul Walmsley 2019-04-12 135
45c054d0815b15 Paul Walmsley 2019-04-12 136 /**
180bb243de730c Lee Jones 2020-11-04 137 * struct sifive_serial_port - driver-specific data extension to struct uart_port
45c054d0815b15 Paul Walmsley 2019-04-12 138 * @port: struct uart_port embedded in this struct
45c054d0815b15 Paul Walmsley 2019-04-12 139 * @dev: struct device *
45c054d0815b15 Paul Walmsley 2019-04-12 140 * @ier: shadowed copy of the interrupt enable register
45c054d0815b15 Paul Walmsley 2019-04-12 141 * @baud_rate: UART serial line rate (e.g., 115200 baud)
180bb243de730c Lee Jones 2020-11-04 142 * @clk: reference to this device's clock
45c054d0815b15 Paul Walmsley 2019-04-12 143 * @clk_notifier: clock rate change notifier for upstream clock changes
45c054d0815b15 Paul Walmsley 2019-04-12 144 *
45c054d0815b15 Paul Walmsley 2019-04-12 145 * Configuration data specific to this SiFive UART.
45c054d0815b15 Paul Walmsley 2019-04-12 146 */
45c054d0815b15 Paul Walmsley 2019-04-12 147 struct sifive_serial_port {
45c054d0815b15 Paul Walmsley 2019-04-12 148 struct uart_port port;
45c054d0815b15 Paul Walmsley 2019-04-12 149 struct device *dev;
45c054d0815b15 Paul Walmsley 2019-04-12 150 unsigned char ier;
45c054d0815b15 Paul Walmsley 2019-04-12 151 unsigned long baud_rate;
45c054d0815b15 Paul Walmsley 2019-04-12 152 struct clk *clk;
45c054d0815b15 Paul Walmsley 2019-04-12 153 struct notifier_block clk_notifier;
328ee9dbff3941 Ryo Takakura 2025-04-05 154 bool console_line_ended;
45c054d0815b15 Paul Walmsley 2019-04-12 @155 };
45c054d0815b15 Paul Walmsley 2019-04-12 156
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
On Sun, 6 Apr 2025 08:48:12 +0800, kernel test robot wrote:
>kernel test robot noticed the following build warnings:
>
>[auto build test WARNING on tty/tty-testing]
>[also build test WARNING on tty/tty-next tty/tty-linus linus/master v6.14 next-20250404]
>[If your patch is applied to the wrong git tree, kindly drop us a note.
>And when submitting patch, we suggest to use '--base' as documented in
>https://git-scm.com/docs/git-format-patch#_base_tree_information]
>
>url: https://github.com/intel-lab-lkp/linux/commits/Ryo-Takakura/serial-sifive-Switch-to-nbcon-console/20250405-230051
>base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-testing
>patch link: https://lore.kernel.org/r/20250405145915.493173-1-ryotkkr98%40gmail.com
>patch subject: [PATCH v2] serial: sifive: Switch to nbcon console
>config: arm-randconfig-002-20250406 (https://download.01.org/0day-ci/archive/20250406/202504060816.EWk91sJS-lkp@intel.com/config)
>compiler: arm-linux-gnueabi-gcc (GCC) 7.5.0
>reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250406/202504060816.EWk91sJS-lkp@intel.com/reproduce)
>
>If you fix the issue in a separate patch/commit (i.e. not just a new version of
>the same patch/commit), kindly add following tags
>| Reported-by: kernel test robot <lkp@intel.com>
>| Closes: https://lore.kernel.org/oe-kbuild-all/202504060816.EWk91sJS-lkp@intel.com/
>
>All warnings (new ones prefixed by >>):
>
>>> drivers/tty/serial/sifive.c:155: warning: Function parameter or struct member 'console_line_ended' not described in 'sifive_serial_port'
Thank you for reporting.
I overlooked this... I'll add a description for it.
Sincerely,
Ryo Takakura
>vim +155 drivers/tty/serial/sifive.c
>
>45c054d0815b15 Paul Walmsley 2019-04-12 131
>45c054d0815b15 Paul Walmsley 2019-04-12 132 /*
>45c054d0815b15 Paul Walmsley 2019-04-12 133 *
>45c054d0815b15 Paul Walmsley 2019-04-12 134 */
>45c054d0815b15 Paul Walmsley 2019-04-12 135
>45c054d0815b15 Paul Walmsley 2019-04-12 136 /**
>180bb243de730c Lee Jones 2020-11-04 137 * struct sifive_serial_port - driver-specific data extension to struct uart_port
>45c054d0815b15 Paul Walmsley 2019-04-12 138 * @port: struct uart_port embedded in this struct
>45c054d0815b15 Paul Walmsley 2019-04-12 139 * @dev: struct device *
>45c054d0815b15 Paul Walmsley 2019-04-12 140 * @ier: shadowed copy of the interrupt enable register
>45c054d0815b15 Paul Walmsley 2019-04-12 141 * @baud_rate: UART serial line rate (e.g., 115200 baud)
>180bb243de730c Lee Jones 2020-11-04 142 * @clk: reference to this device's clock
>45c054d0815b15 Paul Walmsley 2019-04-12 143 * @clk_notifier: clock rate change notifier for upstream clock changes
>45c054d0815b15 Paul Walmsley 2019-04-12 144 *
>45c054d0815b15 Paul Walmsley 2019-04-12 145 * Configuration data specific to this SiFive UART.
>45c054d0815b15 Paul Walmsley 2019-04-12 146 */
>45c054d0815b15 Paul Walmsley 2019-04-12 147 struct sifive_serial_port {
>45c054d0815b15 Paul Walmsley 2019-04-12 148 struct uart_port port;
>45c054d0815b15 Paul Walmsley 2019-04-12 149 struct device *dev;
>45c054d0815b15 Paul Walmsley 2019-04-12 150 unsigned char ier;
>45c054d0815b15 Paul Walmsley 2019-04-12 151 unsigned long baud_rate;
>45c054d0815b15 Paul Walmsley 2019-04-12 152 struct clk *clk;
>45c054d0815b15 Paul Walmsley 2019-04-12 153 struct notifier_block clk_notifier;
>328ee9dbff3941 Ryo Takakura 2025-04-05 154 bool console_line_ended;
>45c054d0815b15 Paul Walmsley 2019-04-12 @155 };
>45c054d0815b15 Paul Walmsley 2019-04-12 156
>
>--
>0-DAY CI Kernel Test Service
>https://github.com/intel/lkp-tests/wiki
© 2016 - 2026 Red Hat, Inc.