summaryrefslogtreecommitdiffstats
path: root/drivers/tty/vcc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/vcc.c')
-rw-r--r--drivers/tty/vcc.c83
1 files changed, 82 insertions, 1 deletions
diff --git a/drivers/tty/vcc.c b/drivers/tty/vcc.c
index 4fd8dd0bda5e..ba3384d23d79 100644
--- a/drivers/tty/vcc.c
+++ b/drivers/tty/vcc.c
@@ -4,15 +4,26 @@
*/
#include <linux/module.h>
+#include <linux/tty.h>
#define DRV_MODULE_NAME "vcc"
#define DRV_MODULE_VERSION "1.1"
#define DRV_MODULE_RELDATE "July 1, 2017"
+static char version[] =
+ DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")";
+
MODULE_DESCRIPTION("Sun LDOM virtual console concentrator driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
+#define VCC_MAX_PORTS 1024
+#define VCC_MINOR_START 0 /* must be zero */
+
+static const char vcc_driver_name[] = "vcc";
+static const char vcc_device_node[] = "vcc";
+static struct tty_driver *vcc_tty_driver;
+
int vcc_dbg;
int vcc_dbg_ldc;
int vcc_dbg_vio;
@@ -46,13 +57,83 @@ module_param(vcc_dbg_vio, uint, 0664);
} \
} while (0) \
-static int __init vcc_init(void)
+/* Note: Be careful when adding flags to this line discipline. Don't
+ * add anything that will cause echoing or we'll go into recursive
+ * loop echoing chars back and forth with the console drivers.
+ */
+static struct ktermios vcc_tty_termios = {
+ .c_iflag = IGNBRK | IGNPAR,
+ .c_oflag = OPOST,
+ .c_cflag = B38400 | CS8 | CREAD | HUPCL,
+ .c_cc = INIT_C_CC,
+ .c_ispeed = 38400,
+ .c_ospeed = 38400
+};
+
+static const struct tty_operations vcc_ops;
+
+#define VCC_TTY_FLAGS (TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_REAL_RAW)
+
+static int vcc_tty_init(void)
{
+ int rv;
+
+ pr_info("VCC: %s\n", version);
+
+ vcc_tty_driver = tty_alloc_driver(VCC_MAX_PORTS, VCC_TTY_FLAGS);
+ if (!vcc_tty_driver) {
+ pr_err("VCC: TTY driver alloc failed\n");
+ return -ENOMEM;
+ }
+
+ vcc_tty_driver->driver_name = vcc_driver_name;
+ vcc_tty_driver->name = vcc_device_node;
+
+ vcc_tty_driver->minor_start = VCC_MINOR_START;
+ vcc_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM;
+ vcc_tty_driver->init_termios = vcc_tty_termios;
+
+ tty_set_operations(vcc_tty_driver, &vcc_ops);
+
+ rv = tty_register_driver(vcc_tty_driver);
+ if (rv) {
+ pr_err("VCC: TTY driver registration failed\n");
+ put_tty_driver(vcc_tty_driver);
+ vcc_tty_driver = NULL;
+ return rv;
+ }
+
+ vccdbg("VCC: TTY driver registered\n");
+
return 0;
}
+static void vcc_tty_exit(void)
+{
+ tty_unregister_driver(vcc_tty_driver);
+ put_tty_driver(vcc_tty_driver);
+ vccdbg("VCC: TTY driver unregistered\n");
+
+ vcc_tty_driver = NULL;
+}
+
+static int __init vcc_init(void)
+{
+ int rv;
+
+ rv = vcc_tty_init();
+ if (rv) {
+ pr_err("VCC: TTY init failed\n");
+ return rv;
+ }
+
+ return rv;
+}
+
static void __exit vcc_exit(void)
{
+ vcc_tty_exit();
+ vccdbg("VCC: TTY driver unregistered\n");
}
module_init(vcc_init);