perf probe: Fix memory leak when synthesizing SDT probes
[linux-2.6-microblaze.git] / drivers / tty / ttynull.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2019 Axis Communications AB
4  *
5  * The console is useful for userspace applications which expect a console
6  * device to work without modifications even when no console is available
7  * or desired.
8  *
9  * In order to use this driver, you should redirect the console to this
10  * TTY, or boot the kernel with console=ttynull.
11  *
12  * Based on ttyprintk.c:
13  *  Copyright (C) 2010 Samo Pogacnik
14  */
15
16 #include <linux/console.h>
17 #include <linux/module.h>
18 #include <linux/tty.h>
19
20 static const struct tty_port_operations ttynull_port_ops;
21 static struct tty_driver *ttynull_driver;
22 static struct tty_port ttynull_port;
23
24 static int ttynull_open(struct tty_struct *tty, struct file *filp)
25 {
26         return tty_port_open(&ttynull_port, tty, filp);
27 }
28
29 static void ttynull_close(struct tty_struct *tty, struct file *filp)
30 {
31         tty_port_close(&ttynull_port, tty, filp);
32 }
33
34 static void ttynull_hangup(struct tty_struct *tty)
35 {
36         tty_port_hangup(&ttynull_port);
37 }
38
39 static int ttynull_write(struct tty_struct *tty, const unsigned char *buf,
40                          int count)
41 {
42         return count;
43 }
44
45 static int ttynull_write_room(struct tty_struct *tty)
46 {
47         return 65536;
48 }
49
50 static const struct tty_operations ttynull_ops = {
51         .open = ttynull_open,
52         .close = ttynull_close,
53         .hangup = ttynull_hangup,
54         .write = ttynull_write,
55         .write_room = ttynull_write_room,
56 };
57
58 static struct tty_driver *ttynull_device(struct console *c, int *index)
59 {
60         *index = 0;
61         return ttynull_driver;
62 }
63
64 static struct console ttynull_console = {
65         .name = "ttynull",
66         .device = ttynull_device,
67 };
68
69 void __init register_ttynull_console(void)
70 {
71         if (!ttynull_driver)
72                 return;
73
74         if (add_preferred_console(ttynull_console.name, 0, NULL))
75                 return;
76
77         register_console(&ttynull_console);
78 }
79
80 static int __init ttynull_init(void)
81 {
82         struct tty_driver *driver;
83         int ret;
84
85         driver = tty_alloc_driver(1,
86                 TTY_DRIVER_RESET_TERMIOS |
87                 TTY_DRIVER_REAL_RAW |
88                 TTY_DRIVER_UNNUMBERED_NODE);
89         if (IS_ERR(driver))
90                 return PTR_ERR(driver);
91
92         tty_port_init(&ttynull_port);
93         ttynull_port.ops = &ttynull_port_ops;
94
95         driver->driver_name = "ttynull";
96         driver->name = "ttynull";
97         driver->type = TTY_DRIVER_TYPE_CONSOLE;
98         driver->init_termios = tty_std_termios;
99         driver->init_termios.c_oflag = OPOST | OCRNL | ONOCR | ONLRET;
100         tty_set_operations(driver, &ttynull_ops);
101         tty_port_link_device(&ttynull_port, driver, 0);
102
103         ret = tty_register_driver(driver);
104         if (ret < 0) {
105                 put_tty_driver(driver);
106                 tty_port_destroy(&ttynull_port);
107                 return ret;
108         }
109
110         ttynull_driver = driver;
111         register_console(&ttynull_console);
112
113         return 0;
114 }
115
116 static void __exit ttynull_exit(void)
117 {
118         unregister_console(&ttynull_console);
119         tty_unregister_driver(ttynull_driver);
120         put_tty_driver(ttynull_driver);
121         tty_port_destroy(&ttynull_port);
122 }
123
124 module_init(ttynull_init);
125 module_exit(ttynull_exit);
126
127 MODULE_LICENSE("GPL v2");