diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-30 13:30:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-30 13:30:38 -0400 |
commit | 52afe190ff034f25546fb0a2cb7380dcb896d371 (patch) | |
tree | 95114016282b66fae8ab5f3b59f390f275651175 | |
parent | 8d02a9a89729605c3026674e4a245839be98c913 (diff) | |
parent | f4e68d58cf2b20a581759bbc7228052534652673 (diff) |
Merge tag 'tty-5.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial fixes from Greg KH:
"Here are some small tty and serial driver fixes for 5.1-rc3.
Nothing major here, just a number of potential problems fixes for
error handling paths, as well as some other minor bugfixes for
reported issues with 5.1-rc1.
All of these have been in linux-next with no reported issues"
* tag 'tty-5.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
tty: fix NULL pointer issue when tty_port ops is not set
Disable kgdboc failed by echo space to /sys/module/kgdboc/parameters/kgdboc
dt-bindings: serial: Add compatible for Mediatek MT8183
tty/serial: atmel: RS485 HD w/DMA: enable RX after TX is stopped
tty/serial: atmel: Add is_half_duplex helper
serial: sh-sci: Fix setting SCSCR_TIE while transferring data
serial: ar933x_uart: Fix build failure with disabled console
tty: serial: qcom_geni_serial: Initialize baud in qcom_geni_console_setup
sc16is7xx: missing unregister/delete driver on error in sc16is7xx_init()
tty: mxs-auart: fix a potential NULL pointer dereference
tty: atmel_serial: fix a potential NULL pointer dereference
serial: max310x: Fix to avoid potential NULL pointer dereference
serial: mvebu-uart: Fix to avoid a potential NULL pointer dereference
-rw-r--r-- | Documentation/devicetree/bindings/serial/mtk-uart.txt | 1 | ||||
-rw-r--r-- | drivers/tty/serial/ar933x_uart.c | 24 | ||||
-rw-r--r-- | drivers/tty/serial/atmel_serial.c | 52 | ||||
-rw-r--r-- | drivers/tty/serial/kgdboc.c | 4 | ||||
-rw-r--r-- | drivers/tty/serial/max310x.c | 2 | ||||
-rw-r--r-- | drivers/tty/serial/mvebu-uart.c | 3 | ||||
-rw-r--r-- | drivers/tty/serial/mxs-auart.c | 4 | ||||
-rw-r--r-- | drivers/tty/serial/qcom_geni_serial.c | 2 | ||||
-rw-r--r-- | drivers/tty/serial/sc16is7xx.c | 12 | ||||
-rw-r--r-- | drivers/tty/serial/sh-sci.c | 12 | ||||
-rw-r--r-- | drivers/tty/tty_port.c | 10 |
11 files changed, 75 insertions, 51 deletions
diff --git a/Documentation/devicetree/bindings/serial/mtk-uart.txt b/Documentation/devicetree/bindings/serial/mtk-uart.txt index 742cb470595b..bcfb13194f16 100644 --- a/Documentation/devicetree/bindings/serial/mtk-uart.txt +++ b/Documentation/devicetree/bindings/serial/mtk-uart.txt | |||
@@ -16,6 +16,7 @@ Required properties: | |||
16 | * "mediatek,mt8127-uart" for MT8127 compatible UARTS | 16 | * "mediatek,mt8127-uart" for MT8127 compatible UARTS |
17 | * "mediatek,mt8135-uart" for MT8135 compatible UARTS | 17 | * "mediatek,mt8135-uart" for MT8135 compatible UARTS |
18 | * "mediatek,mt8173-uart" for MT8173 compatible UARTS | 18 | * "mediatek,mt8173-uart" for MT8173 compatible UARTS |
19 | * "mediatek,mt8183-uart", "mediatek,mt6577-uart" for MT8183 compatible UARTS | ||
19 | * "mediatek,mt6577-uart" for MT6577 and all of the above | 20 | * "mediatek,mt6577-uart" for MT6577 and all of the above |
20 | 21 | ||
21 | - reg: The base address of the UART register bank. | 22 | - reg: The base address of the UART register bank. |
diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c index db5df3d54818..3bdd56a1021b 100644 --- a/drivers/tty/serial/ar933x_uart.c +++ b/drivers/tty/serial/ar933x_uart.c | |||
@@ -49,11 +49,6 @@ struct ar933x_uart_port { | |||
49 | struct clk *clk; | 49 | struct clk *clk; |
50 | }; | 50 | }; |
51 | 51 | ||
52 | static inline bool ar933x_uart_console_enabled(void) | ||
53 | { | ||
54 | return IS_ENABLED(CONFIG_SERIAL_AR933X_CONSOLE); | ||
55 | } | ||
56 | |||
57 | static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up, | 52 | static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up, |
58 | int offset) | 53 | int offset) |
59 | { | 54 | { |
@@ -508,6 +503,7 @@ static const struct uart_ops ar933x_uart_ops = { | |||
508 | .verify_port = ar933x_uart_verify_port, | 503 | .verify_port = ar933x_uart_verify_port, |
509 | }; | 504 | }; |
510 | 505 | ||
506 | #ifdef CONFIG_SERIAL_AR933X_CONSOLE | ||
511 | static struct ar933x_uart_port * | 507 | static struct ar933x_uart_port * |
512 | ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS]; | 508 | ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS]; |
513 | 509 | ||
@@ -604,14 +600,7 @@ static struct console ar933x_uart_console = { | |||
604 | .index = -1, | 600 | .index = -1, |
605 | .data = &ar933x_uart_driver, | 601 | .data = &ar933x_uart_driver, |
606 | }; | 602 | }; |
607 | 603 | #endif /* CONFIG_SERIAL_AR933X_CONSOLE */ | |
608 | static void ar933x_uart_add_console_port(struct ar933x_uart_port *up) | ||
609 | { | ||
610 | if (!ar933x_uart_console_enabled()) | ||
611 | return; | ||
612 | |||
613 | ar933x_console_ports[up->port.line] = up; | ||
614 | } | ||
615 | 604 | ||
616 | static struct uart_driver ar933x_uart_driver = { | 605 | static struct uart_driver ar933x_uart_driver = { |
617 | .owner = THIS_MODULE, | 606 | .owner = THIS_MODULE, |
@@ -700,7 +689,9 @@ static int ar933x_uart_probe(struct platform_device *pdev) | |||
700 | baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP); | 689 | baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP); |
701 | up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD); | 690 | up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD); |
702 | 691 | ||
703 | ar933x_uart_add_console_port(up); | 692 | #ifdef CONFIG_SERIAL_AR933X_CONSOLE |
693 | ar933x_console_ports[up->port.line] = up; | ||
694 | #endif | ||
704 | 695 | ||
705 | ret = uart_add_one_port(&ar933x_uart_driver, &up->port); | 696 | ret = uart_add_one_port(&ar933x_uart_driver, &up->port); |
706 | if (ret) | 697 | if (ret) |
@@ -749,8 +740,9 @@ static int __init ar933x_uart_init(void) | |||
749 | { | 740 | { |
750 | int ret; | 741 | int ret; |
751 | 742 | ||
752 | if (ar933x_uart_console_enabled()) | 743 | #ifdef CONFIG_SERIAL_AR933X_CONSOLE |
753 | ar933x_uart_driver.cons = &ar933x_uart_console; | 744 | ar933x_uart_driver.cons = &ar933x_uart_console; |
745 | #endif | ||
754 | 746 | ||
755 | ret = uart_register_driver(&ar933x_uart_driver); | 747 | ret = uart_register_driver(&ar933x_uart_driver); |
756 | if (ret) | 748 | if (ret) |
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 05147fe24343..0b4f36905321 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c | |||
@@ -166,6 +166,8 @@ struct atmel_uart_port { | |||
166 | unsigned int pending_status; | 166 | unsigned int pending_status; |
167 | spinlock_t lock_suspended; | 167 | spinlock_t lock_suspended; |
168 | 168 | ||
169 | bool hd_start_rx; /* can start RX during half-duplex operation */ | ||
170 | |||
169 | /* ISO7816 */ | 171 | /* ISO7816 */ |
170 | unsigned int fidi_min; | 172 | unsigned int fidi_min; |
171 | unsigned int fidi_max; | 173 | unsigned int fidi_max; |
@@ -231,6 +233,13 @@ static inline void atmel_uart_write_char(struct uart_port *port, u8 value) | |||
231 | __raw_writeb(value, port->membase + ATMEL_US_THR); | 233 | __raw_writeb(value, port->membase + ATMEL_US_THR); |
232 | } | 234 | } |
233 | 235 | ||
236 | static inline int atmel_uart_is_half_duplex(struct uart_port *port) | ||
237 | { | ||
238 | return ((port->rs485.flags & SER_RS485_ENABLED) && | ||
239 | !(port->rs485.flags & SER_RS485_RX_DURING_TX)) || | ||
240 | (port->iso7816.flags & SER_ISO7816_ENABLED); | ||
241 | } | ||
242 | |||
234 | #ifdef CONFIG_SERIAL_ATMEL_PDC | 243 | #ifdef CONFIG_SERIAL_ATMEL_PDC |
235 | static bool atmel_use_pdc_rx(struct uart_port *port) | 244 | static bool atmel_use_pdc_rx(struct uart_port *port) |
236 | { | 245 | { |
@@ -608,10 +617,9 @@ static void atmel_stop_tx(struct uart_port *port) | |||
608 | /* Disable interrupts */ | 617 | /* Disable interrupts */ |
609 | atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask); | 618 | atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask); |
610 | 619 | ||
611 | if (((port->rs485.flags & SER_RS485_ENABLED) && | 620 | if (atmel_uart_is_half_duplex(port)) |
612 | !(port->rs485.flags & SER_RS485_RX_DURING_TX)) || | ||
613 | port->iso7816.flags & SER_ISO7816_ENABLED) | ||
614 | atmel_start_rx(port); | 621 | atmel_start_rx(port); |
622 | |||
615 | } | 623 | } |
616 | 624 | ||
617 | /* | 625 | /* |
@@ -628,9 +636,7 @@ static void atmel_start_tx(struct uart_port *port) | |||
628 | return; | 636 | return; |
629 | 637 | ||
630 | if (atmel_use_pdc_tx(port) || atmel_use_dma_tx(port)) | 638 | if (atmel_use_pdc_tx(port) || atmel_use_dma_tx(port)) |
631 | if (((port->rs485.flags & SER_RS485_ENABLED) && | 639 | if (atmel_uart_is_half_duplex(port)) |
632 | !(port->rs485.flags & SER_RS485_RX_DURING_TX)) || | ||
633 | port->iso7816.flags & SER_ISO7816_ENABLED) | ||
634 | atmel_stop_rx(port); | 640 | atmel_stop_rx(port); |
635 | 641 | ||
636 | if (atmel_use_pdc_tx(port)) | 642 | if (atmel_use_pdc_tx(port)) |
@@ -928,11 +934,14 @@ static void atmel_complete_tx_dma(void *arg) | |||
928 | */ | 934 | */ |
929 | if (!uart_circ_empty(xmit)) | 935 | if (!uart_circ_empty(xmit)) |
930 | atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_tx); | 936 | atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_tx); |
931 | else if (((port->rs485.flags & SER_RS485_ENABLED) && | 937 | else if (atmel_uart_is_half_duplex(port)) { |
932 | !(port->rs485.flags & SER_RS485_RX_DURING_TX)) || | 938 | /* |
933 | port->iso7816.flags & SER_ISO7816_ENABLED) { | 939 | * DMA done, re-enable TXEMPTY and signal that we can stop |
934 | /* DMA done, stop TX, start RX for RS485 */ | 940 | * TX and start RX for RS485 |
935 | atmel_start_rx(port); | 941 | */ |
942 | atmel_port->hd_start_rx = true; | ||
943 | atmel_uart_writel(port, ATMEL_US_IER, | ||
944 | atmel_port->tx_done_mask); | ||
936 | } | 945 | } |
937 | 946 | ||
938 | spin_unlock_irqrestore(&port->lock, flags); | 947 | spin_unlock_irqrestore(&port->lock, flags); |
@@ -1288,6 +1297,10 @@ static int atmel_prepare_rx_dma(struct uart_port *port) | |||
1288 | sg_dma_len(&atmel_port->sg_rx)/2, | 1297 | sg_dma_len(&atmel_port->sg_rx)/2, |
1289 | DMA_DEV_TO_MEM, | 1298 | DMA_DEV_TO_MEM, |
1290 | DMA_PREP_INTERRUPT); | 1299 | DMA_PREP_INTERRUPT); |
1300 | if (!desc) { | ||
1301 | dev_err(port->dev, "Preparing DMA cyclic failed\n"); | ||
1302 | goto chan_err; | ||
1303 | } | ||
1291 | desc->callback = atmel_complete_rx_dma; | 1304 | desc->callback = atmel_complete_rx_dma; |
1292 | desc->callback_param = port; | 1305 | desc->callback_param = port; |
1293 | atmel_port->desc_rx = desc; | 1306 | atmel_port->desc_rx = desc; |
@@ -1376,9 +1389,20 @@ atmel_handle_transmit(struct uart_port *port, unsigned int pending) | |||
1376 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 1389 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
1377 | 1390 | ||
1378 | if (pending & atmel_port->tx_done_mask) { | 1391 | if (pending & atmel_port->tx_done_mask) { |
1379 | /* Either PDC or interrupt transmission */ | ||
1380 | atmel_uart_writel(port, ATMEL_US_IDR, | 1392 | atmel_uart_writel(port, ATMEL_US_IDR, |
1381 | atmel_port->tx_done_mask); | 1393 | atmel_port->tx_done_mask); |
1394 | |||
1395 | /* Start RX if flag was set and FIFO is empty */ | ||
1396 | if (atmel_port->hd_start_rx) { | ||
1397 | if (!(atmel_uart_readl(port, ATMEL_US_CSR) | ||
1398 | & ATMEL_US_TXEMPTY)) | ||
1399 | dev_warn(port->dev, "Should start RX, but TX fifo is not empty\n"); | ||
1400 | |||
1401 | atmel_port->hd_start_rx = false; | ||
1402 | atmel_start_rx(port); | ||
1403 | return; | ||
1404 | } | ||
1405 | |||
1382 | atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_tx); | 1406 | atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_tx); |
1383 | } | 1407 | } |
1384 | } | 1408 | } |
@@ -1508,9 +1532,7 @@ static void atmel_tx_pdc(struct uart_port *port) | |||
1508 | atmel_uart_writel(port, ATMEL_US_IER, | 1532 | atmel_uart_writel(port, ATMEL_US_IER, |
1509 | atmel_port->tx_done_mask); | 1533 | atmel_port->tx_done_mask); |
1510 | } else { | 1534 | } else { |
1511 | if (((port->rs485.flags & SER_RS485_ENABLED) && | 1535 | if (atmel_uart_is_half_duplex(port)) { |
1512 | !(port->rs485.flags & SER_RS485_RX_DURING_TX)) || | ||
1513 | port->iso7816.flags & SER_ISO7816_ENABLED) { | ||
1514 | /* DMA done, stop TX, start RX for RS485 */ | 1536 | /* DMA done, stop TX, start RX for RS485 */ |
1515 | atmel_start_rx(port); | 1537 | atmel_start_rx(port); |
1516 | } | 1538 | } |
diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c index 6fb312e7af71..bfe5e9e034ec 100644 --- a/drivers/tty/serial/kgdboc.c +++ b/drivers/tty/serial/kgdboc.c | |||
@@ -148,8 +148,10 @@ static int configure_kgdboc(void) | |||
148 | char *cptr = config; | 148 | char *cptr = config; |
149 | struct console *cons; | 149 | struct console *cons; |
150 | 150 | ||
151 | if (!strlen(config) || isspace(config[0])) | 151 | if (!strlen(config) || isspace(config[0])) { |
152 | err = 0; | ||
152 | goto noconfig; | 153 | goto noconfig; |
154 | } | ||
153 | 155 | ||
154 | kgdboc_io_ops.is_console = 0; | 156 | kgdboc_io_ops.is_console = 0; |
155 | kgdb_tty_driver = NULL; | 157 | kgdb_tty_driver = NULL; |
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index f5bdde405627..450ba6d7996c 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c | |||
@@ -1415,6 +1415,8 @@ static int max310x_spi_probe(struct spi_device *spi) | |||
1415 | if (spi->dev.of_node) { | 1415 | if (spi->dev.of_node) { |
1416 | const struct of_device_id *of_id = | 1416 | const struct of_device_id *of_id = |
1417 | of_match_device(max310x_dt_ids, &spi->dev); | 1417 | of_match_device(max310x_dt_ids, &spi->dev); |
1418 | if (!of_id) | ||
1419 | return -ENODEV; | ||
1418 | 1420 | ||
1419 | devtype = (struct max310x_devtype *)of_id->data; | 1421 | devtype = (struct max310x_devtype *)of_id->data; |
1420 | } else { | 1422 | } else { |
diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c index 231f751d1ef4..7e7b1559fa36 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c | |||
@@ -810,6 +810,9 @@ static int mvebu_uart_probe(struct platform_device *pdev) | |||
810 | return -EINVAL; | 810 | return -EINVAL; |
811 | } | 811 | } |
812 | 812 | ||
813 | if (!match) | ||
814 | return -ENODEV; | ||
815 | |||
813 | /* Assume that all UART ports have a DT alias or none has */ | 816 | /* Assume that all UART ports have a DT alias or none has */ |
814 | id = of_alias_get_id(pdev->dev.of_node, "serial"); | 817 | id = of_alias_get_id(pdev->dev.of_node, "serial"); |
815 | if (!pdev->dev.of_node || id < 0) | 818 | if (!pdev->dev.of_node || id < 0) |
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 27235a526cce..4c188f4079b3 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c | |||
@@ -1686,6 +1686,10 @@ static int mxs_auart_probe(struct platform_device *pdev) | |||
1686 | 1686 | ||
1687 | s->port.mapbase = r->start; | 1687 | s->port.mapbase = r->start; |
1688 | s->port.membase = ioremap(r->start, resource_size(r)); | 1688 | s->port.membase = ioremap(r->start, resource_size(r)); |
1689 | if (!s->port.membase) { | ||
1690 | ret = -ENOMEM; | ||
1691 | goto out_disable_clks; | ||
1692 | } | ||
1689 | s->port.ops = &mxs_auart_ops; | 1693 | s->port.ops = &mxs_auart_ops; |
1690 | s->port.iotype = UPIO_MEM; | 1694 | s->port.iotype = UPIO_MEM; |
1691 | s->port.fifosize = MXS_AUART_FIFO_SIZE; | 1695 | s->port.fifosize = MXS_AUART_FIFO_SIZE; |
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 3bcec1c20219..35e5f9c5d5be 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c | |||
@@ -1050,7 +1050,7 @@ static int __init qcom_geni_console_setup(struct console *co, char *options) | |||
1050 | { | 1050 | { |
1051 | struct uart_port *uport; | 1051 | struct uart_port *uport; |
1052 | struct qcom_geni_serial_port *port; | 1052 | struct qcom_geni_serial_port *port; |
1053 | int baud; | 1053 | int baud = 9600; |
1054 | int bits = 8; | 1054 | int bits = 8; |
1055 | int parity = 'n'; | 1055 | int parity = 'n'; |
1056 | int flow = 'n'; | 1056 | int flow = 'n'; |
diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index 635178cf3eed..09a183dfc526 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c | |||
@@ -1507,7 +1507,7 @@ static int __init sc16is7xx_init(void) | |||
1507 | ret = i2c_add_driver(&sc16is7xx_i2c_uart_driver); | 1507 | ret = i2c_add_driver(&sc16is7xx_i2c_uart_driver); |
1508 | if (ret < 0) { | 1508 | if (ret < 0) { |
1509 | pr_err("failed to init sc16is7xx i2c --> %d\n", ret); | 1509 | pr_err("failed to init sc16is7xx i2c --> %d\n", ret); |
1510 | return ret; | 1510 | goto err_i2c; |
1511 | } | 1511 | } |
1512 | #endif | 1512 | #endif |
1513 | 1513 | ||
@@ -1515,10 +1515,18 @@ static int __init sc16is7xx_init(void) | |||
1515 | ret = spi_register_driver(&sc16is7xx_spi_uart_driver); | 1515 | ret = spi_register_driver(&sc16is7xx_spi_uart_driver); |
1516 | if (ret < 0) { | 1516 | if (ret < 0) { |
1517 | pr_err("failed to init sc16is7xx spi --> %d\n", ret); | 1517 | pr_err("failed to init sc16is7xx spi --> %d\n", ret); |
1518 | return ret; | 1518 | goto err_spi; |
1519 | } | 1519 | } |
1520 | #endif | 1520 | #endif |
1521 | return ret; | 1521 | return ret; |
1522 | |||
1523 | err_spi: | ||
1524 | #ifdef CONFIG_SERIAL_SC16IS7XX_I2C | ||
1525 | i2c_del_driver(&sc16is7xx_i2c_uart_driver); | ||
1526 | #endif | ||
1527 | err_i2c: | ||
1528 | uart_unregister_driver(&sc16is7xx_uart); | ||
1529 | return ret; | ||
1522 | } | 1530 | } |
1523 | module_init(sc16is7xx_init); | 1531 | module_init(sc16is7xx_init); |
1524 | 1532 | ||
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 060fcd42b6d5..2d1c626312cd 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -838,19 +838,9 @@ static void sci_transmit_chars(struct uart_port *port) | |||
838 | 838 | ||
839 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 839 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
840 | uart_write_wakeup(port); | 840 | uart_write_wakeup(port); |
841 | if (uart_circ_empty(xmit)) { | 841 | if (uart_circ_empty(xmit)) |
842 | sci_stop_tx(port); | 842 | sci_stop_tx(port); |
843 | } else { | ||
844 | ctrl = serial_port_in(port, SCSCR); | ||
845 | |||
846 | if (port->type != PORT_SCI) { | ||
847 | serial_port_in(port, SCxSR); /* Dummy read */ | ||
848 | sci_clear_SCxSR(port, SCxSR_TDxE_CLEAR(port)); | ||
849 | } | ||
850 | 843 | ||
851 | ctrl |= SCSCR_TIE; | ||
852 | serial_port_out(port, SCSCR, ctrl); | ||
853 | } | ||
854 | } | 844 | } |
855 | 845 | ||
856 | /* On SH3, SCIF may read end-of-break as a space->mark char */ | 846 | /* On SH3, SCIF may read end-of-break as a space->mark char */ |
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 044c3cbdcfa4..a9e12b3bc31d 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c | |||
@@ -325,7 +325,7 @@ static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty) | |||
325 | if (tty && C_HUPCL(tty)) | 325 | if (tty && C_HUPCL(tty)) |
326 | tty_port_lower_dtr_rts(port); | 326 | tty_port_lower_dtr_rts(port); |
327 | 327 | ||
328 | if (port->ops->shutdown) | 328 | if (port->ops && port->ops->shutdown) |
329 | port->ops->shutdown(port); | 329 | port->ops->shutdown(port); |
330 | } | 330 | } |
331 | out: | 331 | out: |
@@ -398,7 +398,7 @@ EXPORT_SYMBOL_GPL(tty_port_tty_wakeup); | |||
398 | */ | 398 | */ |
399 | int tty_port_carrier_raised(struct tty_port *port) | 399 | int tty_port_carrier_raised(struct tty_port *port) |
400 | { | 400 | { |
401 | if (port->ops->carrier_raised == NULL) | 401 | if (!port->ops || !port->ops->carrier_raised) |
402 | return 1; | 402 | return 1; |
403 | return port->ops->carrier_raised(port); | 403 | return port->ops->carrier_raised(port); |
404 | } | 404 | } |
@@ -414,7 +414,7 @@ EXPORT_SYMBOL(tty_port_carrier_raised); | |||
414 | */ | 414 | */ |
415 | void tty_port_raise_dtr_rts(struct tty_port *port) | 415 | void tty_port_raise_dtr_rts(struct tty_port *port) |
416 | { | 416 | { |
417 | if (port->ops->dtr_rts) | 417 | if (port->ops && port->ops->dtr_rts) |
418 | port->ops->dtr_rts(port, 1); | 418 | port->ops->dtr_rts(port, 1); |
419 | } | 419 | } |
420 | EXPORT_SYMBOL(tty_port_raise_dtr_rts); | 420 | EXPORT_SYMBOL(tty_port_raise_dtr_rts); |
@@ -429,7 +429,7 @@ EXPORT_SYMBOL(tty_port_raise_dtr_rts); | |||
429 | */ | 429 | */ |
430 | void tty_port_lower_dtr_rts(struct tty_port *port) | 430 | void tty_port_lower_dtr_rts(struct tty_port *port) |
431 | { | 431 | { |
432 | if (port->ops->dtr_rts) | 432 | if (port->ops && port->ops->dtr_rts) |
433 | port->ops->dtr_rts(port, 0); | 433 | port->ops->dtr_rts(port, 0); |
434 | } | 434 | } |
435 | EXPORT_SYMBOL(tty_port_lower_dtr_rts); | 435 | EXPORT_SYMBOL(tty_port_lower_dtr_rts); |
@@ -684,7 +684,7 @@ int tty_port_open(struct tty_port *port, struct tty_struct *tty, | |||
684 | 684 | ||
685 | if (!tty_port_initialized(port)) { | 685 | if (!tty_port_initialized(port)) { |
686 | clear_bit(TTY_IO_ERROR, &tty->flags); | 686 | clear_bit(TTY_IO_ERROR, &tty->flags); |
687 | if (port->ops->activate) { | 687 | if (port->ops && port->ops->activate) { |
688 | int retval = port->ops->activate(port, tty); | 688 | int retval = port->ops->activate(port, tty); |
689 | if (retval) { | 689 | if (retval) { |
690 | mutex_unlock(&port->mutex); | 690 | mutex_unlock(&port->mutex); |