aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS2
-rw-r--r--drivers/tty/ehv_bytechan.c17
-rw-r--r--drivers/tty/serdev/core.c12
-rw-r--r--drivers/tty/serdev/serdev-ttyport.c21
-rw-r--r--drivers/tty/serial/8250/8250_port.c21
-rw-r--r--drivers/tty/serial/altera_jtaguart.c1
-rw-r--r--drivers/tty/serial/altera_uart.c1
-rw-r--r--drivers/tty/serial/efm32-uart.c11
-rw-r--r--drivers/tty/serial/ifx6x60.c2
-rw-r--r--drivers/tty/serial/imx.c14
-rw-r--r--drivers/tty/serial/serial_core.c6
-rw-r--r--drivers/tty/tty_port.c75
-rw-r--r--include/linux/serdev.h19
-rw-r--r--include/linux/tty.h9
14 files changed, 162 insertions, 49 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 9e984645c4b0..053c3bdd1fe5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7143,7 +7143,7 @@ S: Maintained
7143F: drivers/media/platform/rcar_jpu.c 7143F: drivers/media/platform/rcar_jpu.c
7144 7144
7145JSM Neo PCI based serial card 7145JSM Neo PCI based serial card
7146M: Gabriel Krisman Bertazi <krisman@linux.vnet.ibm.com> 7146M: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com>
7147L: linux-serial@vger.kernel.org 7147L: linux-serial@vger.kernel.org
7148S: Maintained 7148S: Maintained
7149F: drivers/tty/serial/jsm/ 7149F: drivers/tty/serial/jsm/
diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c
index 7ac9bcdf1e61..61fe8d6fd24e 100644
--- a/drivers/tty/ehv_bytechan.c
+++ b/drivers/tty/ehv_bytechan.c
@@ -764,7 +764,7 @@ static int __init ehv_bc_init(void)
764 ehv_bc_driver = alloc_tty_driver(count); 764 ehv_bc_driver = alloc_tty_driver(count);
765 if (!ehv_bc_driver) { 765 if (!ehv_bc_driver) {
766 ret = -ENOMEM; 766 ret = -ENOMEM;
767 goto error; 767 goto err_free_bcs;
768 } 768 }
769 769
770 ehv_bc_driver->driver_name = "ehv-bc"; 770 ehv_bc_driver->driver_name = "ehv-bc";
@@ -778,24 +778,23 @@ static int __init ehv_bc_init(void)
778 ret = tty_register_driver(ehv_bc_driver); 778 ret = tty_register_driver(ehv_bc_driver);
779 if (ret) { 779 if (ret) {
780 pr_err("ehv-bc: could not register tty driver (ret=%i)\n", ret); 780 pr_err("ehv-bc: could not register tty driver (ret=%i)\n", ret);
781 goto error; 781 goto err_put_tty_driver;
782 } 782 }
783 783
784 ret = platform_driver_register(&ehv_bc_tty_driver); 784 ret = platform_driver_register(&ehv_bc_tty_driver);
785 if (ret) { 785 if (ret) {
786 pr_err("ehv-bc: could not register platform driver (ret=%i)\n", 786 pr_err("ehv-bc: could not register platform driver (ret=%i)\n",
787 ret); 787 ret);
788 goto error; 788 goto err_deregister_tty_driver;
789 } 789 }
790 790
791 return 0; 791 return 0;
792 792
793error: 793err_deregister_tty_driver:
794 if (ehv_bc_driver) { 794 tty_unregister_driver(ehv_bc_driver);
795 tty_unregister_driver(ehv_bc_driver); 795err_put_tty_driver:
796 put_tty_driver(ehv_bc_driver); 796 put_tty_driver(ehv_bc_driver);
797 } 797err_free_bcs:
798
799 kfree(bcs); 798 kfree(bcs);
800 799
801 return ret; 800 return ret;
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index 433de5ea9b02..f71b47334149 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -122,6 +122,18 @@ void serdev_device_write_wakeup(struct serdev_device *serdev)
122} 122}
123EXPORT_SYMBOL_GPL(serdev_device_write_wakeup); 123EXPORT_SYMBOL_GPL(serdev_device_write_wakeup);
124 124
125int serdev_device_write_buf(struct serdev_device *serdev,
126 const unsigned char *buf, size_t count)
127{
128 struct serdev_controller *ctrl = serdev->ctrl;
129
130 if (!ctrl || !ctrl->ops->write_buf)
131 return -EINVAL;
132
133 return ctrl->ops->write_buf(ctrl, buf, count);
134}
135EXPORT_SYMBOL_GPL(serdev_device_write_buf);
136
125int serdev_device_write(struct serdev_device *serdev, 137int serdev_device_write(struct serdev_device *serdev,
126 const unsigned char *buf, size_t count, 138 const unsigned char *buf, size_t count,
127 unsigned long timeout) 139 unsigned long timeout)
diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c
index 487c88f6aa0e..d0a021c93986 100644
--- a/drivers/tty/serdev/serdev-ttyport.c
+++ b/drivers/tty/serdev/serdev-ttyport.c
@@ -102,9 +102,6 @@ static int ttyport_open(struct serdev_controller *ctrl)
102 return PTR_ERR(tty); 102 return PTR_ERR(tty);
103 serport->tty = tty; 103 serport->tty = tty;
104 104
105 serport->port->client_ops = &client_ops;
106 serport->port->client_data = ctrl;
107
108 if (tty->ops->open) 105 if (tty->ops->open)
109 tty->ops->open(serport->tty, NULL); 106 tty->ops->open(serport->tty, NULL);
110 else 107 else
@@ -215,6 +212,7 @@ struct device *serdev_tty_port_register(struct tty_port *port,
215 struct device *parent, 212 struct device *parent,
216 struct tty_driver *drv, int idx) 213 struct tty_driver *drv, int idx)
217{ 214{
215 const struct tty_port_client_operations *old_ops;
218 struct serdev_controller *ctrl; 216 struct serdev_controller *ctrl;
219 struct serport *serport; 217 struct serport *serport;
220 int ret; 218 int ret;
@@ -233,28 +231,37 @@ struct device *serdev_tty_port_register(struct tty_port *port,
233 231
234 ctrl->ops = &ctrl_ops; 232 ctrl->ops = &ctrl_ops;
235 233
234 old_ops = port->client_ops;
235 port->client_ops = &client_ops;
236 port->client_data = ctrl;
237
236 ret = serdev_controller_add(ctrl); 238 ret = serdev_controller_add(ctrl);
237 if (ret) 239 if (ret)
238 goto err_controller_put; 240 goto err_reset_data;
239 241
240 dev_info(&ctrl->dev, "tty port %s%d registered\n", drv->name, idx); 242 dev_info(&ctrl->dev, "tty port %s%d registered\n", drv->name, idx);
241 return &ctrl->dev; 243 return &ctrl->dev;
242 244
243err_controller_put: 245err_reset_data:
246 port->client_data = NULL;
247 port->client_ops = old_ops;
244 serdev_controller_put(ctrl); 248 serdev_controller_put(ctrl);
249
245 return ERR_PTR(ret); 250 return ERR_PTR(ret);
246} 251}
247 252
248void serdev_tty_port_unregister(struct tty_port *port) 253int serdev_tty_port_unregister(struct tty_port *port)
249{ 254{
250 struct serdev_controller *ctrl = port->client_data; 255 struct serdev_controller *ctrl = port->client_data;
251 struct serport *serport = serdev_controller_get_drvdata(ctrl); 256 struct serport *serport = serdev_controller_get_drvdata(ctrl);
252 257
253 if (!serport) 258 if (!serport)
254 return; 259 return -ENODEV;
255 260
256 serdev_controller_remove(ctrl); 261 serdev_controller_remove(ctrl);
257 port->client_ops = NULL; 262 port->client_ops = NULL;
258 port->client_data = NULL; 263 port->client_data = NULL;
259 serdev_controller_put(ctrl); 264 serdev_controller_put(ctrl);
265
266 return 0;
260} 267}
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 09a65a3ec7f7..68fd045a7025 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -47,6 +47,7 @@
47/* 47/*
48 * These are definitions for the Exar XR17V35X and XR17(C|D)15X 48 * These are definitions for the Exar XR17V35X and XR17(C|D)15X
49 */ 49 */
50#define UART_EXAR_INT0 0x80
50#define UART_EXAR_SLEEP 0x8b /* Sleep mode */ 51#define UART_EXAR_SLEEP 0x8b /* Sleep mode */
51#define UART_EXAR_DVID 0x8d /* Device identification */ 52#define UART_EXAR_DVID 0x8d /* Device identification */
52 53
@@ -1337,7 +1338,7 @@ out_lock:
1337 /* 1338 /*
1338 * Check if the device is a Fintek F81216A 1339 * Check if the device is a Fintek F81216A
1339 */ 1340 */
1340 if (port->type == PORT_16550A) 1341 if (port->type == PORT_16550A && port->iotype == UPIO_PORT)
1341 fintek_8250_probe(up); 1342 fintek_8250_probe(up);
1342 1343
1343 if (up->capabilities != old_capabilities) { 1344 if (up->capabilities != old_capabilities) {
@@ -1869,17 +1870,13 @@ static int serial8250_default_handle_irq(struct uart_port *port)
1869static int exar_handle_irq(struct uart_port *port) 1870static int exar_handle_irq(struct uart_port *port)
1870{ 1871{
1871 unsigned int iir = serial_port_in(port, UART_IIR); 1872 unsigned int iir = serial_port_in(port, UART_IIR);
1872 int ret; 1873 int ret = 0;
1873 1874
1874 ret = serial8250_handle_irq(port, iir); 1875 if (((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X)) &&
1876 serial_port_in(port, UART_EXAR_INT0) != 0)
1877 ret = 1;
1875 1878
1876 if ((port->type == PORT_XR17V35X) || 1879 ret |= serial8250_handle_irq(port, iir);
1877 (port->type == PORT_XR17D15X)) {
1878 serial_port_in(port, 0x80);
1879 serial_port_in(port, 0x81);
1880 serial_port_in(port, 0x82);
1881 serial_port_in(port, 0x83);
1882 }
1883 1880
1884 return ret; 1881 return ret;
1885} 1882}
@@ -2177,6 +2174,8 @@ int serial8250_do_startup(struct uart_port *port)
2177 serial_port_in(port, UART_RX); 2174 serial_port_in(port, UART_RX);
2178 serial_port_in(port, UART_IIR); 2175 serial_port_in(port, UART_IIR);
2179 serial_port_in(port, UART_MSR); 2176 serial_port_in(port, UART_MSR);
2177 if ((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X))
2178 serial_port_in(port, UART_EXAR_INT0);
2180 2179
2181 /* 2180 /*
2182 * At this point, there's no way the LSR could still be 0xff; 2181 * At this point, there's no way the LSR could still be 0xff;
@@ -2335,6 +2334,8 @@ dont_test_tx_en:
2335 serial_port_in(port, UART_RX); 2334 serial_port_in(port, UART_RX);
2336 serial_port_in(port, UART_IIR); 2335 serial_port_in(port, UART_IIR);
2337 serial_port_in(port, UART_MSR); 2336 serial_port_in(port, UART_MSR);
2337 if ((port->type == PORT_XR17V35X) || (port->type == PORT_XR17D15X))
2338 serial_port_in(port, UART_EXAR_INT0);
2338 up->lsr_saved_flags = 0; 2339 up->lsr_saved_flags = 0;
2339 up->msr_saved_flags = 0; 2340 up->msr_saved_flags = 0;
2340 2341
diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c
index 18e3f8342b85..0475f5d261ce 100644
--- a/drivers/tty/serial/altera_jtaguart.c
+++ b/drivers/tty/serial/altera_jtaguart.c
@@ -478,6 +478,7 @@ static int altera_jtaguart_remove(struct platform_device *pdev)
478 478
479 port = &altera_jtaguart_ports[i].port; 479 port = &altera_jtaguart_ports[i].port;
480 uart_remove_one_port(&altera_jtaguart_driver, port); 480 uart_remove_one_port(&altera_jtaguart_driver, port);
481 iounmap(port->membase);
481 482
482 return 0; 483 return 0;
483} 484}
diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c
index 46d3438a0d27..3e4b717670d7 100644
--- a/drivers/tty/serial/altera_uart.c
+++ b/drivers/tty/serial/altera_uart.c
@@ -615,6 +615,7 @@ static int altera_uart_remove(struct platform_device *pdev)
615 if (port) { 615 if (port) {
616 uart_remove_one_port(&altera_uart_driver, port); 616 uart_remove_one_port(&altera_uart_driver, port);
617 port->mapbase = 0; 617 port->mapbase = 0;
618 iounmap(port->membase);
618 } 619 }
619 620
620 return 0; 621 return 0;
diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c
index ebd8569f9ad5..9fff25be87f9 100644
--- a/drivers/tty/serial/efm32-uart.c
+++ b/drivers/tty/serial/efm32-uart.c
@@ -27,6 +27,7 @@
27#define UARTn_FRAME 0x04 27#define UARTn_FRAME 0x04
28#define UARTn_FRAME_DATABITS__MASK 0x000f 28#define UARTn_FRAME_DATABITS__MASK 0x000f
29#define UARTn_FRAME_DATABITS(n) ((n) - 3) 29#define UARTn_FRAME_DATABITS(n) ((n) - 3)
30#define UARTn_FRAME_PARITY__MASK 0x0300
30#define UARTn_FRAME_PARITY_NONE 0x0000 31#define UARTn_FRAME_PARITY_NONE 0x0000
31#define UARTn_FRAME_PARITY_EVEN 0x0200 32#define UARTn_FRAME_PARITY_EVEN 0x0200
32#define UARTn_FRAME_PARITY_ODD 0x0300 33#define UARTn_FRAME_PARITY_ODD 0x0300
@@ -572,12 +573,16 @@ static void efm32_uart_console_get_options(struct efm32_uart_port *efm_port,
572 16 * (4 + (clkdiv >> 6))); 573 16 * (4 + (clkdiv >> 6)));
573 574
574 frame = efm32_uart_read32(efm_port, UARTn_FRAME); 575 frame = efm32_uart_read32(efm_port, UARTn_FRAME);
575 if (frame & UARTn_FRAME_PARITY_ODD) 576 switch (frame & UARTn_FRAME_PARITY__MASK) {
577 case UARTn_FRAME_PARITY_ODD:
576 *parity = 'o'; 578 *parity = 'o';
577 else if (frame & UARTn_FRAME_PARITY_EVEN) 579 break;
580 case UARTn_FRAME_PARITY_EVEN:
578 *parity = 'e'; 581 *parity = 'e';
579 else 582 break;
583 default:
580 *parity = 'n'; 584 *parity = 'n';
585 }
581 586
582 *bits = (frame & UARTn_FRAME_DATABITS__MASK) - 587 *bits = (frame & UARTn_FRAME_DATABITS__MASK) -
583 UARTn_FRAME_DATABITS(4) + 4; 588 UARTn_FRAME_DATABITS(4) + 4;
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c
index 157883653256..f190a84a0246 100644
--- a/drivers/tty/serial/ifx6x60.c
+++ b/drivers/tty/serial/ifx6x60.c
@@ -1382,9 +1382,9 @@ static struct spi_driver ifx_spi_driver = {
1382static void __exit ifx_spi_exit(void) 1382static void __exit ifx_spi_exit(void)
1383{ 1383{
1384 /* unregister */ 1384 /* unregister */
1385 spi_unregister_driver(&ifx_spi_driver);
1385 tty_unregister_driver(tty_drv); 1386 tty_unregister_driver(tty_drv);
1386 put_tty_driver(tty_drv); 1387 put_tty_driver(tty_drv);
1387 spi_unregister_driver(&ifx_spi_driver);
1388 unregister_reboot_notifier(&ifx_modem_reboot_notifier_block); 1388 unregister_reboot_notifier(&ifx_modem_reboot_notifier_block);
1389} 1389}
1390 1390
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 33509b4beaec..bbefddd92bfe 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -2184,7 +2184,9 @@ static int serial_imx_probe(struct platform_device *pdev)
2184 * and DCD (when they are outputs) or enables the respective 2184 * and DCD (when they are outputs) or enables the respective
2185 * irqs. So set this bit early, i.e. before requesting irqs. 2185 * irqs. So set this bit early, i.e. before requesting irqs.
2186 */ 2186 */
2187 writel(UFCR_DCEDTE, sport->port.membase + UFCR); 2187 reg = readl(sport->port.membase + UFCR);
2188 if (!(reg & UFCR_DCEDTE))
2189 writel(reg | UFCR_DCEDTE, sport->port.membase + UFCR);
2188 2190
2189 /* 2191 /*
2190 * Disable UCR3_RI and UCR3_DCD irqs. They are also not 2192 * Disable UCR3_RI and UCR3_DCD irqs. They are also not
@@ -2195,7 +2197,15 @@ static int serial_imx_probe(struct platform_device *pdev)
2195 sport->port.membase + UCR3); 2197 sport->port.membase + UCR3);
2196 2198
2197 } else { 2199 } else {
2198 writel(0, sport->port.membase + UFCR); 2200 unsigned long ucr3 = UCR3_DSR;
2201
2202 reg = readl(sport->port.membase + UFCR);
2203 if (reg & UFCR_DCEDTE)
2204 writel(reg & ~UFCR_DCEDTE, sport->port.membase + UFCR);
2205
2206 if (!is_imx1_uart(sport))
2207 ucr3 |= IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP;
2208 writel(ucr3, sport->port.membase + UCR3);
2199 } 2209 }
2200 2210
2201 clk_disable_unprepare(sport->clk_ipg); 2211 clk_disable_unprepare(sport->clk_ipg);
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 0f45b7884a2c..13bfd5dcffce 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -2083,7 +2083,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
2083 mutex_lock(&port->mutex); 2083 mutex_lock(&port->mutex);
2084 2084
2085 tty_dev = device_find_child(uport->dev, &match, serial_match_port); 2085 tty_dev = device_find_child(uport->dev, &match, serial_match_port);
2086 if (device_may_wakeup(tty_dev)) { 2086 if (tty_dev && device_may_wakeup(tty_dev)) {
2087 if (!enable_irq_wake(uport->irq)) 2087 if (!enable_irq_wake(uport->irq))
2088 uport->irq_wake = 1; 2088 uport->irq_wake = 1;
2089 put_device(tty_dev); 2089 put_device(tty_dev);
@@ -2782,7 +2782,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
2782 * Register the port whether it's detected or not. This allows 2782 * Register the port whether it's detected or not. This allows
2783 * setserial to be used to alter this port's parameters. 2783 * setserial to be used to alter this port's parameters.
2784 */ 2784 */
2785 tty_dev = tty_port_register_device_attr(port, drv->tty_driver, 2785 tty_dev = tty_port_register_device_attr_serdev(port, drv->tty_driver,
2786 uport->line, uport->dev, port, uport->tty_groups); 2786 uport->line, uport->dev, port, uport->tty_groups);
2787 if (likely(!IS_ERR(tty_dev))) { 2787 if (likely(!IS_ERR(tty_dev))) {
2788 device_set_wakeup_capable(tty_dev, 1); 2788 device_set_wakeup_capable(tty_dev, 1);
@@ -2845,7 +2845,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
2845 /* 2845 /*
2846 * Remove the devices from the tty layer 2846 * Remove the devices from the tty layer
2847 */ 2847 */
2848 tty_unregister_device(drv->tty_driver, uport->line); 2848 tty_port_unregister_device(port, drv->tty_driver, uport->line);
2849 2849
2850 tty = tty_port_tty_get(port); 2850 tty = tty_port_tty_get(port);
2851 if (tty) { 2851 if (tty) {
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c
index 1d21a9c1d33e..4fb3165384c4 100644
--- a/drivers/tty/tty_port.c
+++ b/drivers/tty/tty_port.c
@@ -34,7 +34,9 @@ static int tty_port_default_receive_buf(struct tty_port *port,
34 if (!disc) 34 if (!disc)
35 return 0; 35 return 0;
36 36
37 mutex_lock(&tty->atomic_write_lock);
37 ret = tty_ldisc_receive_buf(disc, p, (char *)f, count); 38 ret = tty_ldisc_receive_buf(disc, p, (char *)f, count);
39 mutex_unlock(&tty->atomic_write_lock);
38 40
39 tty_ldisc_deref(disc); 41 tty_ldisc_deref(disc);
40 42
@@ -129,19 +131,85 @@ struct device *tty_port_register_device_attr(struct tty_port *port,
129 struct device *device, void *drvdata, 131 struct device *device, void *drvdata,
130 const struct attribute_group **attr_grp) 132 const struct attribute_group **attr_grp)
131{ 133{
134 tty_port_link_device(port, driver, index);
135 return tty_register_device_attr(driver, index, device, drvdata,
136 attr_grp);
137}
138EXPORT_SYMBOL_GPL(tty_port_register_device_attr);
139
140/**
141 * tty_port_register_device_attr_serdev - register tty or serdev device
142 * @port: tty_port of the device
143 * @driver: tty_driver for this device
144 * @index: index of the tty
145 * @device: parent if exists, otherwise NULL
146 * @drvdata: driver data for the device
147 * @attr_grp: attribute group for the device
148 *
149 * Register a serdev or tty device depending on if the parent device has any
150 * defined serdev clients or not.
151 */
152struct device *tty_port_register_device_attr_serdev(struct tty_port *port,
153 struct tty_driver *driver, unsigned index,
154 struct device *device, void *drvdata,
155 const struct attribute_group **attr_grp)
156{
132 struct device *dev; 157 struct device *dev;
133 158
134 tty_port_link_device(port, driver, index); 159 tty_port_link_device(port, driver, index);
135 160
136 dev = serdev_tty_port_register(port, device, driver, index); 161 dev = serdev_tty_port_register(port, device, driver, index);
137 if (PTR_ERR(dev) != -ENODEV) 162 if (PTR_ERR(dev) != -ENODEV) {
138 /* Skip creating cdev if we registered a serdev device */ 163 /* Skip creating cdev if we registered a serdev device */
139 return dev; 164 return dev;
165 }
140 166
141 return tty_register_device_attr(driver, index, device, drvdata, 167 return tty_register_device_attr(driver, index, device, drvdata,
142 attr_grp); 168 attr_grp);
143} 169}
144EXPORT_SYMBOL_GPL(tty_port_register_device_attr); 170EXPORT_SYMBOL_GPL(tty_port_register_device_attr_serdev);
171
172/**
173 * tty_port_register_device_serdev - register tty or serdev device
174 * @port: tty_port of the device
175 * @driver: tty_driver for this device
176 * @index: index of the tty
177 * @device: parent if exists, otherwise NULL
178 *
179 * Register a serdev or tty device depending on if the parent device has any
180 * defined serdev clients or not.
181 */
182struct device *tty_port_register_device_serdev(struct tty_port *port,
183 struct tty_driver *driver, unsigned index,
184 struct device *device)
185{
186 return tty_port_register_device_attr_serdev(port, driver, index,
187 device, NULL, NULL);
188}
189EXPORT_SYMBOL_GPL(tty_port_register_device_serdev);
190
191/**
192 * tty_port_unregister_device - deregister a tty or serdev device
193 * @port: tty_port of the device
194 * @driver: tty_driver for this device
195 * @index: index of the tty
196 *
197 * If a tty or serdev device is registered with a call to
198 * tty_port_register_device_serdev() then this function must be called when
199 * the device is gone.
200 */
201void tty_port_unregister_device(struct tty_port *port,
202 struct tty_driver *driver, unsigned index)
203{
204 int ret;
205
206 ret = serdev_tty_port_unregister(port);
207 if (ret == 0)
208 return;
209
210 tty_unregister_device(driver, index);
211}
212EXPORT_SYMBOL_GPL(tty_port_unregister_device);
145 213
146int tty_port_alloc_xmit_buf(struct tty_port *port) 214int tty_port_alloc_xmit_buf(struct tty_port *port)
147{ 215{
@@ -189,9 +257,6 @@ static void tty_port_destructor(struct kref *kref)
189 /* check if last port ref was dropped before tty release */ 257 /* check if last port ref was dropped before tty release */
190 if (WARN_ON(port->itty)) 258 if (WARN_ON(port->itty))
191 return; 259 return;
192
193 serdev_tty_port_unregister(port);
194
195 if (port->xmit_buf) 260 if (port->xmit_buf)
196 free_page((unsigned long)port->xmit_buf); 261 free_page((unsigned long)port->xmit_buf);
197 tty_port_destroy(port); 262 tty_port_destroy(port);
diff --git a/include/linux/serdev.h b/include/linux/serdev.h
index cda76c6506ca..e69402d4a8ae 100644
--- a/include/linux/serdev.h
+++ b/include/linux/serdev.h
@@ -195,6 +195,7 @@ int serdev_device_open(struct serdev_device *);
195void serdev_device_close(struct serdev_device *); 195void serdev_device_close(struct serdev_device *);
196unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int); 196unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int);
197void serdev_device_set_flow_control(struct serdev_device *, bool); 197void serdev_device_set_flow_control(struct serdev_device *, bool);
198int serdev_device_write_buf(struct serdev_device *, const unsigned char *, size_t);
198void serdev_device_wait_until_sent(struct serdev_device *, long); 199void serdev_device_wait_until_sent(struct serdev_device *, long);
199int serdev_device_get_tiocm(struct serdev_device *); 200int serdev_device_get_tiocm(struct serdev_device *);
200int serdev_device_set_tiocm(struct serdev_device *, int, int); 201int serdev_device_set_tiocm(struct serdev_device *, int, int);
@@ -236,6 +237,12 @@ static inline unsigned int serdev_device_set_baudrate(struct serdev_device *sdev
236 return 0; 237 return 0;
237} 238}
238static inline void serdev_device_set_flow_control(struct serdev_device *sdev, bool enable) {} 239static inline void serdev_device_set_flow_control(struct serdev_device *sdev, bool enable) {}
240static inline int serdev_device_write_buf(struct serdev_device *serdev,
241 const unsigned char *buf,
242 size_t count)
243{
244 return -ENODEV;
245}
239static inline void serdev_device_wait_until_sent(struct serdev_device *sdev, long timeout) {} 246static inline void serdev_device_wait_until_sent(struct serdev_device *sdev, long timeout) {}
240static inline int serdev_device_get_tiocm(struct serdev_device *serdev) 247static inline int serdev_device_get_tiocm(struct serdev_device *serdev)
241{ 248{
@@ -301,7 +308,7 @@ struct tty_driver;
301struct device *serdev_tty_port_register(struct tty_port *port, 308struct device *serdev_tty_port_register(struct tty_port *port,
302 struct device *parent, 309 struct device *parent,
303 struct tty_driver *drv, int idx); 310 struct tty_driver *drv, int idx);
304void serdev_tty_port_unregister(struct tty_port *port); 311int serdev_tty_port_unregister(struct tty_port *port);
305#else 312#else
306static inline struct device *serdev_tty_port_register(struct tty_port *port, 313static inline struct device *serdev_tty_port_register(struct tty_port *port,
307 struct device *parent, 314 struct device *parent,
@@ -309,14 +316,10 @@ static inline struct device *serdev_tty_port_register(struct tty_port *port,
309{ 316{
310 return ERR_PTR(-ENODEV); 317 return ERR_PTR(-ENODEV);
311} 318}
312static inline void serdev_tty_port_unregister(struct tty_port *port) {} 319static inline int serdev_tty_port_unregister(struct tty_port *port)
313#endif /* CONFIG_SERIAL_DEV_CTRL_TTYPORT */
314
315static inline int serdev_device_write_buf(struct serdev_device *serdev,
316 const unsigned char *data,
317 size_t count)
318{ 320{
319 return serdev_device_write(serdev, data, count, 0); 321 return -ENODEV;
320} 322}
323#endif /* CONFIG_SERIAL_DEV_CTRL_TTYPORT */
321 324
322#endif /*_LINUX_SERDEV_H */ 325#endif /*_LINUX_SERDEV_H */
diff --git a/include/linux/tty.h b/include/linux/tty.h
index d07cd2105a6c..eccb4ec30a8a 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -558,6 +558,15 @@ extern struct device *tty_port_register_device_attr(struct tty_port *port,
558 struct tty_driver *driver, unsigned index, 558 struct tty_driver *driver, unsigned index,
559 struct device *device, void *drvdata, 559 struct device *device, void *drvdata,
560 const struct attribute_group **attr_grp); 560 const struct attribute_group **attr_grp);
561extern struct device *tty_port_register_device_serdev(struct tty_port *port,
562 struct tty_driver *driver, unsigned index,
563 struct device *device);
564extern struct device *tty_port_register_device_attr_serdev(struct tty_port *port,
565 struct tty_driver *driver, unsigned index,
566 struct device *device, void *drvdata,
567 const struct attribute_group **attr_grp);
568extern void tty_port_unregister_device(struct tty_port *port,
569 struct tty_driver *driver, unsigned index);
561extern int tty_port_alloc_xmit_buf(struct tty_port *port); 570extern int tty_port_alloc_xmit_buf(struct tty_port *port);
562extern void tty_port_free_xmit_buf(struct tty_port *port); 571extern void tty_port_free_xmit_buf(struct tty_port *port);
563extern void tty_port_destroy(struct tty_port *port); 572extern void tty_port_destroy(struct tty_port *port);