Merge tag 'tty-5.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 30 Mar 2019 17:30:38 +0000 (10:30 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 30 Mar 2019 17:30:38 +0000 (10:30 -0700)
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

Documentation/devicetree/bindings/serial/mtk-uart.txt
drivers/tty/serial/ar933x_uart.c
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/kgdboc.c
drivers/tty/serial/max310x.c
drivers/tty/serial/mvebu-uart.c
drivers/tty/serial/mxs-auart.c
drivers/tty/serial/qcom_geni_serial.c
drivers/tty/serial/sc16is7xx.c
drivers/tty/serial/sh-sci.c
drivers/tty/tty_port.c

index 742cb470595ba4d7e2a3e467328d33a8bf5335b5..bcfb13194f16364b0ac77a4391a26c0bb34206d0 100644 (file)
@@ -16,6 +16,7 @@ Required properties:
   * "mediatek,mt8127-uart" for MT8127 compatible UARTS
   * "mediatek,mt8135-uart" for MT8135 compatible UARTS
   * "mediatek,mt8173-uart" for MT8173 compatible UARTS
+  * "mediatek,mt8183-uart", "mediatek,mt6577-uart" for MT8183 compatible UARTS
   * "mediatek,mt6577-uart" for MT6577 and all of the above
 
 - reg: The base address of the UART register bank.
index db5df3d548188b6c440db8928ac157b5512174bb..3bdd56a1021b26d6e74ff98ad6f0e25f25f5de08 100644 (file)
@@ -49,11 +49,6 @@ struct ar933x_uart_port {
        struct clk              *clk;
 };
 
-static inline bool ar933x_uart_console_enabled(void)
-{
-       return IS_ENABLED(CONFIG_SERIAL_AR933X_CONSOLE);
-}
-
 static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up,
                                            int offset)
 {
@@ -508,6 +503,7 @@ static const struct uart_ops ar933x_uart_ops = {
        .verify_port    = ar933x_uart_verify_port,
 };
 
+#ifdef CONFIG_SERIAL_AR933X_CONSOLE
 static struct ar933x_uart_port *
 ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS];
 
@@ -604,14 +600,7 @@ static struct console ar933x_uart_console = {
        .index          = -1,
        .data           = &ar933x_uart_driver,
 };
-
-static void ar933x_uart_add_console_port(struct ar933x_uart_port *up)
-{
-       if (!ar933x_uart_console_enabled())
-               return;
-
-       ar933x_console_ports[up->port.line] = up;
-}
+#endif /* CONFIG_SERIAL_AR933X_CONSOLE */
 
 static struct uart_driver ar933x_uart_driver = {
        .owner          = THIS_MODULE,
@@ -700,7 +689,9 @@ static int ar933x_uart_probe(struct platform_device *pdev)
        baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP);
        up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD);
 
-       ar933x_uart_add_console_port(up);
+#ifdef CONFIG_SERIAL_AR933X_CONSOLE
+       ar933x_console_ports[up->port.line] = up;
+#endif
 
        ret = uart_add_one_port(&ar933x_uart_driver, &up->port);
        if (ret)
@@ -749,8 +740,9 @@ static int __init ar933x_uart_init(void)
 {
        int ret;
 
-       if (ar933x_uart_console_enabled())
-               ar933x_uart_driver.cons = &ar933x_uart_console;
+#ifdef CONFIG_SERIAL_AR933X_CONSOLE
+       ar933x_uart_driver.cons = &ar933x_uart_console;
+#endif
 
        ret = uart_register_driver(&ar933x_uart_driver);
        if (ret)
index 05147fe243434a52e4ca827227d95dc1f6a0f2e6..0b4f3690532145da4228b8b8255f0d5da928a31f 100644 (file)
@@ -166,6 +166,8 @@ struct atmel_uart_port {
        unsigned int            pending_status;
        spinlock_t              lock_suspended;
 
+       bool                    hd_start_rx;    /* can start RX during half-duplex operation */
+
        /* ISO7816 */
        unsigned int            fidi_min;
        unsigned int            fidi_max;
@@ -231,6 +233,13 @@ static inline void atmel_uart_write_char(struct uart_port *port, u8 value)
        __raw_writeb(value, port->membase + ATMEL_US_THR);
 }
 
+static inline int atmel_uart_is_half_duplex(struct uart_port *port)
+{
+       return ((port->rs485.flags & SER_RS485_ENABLED) &&
+               !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
+               (port->iso7816.flags & SER_ISO7816_ENABLED);
+}
+
 #ifdef CONFIG_SERIAL_ATMEL_PDC
 static bool atmel_use_pdc_rx(struct uart_port *port)
 {
@@ -608,10 +617,9 @@ static void atmel_stop_tx(struct uart_port *port)
        /* Disable interrupts */
        atmel_uart_writel(port, ATMEL_US_IDR, atmel_port->tx_done_mask);
 
-       if (((port->rs485.flags & SER_RS485_ENABLED) &&
-            !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
-           port->iso7816.flags & SER_ISO7816_ENABLED)
+       if (atmel_uart_is_half_duplex(port))
                atmel_start_rx(port);
+
 }
 
 /*
@@ -628,9 +636,7 @@ static void atmel_start_tx(struct uart_port *port)
                return;
 
        if (atmel_use_pdc_tx(port) || atmel_use_dma_tx(port))
-               if (((port->rs485.flags & SER_RS485_ENABLED) &&
-                    !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
-                   port->iso7816.flags & SER_ISO7816_ENABLED)
+               if (atmel_uart_is_half_duplex(port))
                        atmel_stop_rx(port);
 
        if (atmel_use_pdc_tx(port))
@@ -928,11 +934,14 @@ static void atmel_complete_tx_dma(void *arg)
         */
        if (!uart_circ_empty(xmit))
                atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_tx);
-       else if (((port->rs485.flags & SER_RS485_ENABLED) &&
-                 !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
-                port->iso7816.flags & SER_ISO7816_ENABLED) {
-               /* DMA done, stop TX, start RX for RS485 */
-               atmel_start_rx(port);
+       else if (atmel_uart_is_half_duplex(port)) {
+               /*
+                * DMA done, re-enable TXEMPTY and signal that we can stop
+                * TX and start RX for RS485
+                */
+               atmel_port->hd_start_rx = true;
+               atmel_uart_writel(port, ATMEL_US_IER,
+                                 atmel_port->tx_done_mask);
        }
 
        spin_unlock_irqrestore(&port->lock, flags);
@@ -1288,6 +1297,10 @@ static int atmel_prepare_rx_dma(struct uart_port *port)
                                         sg_dma_len(&atmel_port->sg_rx)/2,
                                         DMA_DEV_TO_MEM,
                                         DMA_PREP_INTERRUPT);
+       if (!desc) {
+               dev_err(port->dev, "Preparing DMA cyclic failed\n");
+               goto chan_err;
+       }
        desc->callback = atmel_complete_rx_dma;
        desc->callback_param = port;
        atmel_port->desc_rx = desc;
@@ -1376,9 +1389,20 @@ atmel_handle_transmit(struct uart_port *port, unsigned int pending)
        struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
 
        if (pending & atmel_port->tx_done_mask) {
-               /* Either PDC or interrupt transmission */
                atmel_uart_writel(port, ATMEL_US_IDR,
                                  atmel_port->tx_done_mask);
+
+               /* Start RX if flag was set and FIFO is empty */
+               if (atmel_port->hd_start_rx) {
+                       if (!(atmel_uart_readl(port, ATMEL_US_CSR)
+                                       & ATMEL_US_TXEMPTY))
+                               dev_warn(port->dev, "Should start RX, but TX fifo is not empty\n");
+
+                       atmel_port->hd_start_rx = false;
+                       atmel_start_rx(port);
+                       return;
+               }
+
                atmel_tasklet_schedule(atmel_port, &atmel_port->tasklet_tx);
        }
 }
@@ -1508,9 +1532,7 @@ static void atmel_tx_pdc(struct uart_port *port)
                atmel_uart_writel(port, ATMEL_US_IER,
                                  atmel_port->tx_done_mask);
        } else {
-               if (((port->rs485.flags & SER_RS485_ENABLED) &&
-                    !(port->rs485.flags & SER_RS485_RX_DURING_TX)) ||
-                   port->iso7816.flags & SER_ISO7816_ENABLED) {
+               if (atmel_uart_is_half_duplex(port)) {
                        /* DMA done, stop TX, start RX for RS485 */
                        atmel_start_rx(port);
                }
index 6fb312e7af713ecd3efcc4c0ef069602635f7681..bfe5e9e034ecf86b3de80476eb90a44a0d228359 100644 (file)
@@ -148,8 +148,10 @@ static int configure_kgdboc(void)
        char *cptr = config;
        struct console *cons;
 
-       if (!strlen(config) || isspace(config[0]))
+       if (!strlen(config) || isspace(config[0])) {
+               err = 0;
                goto noconfig;
+       }
 
        kgdboc_io_ops.is_console = 0;
        kgdb_tty_driver = NULL;
index f5bdde40562750c7695823e93bab799bf5593ad5..450ba6d7996c229e7e3a796439f8e6caa1dbaebb 100644 (file)
@@ -1415,6 +1415,8 @@ static int max310x_spi_probe(struct spi_device *spi)
        if (spi->dev.of_node) {
                const struct of_device_id *of_id =
                        of_match_device(max310x_dt_ids, &spi->dev);
+               if (!of_id)
+                       return -ENODEV;
 
                devtype = (struct max310x_devtype *)of_id->data;
        } else {
index 231f751d1ef48b42e4a9820c73408242862035e9..7e7b1559fa3695406ae80edda49f0f1f7634dc9a 100644 (file)
@@ -810,6 +810,9 @@ static int mvebu_uart_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
+       if (!match)
+               return -ENODEV;
+
        /* Assume that all UART ports have a DT alias or none has */
        id = of_alias_get_id(pdev->dev.of_node, "serial");
        if (!pdev->dev.of_node || id < 0)
index 27235a526cce8c4b59aa14f6764e466b10988748..4c188f4079b3ea68ee51982b41d4b14ba27567c4 100644 (file)
@@ -1686,6 +1686,10 @@ static int mxs_auart_probe(struct platform_device *pdev)
 
        s->port.mapbase = r->start;
        s->port.membase = ioremap(r->start, resource_size(r));
+       if (!s->port.membase) {
+               ret = -ENOMEM;
+               goto out_disable_clks;
+       }
        s->port.ops = &mxs_auart_ops;
        s->port.iotype = UPIO_MEM;
        s->port.fifosize = MXS_AUART_FIFO_SIZE;
index 3bcec1c20219102b277aafc72b548425df33e175..35e5f9c5d5bed48274363343366c8bd76395c500 100644 (file)
@@ -1050,7 +1050,7 @@ static int __init qcom_geni_console_setup(struct console *co, char *options)
 {
        struct uart_port *uport;
        struct qcom_geni_serial_port *port;
-       int baud;
+       int baud = 9600;
        int bits = 8;
        int parity = 'n';
        int flow = 'n';
index 635178cf3eed538aa35bf49225a4886097e2e7b0..09a183dfc52640027bf571184ee4e69e819c5951 100644 (file)
@@ -1507,7 +1507,7 @@ static int __init sc16is7xx_init(void)
        ret = i2c_add_driver(&sc16is7xx_i2c_uart_driver);
        if (ret < 0) {
                pr_err("failed to init sc16is7xx i2c --> %d\n", ret);
-               return ret;
+               goto err_i2c;
        }
 #endif
 
@@ -1515,10 +1515,18 @@ static int __init sc16is7xx_init(void)
        ret = spi_register_driver(&sc16is7xx_spi_uart_driver);
        if (ret < 0) {
                pr_err("failed to init sc16is7xx spi --> %d\n", ret);
-               return ret;
+               goto err_spi;
        }
 #endif
        return ret;
+
+err_spi:
+#ifdef CONFIG_SERIAL_SC16IS7XX_I2C
+       i2c_del_driver(&sc16is7xx_i2c_uart_driver);
+#endif
+err_i2c:
+       uart_unregister_driver(&sc16is7xx_uart);
+       return ret;
 }
 module_init(sc16is7xx_init);
 
index 060fcd42b6d560105a114c9923ce1cdcc177b696..2d1c626312cd8892d5eae0fa65e03d3347a09e81 100644 (file)
@@ -838,19 +838,9 @@ static void sci_transmit_chars(struct uart_port *port)
 
        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
                uart_write_wakeup(port);
-       if (uart_circ_empty(xmit)) {
+       if (uart_circ_empty(xmit))
                sci_stop_tx(port);
-       } else {
-               ctrl = serial_port_in(port, SCSCR);
-
-               if (port->type != PORT_SCI) {
-                       serial_port_in(port, SCxSR); /* Dummy read */
-                       sci_clear_SCxSR(port, SCxSR_TDxE_CLEAR(port));
-               }
 
-               ctrl |= SCSCR_TIE;
-               serial_port_out(port, SCSCR, ctrl);
-       }
 }
 
 /* On SH3, SCIF may read end-of-break as a space->mark char */
index 044c3cbdcfa40664497d13bd00e607584eff99c7..a9e12b3bc31d7e19966c724b8b31ce3ac64c5242 100644 (file)
@@ -325,7 +325,7 @@ static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty)
                if (tty && C_HUPCL(tty))
                        tty_port_lower_dtr_rts(port);
 
-               if (port->ops->shutdown)
+               if (port->ops && port->ops->shutdown)
                        port->ops->shutdown(port);
        }
 out:
@@ -398,7 +398,7 @@ EXPORT_SYMBOL_GPL(tty_port_tty_wakeup);
  */
 int tty_port_carrier_raised(struct tty_port *port)
 {
-       if (port->ops->carrier_raised == NULL)
+       if (!port->ops || !port->ops->carrier_raised)
                return 1;
        return port->ops->carrier_raised(port);
 }
@@ -414,7 +414,7 @@ EXPORT_SYMBOL(tty_port_carrier_raised);
  */
 void tty_port_raise_dtr_rts(struct tty_port *port)
 {
-       if (port->ops->dtr_rts)
+       if (port->ops && port->ops->dtr_rts)
                port->ops->dtr_rts(port, 1);
 }
 EXPORT_SYMBOL(tty_port_raise_dtr_rts);
@@ -429,7 +429,7 @@ EXPORT_SYMBOL(tty_port_raise_dtr_rts);
  */
 void tty_port_lower_dtr_rts(struct tty_port *port)
 {
-       if (port->ops->dtr_rts)
+       if (port->ops && port->ops->dtr_rts)
                port->ops->dtr_rts(port, 0);
 }
 EXPORT_SYMBOL(tty_port_lower_dtr_rts);
@@ -684,7 +684,7 @@ int tty_port_open(struct tty_port *port, struct tty_struct *tty,
 
        if (!tty_port_initialized(port)) {
                clear_bit(TTY_IO_ERROR, &tty->flags);
-               if (port->ops->activate) {
+               if (port->ops && port->ops->activate) {
                        int retval = port->ops->activate(port, tty);
                        if (retval) {
                                mutex_unlock(&port->mutex);