tty: New RISC-V SBI console driver
authorPalmer Dabbelt <palmer@sifive.com>
Thu, 8 Mar 2018 22:27:34 +0000 (14:27 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 9 Mar 2018 18:19:28 +0000 (10:19 -0800)
The RISC-V ISA defines a simple console that is availiable via SBI calls
on all systems.  The SBI console is designed to be availiable at all
times, so while it's most natural to use this as an early printk target
it's also possible to use this as the system console when there isn't a
better one availiable.

This patch adds support for the RISC-V SBI console via the HVC
infastructure.  It's entirely independent from our early printk support,
which results in early boot messages appearing twice over the SBI
console.  As far as I can tell that's the fault of our early printk
support (we should support earlycon) as opposed to this driver.

There is one checkpatch.pl warning here: to check the MAINTAINERS file.
They're all matched by the "K: riscv" line.

Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/hvc/Kconfig
drivers/tty/hvc/Makefile
drivers/tty/hvc/hvc_riscv_sbi.c [new file with mode: 0644]

index fec457edad14800c5ed07476afe5f2a9986478c8..e7cc617d6e4577d7e43f159c06b009bf94743a9d 100644 (file)
@@ -97,6 +97,16 @@ config HVC_BFIN_JTAG
         the HVC driver.  If you don't have JTAG, then you probably don't
         want this option.
 
+config HVC_RISCV_SBI
+       bool "RISC-V SBI console support"
+       depends on RISCV
+       select HVC_DRIVER
+       help
+         This enables support for console output via RISC-V SBI calls, which
+         is normally used only during boot to output printk.
+
+         If you don't know what do to here, say Y.
+
 config HVCS
        tristate "IBM Hypervisor Virtual Console Server support"
        depends on PPC_PSERIES && HVC_CONSOLE
index 0b02ec7f1dfd3054cc8a6010a3d3348622351701..83079ae000aeec53d92b59d3da40420162e14cff 100644 (file)
@@ -11,4 +11,5 @@ obj-$(CONFIG_HVC_XEN)         += hvc_xen.o
 obj-$(CONFIG_HVC_IUCV)         += hvc_iucv.o
 obj-$(CONFIG_HVC_UDBG)         += hvc_udbg.o
 obj-$(CONFIG_HVC_BFIN_JTAG)    += hvc_bfin_jtag.o
+obj-$(CONFIG_HVC_RISCV_SBI)    += hvc_riscv_sbi.o
 obj-$(CONFIG_HVCS)             += hvcs.o
diff --git a/drivers/tty/hvc/hvc_riscv_sbi.c b/drivers/tty/hvc/hvc_riscv_sbi.c
new file mode 100644 (file)
index 0000000..75155bd
--- /dev/null
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2008 David Gibson, IBM Corporation
+ * Copyright (C) 2012 Regents of the University of California
+ * Copyright (C) 2017 SiFive
+ */
+
+#include <linux/console.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+
+#include <asm/sbi.h>
+
+#include "hvc_console.h"
+
+static int hvc_sbi_tty_put(uint32_t vtermno, const char *buf, int count)
+{
+       int i;
+
+       for (i = 0; i < count; i++)
+               sbi_console_putchar(buf[i]);
+
+       return i;
+}
+
+static int hvc_sbi_tty_get(uint32_t vtermno, char *buf, int count)
+{
+       int i, c;
+
+       for (i = 0; i < count; i++) {
+               c = sbi_console_getchar();
+               if (c < 0)
+                       break;
+               buf[i] = c;
+       }
+
+       return i;
+}
+
+static const struct hv_ops hvc_sbi_ops = {
+       .get_chars = hvc_sbi_tty_get,
+       .put_chars = hvc_sbi_tty_put,
+};
+
+static int __init hvc_sbi_init(void)
+{
+       return PTR_ERR_OR_ZERO(hvc_alloc(0, 0, &hvc_sbi_ops, 16));
+}
+device_initcall(hvc_sbi_init);
+
+static int __init hvc_sbi_console_init(void)
+{
+       hvc_instantiate(0, 0, &hvc_sbi_ops);
+       add_preferred_console("hvc", 0, NULL);
+
+       return 0;
+}
+console_initcall(hvc_sbi_console_init);