sparc64: vcc: TTY driver initialization and cleanup
[linux-2.6-block.git] / drivers / tty / vcc.c
CommitLineData
55bd2133
JR
1/* vcc.c: sun4v virtual channel concentrator
2 *
3 * Copyright (C) 2017 Oracle. All rights reserved.
4 */
5
6#include <linux/module.h>
ce808b74 7#include <linux/tty.h>
55bd2133 8
f283ebd5
JR
9#define DRV_MODULE_NAME "vcc"
10#define DRV_MODULE_VERSION "1.1"
11#define DRV_MODULE_RELDATE "July 1, 2017"
12
ce808b74
JR
13static char version[] =
14 DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")";
15
f283ebd5
JR
16MODULE_DESCRIPTION("Sun LDOM virtual console concentrator driver");
17MODULE_LICENSE("GPL");
18MODULE_VERSION(DRV_MODULE_VERSION);
19
ce808b74
JR
20#define VCC_MAX_PORTS 1024
21#define VCC_MINOR_START 0 /* must be zero */
22
23static const char vcc_driver_name[] = "vcc";
24static const char vcc_device_node[] = "vcc";
25static struct tty_driver *vcc_tty_driver;
26
f283ebd5
JR
27int vcc_dbg;
28int vcc_dbg_ldc;
29int vcc_dbg_vio;
30
31module_param(vcc_dbg, uint, 0664);
32module_param(vcc_dbg_ldc, uint, 0664);
33module_param(vcc_dbg_vio, uint, 0664);
34
35#define VCC_DBG_DRV 0x1
36#define VCC_DBG_LDC 0x2
37#define VCC_DBG_PKT 0x4
38
39#define vccdbg(f, a...) \
40 do { \
41 if (vcc_dbg & VCC_DBG_DRV) \
42 pr_info(f, ## a); \
43 } while (0) \
44
45#define vccdbgl(l) \
46 do { \
47 if (vcc_dbg & VCC_DBG_LDC) \
48 ldc_print(l); \
49 } while (0) \
50
51#define vccdbgp(pkt) \
52 do { \
53 if (vcc_dbg & VCC_DBG_PKT) { \
54 int i; \
55 for (i = 0; i < pkt.tag.stype; i++) \
56 pr_info("[%c]", pkt.data[i]); \
57 } \
58 } while (0) \
59
ce808b74
JR
60/* Note: Be careful when adding flags to this line discipline. Don't
61 * add anything that will cause echoing or we'll go into recursive
62 * loop echoing chars back and forth with the console drivers.
63 */
64static struct ktermios vcc_tty_termios = {
65 .c_iflag = IGNBRK | IGNPAR,
66 .c_oflag = OPOST,
67 .c_cflag = B38400 | CS8 | CREAD | HUPCL,
68 .c_cc = INIT_C_CC,
69 .c_ispeed = 38400,
70 .c_ospeed = 38400
71};
72
73static const struct tty_operations vcc_ops;
74
75#define VCC_TTY_FLAGS (TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_REAL_RAW)
76
77static int vcc_tty_init(void)
55bd2133 78{
ce808b74
JR
79 int rv;
80
81 pr_info("VCC: %s\n", version);
82
83 vcc_tty_driver = tty_alloc_driver(VCC_MAX_PORTS, VCC_TTY_FLAGS);
84 if (!vcc_tty_driver) {
85 pr_err("VCC: TTY driver alloc failed\n");
86 return -ENOMEM;
87 }
88
89 vcc_tty_driver->driver_name = vcc_driver_name;
90 vcc_tty_driver->name = vcc_device_node;
91
92 vcc_tty_driver->minor_start = VCC_MINOR_START;
93 vcc_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM;
94 vcc_tty_driver->init_termios = vcc_tty_termios;
95
96 tty_set_operations(vcc_tty_driver, &vcc_ops);
97
98 rv = tty_register_driver(vcc_tty_driver);
99 if (rv) {
100 pr_err("VCC: TTY driver registration failed\n");
101 put_tty_driver(vcc_tty_driver);
102 vcc_tty_driver = NULL;
103 return rv;
104 }
105
106 vccdbg("VCC: TTY driver registered\n");
107
55bd2133
JR
108 return 0;
109}
110
ce808b74
JR
111static void vcc_tty_exit(void)
112{
113 tty_unregister_driver(vcc_tty_driver);
114 put_tty_driver(vcc_tty_driver);
115 vccdbg("VCC: TTY driver unregistered\n");
116
117 vcc_tty_driver = NULL;
118}
119
120static int __init vcc_init(void)
121{
122 int rv;
123
124 rv = vcc_tty_init();
125 if (rv) {
126 pr_err("VCC: TTY init failed\n");
127 return rv;
128 }
129
130 return rv;
131}
132
55bd2133
JR
133static void __exit vcc_exit(void)
134{
ce808b74
JR
135 vcc_tty_exit();
136 vccdbg("VCC: TTY driver unregistered\n");
55bd2133
JR
137}
138
139module_init(vcc_init);
140module_exit(vcc_exit);