13117ff13SVincent Whitchurch // SPDX-License-Identifier: GPL-2.0
23117ff13SVincent Whitchurch /*
33117ff13SVincent Whitchurch * Copyright (C) 2019 Axis Communications AB
43117ff13SVincent Whitchurch *
53117ff13SVincent Whitchurch * Based on ttyprintk.c:
63117ff13SVincent Whitchurch * Copyright (C) 2010 Samo Pogacnik
73117ff13SVincent Whitchurch */
83117ff13SVincent Whitchurch
93117ff13SVincent Whitchurch #include <linux/console.h>
103117ff13SVincent Whitchurch #include <linux/module.h>
113117ff13SVincent Whitchurch #include <linux/tty.h>
123117ff13SVincent Whitchurch
133117ff13SVincent Whitchurch static const struct tty_port_operations ttynull_port_ops;
143117ff13SVincent Whitchurch static struct tty_driver *ttynull_driver;
153117ff13SVincent Whitchurch static struct tty_port ttynull_port;
163117ff13SVincent Whitchurch
ttynull_open(struct tty_struct * tty,struct file * filp)173117ff13SVincent Whitchurch static int ttynull_open(struct tty_struct *tty, struct file *filp)
183117ff13SVincent Whitchurch {
193117ff13SVincent Whitchurch return tty_port_open(&ttynull_port, tty, filp);
203117ff13SVincent Whitchurch }
213117ff13SVincent Whitchurch
ttynull_close(struct tty_struct * tty,struct file * filp)223117ff13SVincent Whitchurch static void ttynull_close(struct tty_struct *tty, struct file *filp)
233117ff13SVincent Whitchurch {
243117ff13SVincent Whitchurch tty_port_close(&ttynull_port, tty, filp);
253117ff13SVincent Whitchurch }
263117ff13SVincent Whitchurch
ttynull_hangup(struct tty_struct * tty)273117ff13SVincent Whitchurch static void ttynull_hangup(struct tty_struct *tty)
283117ff13SVincent Whitchurch {
293117ff13SVincent Whitchurch tty_port_hangup(&ttynull_port);
303117ff13SVincent Whitchurch }
313117ff13SVincent Whitchurch
ttynull_write(struct tty_struct * tty,const u8 * buf,size_t count)3295713967SJiri Slaby (SUSE) static ssize_t ttynull_write(struct tty_struct *tty, const u8 *buf,
3395713967SJiri Slaby (SUSE) size_t count)
343117ff13SVincent Whitchurch {
353117ff13SVincent Whitchurch return count;
363117ff13SVincent Whitchurch }
373117ff13SVincent Whitchurch
ttynull_write_room(struct tty_struct * tty)3803b3b1a2SJiri Slaby static unsigned int ttynull_write_room(struct tty_struct *tty)
393117ff13SVincent Whitchurch {
403117ff13SVincent Whitchurch return 65536;
413117ff13SVincent Whitchurch }
423117ff13SVincent Whitchurch
433117ff13SVincent Whitchurch static const struct tty_operations ttynull_ops = {
443117ff13SVincent Whitchurch .open = ttynull_open,
453117ff13SVincent Whitchurch .close = ttynull_close,
463117ff13SVincent Whitchurch .hangup = ttynull_hangup,
473117ff13SVincent Whitchurch .write = ttynull_write,
483117ff13SVincent Whitchurch .write_room = ttynull_write_room,
493117ff13SVincent Whitchurch };
503117ff13SVincent Whitchurch
ttynull_device(struct console * c,int * index)513117ff13SVincent Whitchurch static struct tty_driver *ttynull_device(struct console *c, int *index)
523117ff13SVincent Whitchurch {
533117ff13SVincent Whitchurch *index = 0;
543117ff13SVincent Whitchurch return ttynull_driver;
553117ff13SVincent Whitchurch }
563117ff13SVincent Whitchurch
573117ff13SVincent Whitchurch static struct console ttynull_console = {
583117ff13SVincent Whitchurch .name = "ttynull",
593117ff13SVincent Whitchurch .device = ttynull_device,
603117ff13SVincent Whitchurch };
613117ff13SVincent Whitchurch
ttynull_init(void)623117ff13SVincent Whitchurch static int __init ttynull_init(void)
633117ff13SVincent Whitchurch {
643117ff13SVincent Whitchurch struct tty_driver *driver;
653117ff13SVincent Whitchurch int ret;
663117ff13SVincent Whitchurch
673117ff13SVincent Whitchurch driver = tty_alloc_driver(1,
683117ff13SVincent Whitchurch TTY_DRIVER_RESET_TERMIOS |
693117ff13SVincent Whitchurch TTY_DRIVER_REAL_RAW |
703117ff13SVincent Whitchurch TTY_DRIVER_UNNUMBERED_NODE);
713117ff13SVincent Whitchurch if (IS_ERR(driver))
723117ff13SVincent Whitchurch return PTR_ERR(driver);
733117ff13SVincent Whitchurch
743117ff13SVincent Whitchurch tty_port_init(&ttynull_port);
753117ff13SVincent Whitchurch ttynull_port.ops = &ttynull_port_ops;
763117ff13SVincent Whitchurch
773117ff13SVincent Whitchurch driver->driver_name = "ttynull";
783117ff13SVincent Whitchurch driver->name = "ttynull";
793117ff13SVincent Whitchurch driver->type = TTY_DRIVER_TYPE_CONSOLE;
803117ff13SVincent Whitchurch driver->init_termios = tty_std_termios;
813117ff13SVincent Whitchurch driver->init_termios.c_oflag = OPOST | OCRNL | ONOCR | ONLRET;
823117ff13SVincent Whitchurch tty_set_operations(driver, &ttynull_ops);
833117ff13SVincent Whitchurch tty_port_link_device(&ttynull_port, driver, 0);
843117ff13SVincent Whitchurch
853117ff13SVincent Whitchurch ret = tty_register_driver(driver);
863117ff13SVincent Whitchurch if (ret < 0) {
879f90a4ddSJiri Slaby tty_driver_kref_put(driver);
883117ff13SVincent Whitchurch tty_port_destroy(&ttynull_port);
893117ff13SVincent Whitchurch return ret;
903117ff13SVincent Whitchurch }
913117ff13SVincent Whitchurch
923117ff13SVincent Whitchurch ttynull_driver = driver;
933117ff13SVincent Whitchurch register_console(&ttynull_console);
943117ff13SVincent Whitchurch
953117ff13SVincent Whitchurch return 0;
963117ff13SVincent Whitchurch }
973117ff13SVincent Whitchurch
ttynull_exit(void)983117ff13SVincent Whitchurch static void __exit ttynull_exit(void)
993117ff13SVincent Whitchurch {
1003117ff13SVincent Whitchurch unregister_console(&ttynull_console);
1013117ff13SVincent Whitchurch tty_unregister_driver(ttynull_driver);
1029f90a4ddSJiri Slaby tty_driver_kref_put(ttynull_driver);
1033117ff13SVincent Whitchurch tty_port_destroy(&ttynull_port);
1043117ff13SVincent Whitchurch }
1053117ff13SVincent Whitchurch
1063117ff13SVincent Whitchurch module_init(ttynull_init);
1073117ff13SVincent Whitchurch module_exit(ttynull_exit);
1083117ff13SVincent Whitchurch
109*f0a17485SJeff Johnson MODULE_DESCRIPTION("NULL TTY driver");
1103117ff13SVincent Whitchurch MODULE_LICENSE("GPL v2");
111