Merge 6.4-rc3 into tty-next
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 27 May 2023 07:32:07 +0000 (08:32 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 27 May 2023 07:32:07 +0000 (08:32 +0100)
We need the serial/tty fixes in here as well.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
27 files changed:
arch/mips/alchemy/common/platform.c
drivers/tty/serial/8250/8250.h
drivers/tty/serial/8250/8250_core.c
drivers/tty/serial/8250/8250_early.c
drivers/tty/serial/8250/8250_em.c
drivers/tty/serial/8250/8250_of.c
drivers/tty/serial/8250/8250_omap.c
drivers/tty/serial/8250/8250_port.c
drivers/tty/serial/8250/8250_pxa.c
drivers/tty/serial/8250/8250_rt288x.c [new file with mode: 0644]
drivers/tty/serial/8250/8250_uniphier.c
drivers/tty/serial/8250/Makefile
drivers/tty/serial/Makefile
drivers/tty/serial/amba-pl011.c
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/clps711x.c
drivers/tty/serial/cpm_uart/cpm_uart_core.c
drivers/tty/serial/fsl_lpuart.c
drivers/tty/serial/imx.c
drivers/tty/serial/lantiq.c
drivers/tty/serial/serial_core.c
drivers/tty/serial/st-asc.c
drivers/tty/serial/stm32-usart.c
drivers/tty/serial/uartlite.c
drivers/tty/serial/xilinx_uartps.c
include/linux/serial_8250.h
include/linux/serial_core.h

index b8f3397..d4ab34b 100644 (file)
@@ -51,9 +51,9 @@ static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
 #define PORT(_base, _irq)                                      \
        {                                                       \
                .mapbase        = _base,                        \
+               .mapsize        = 0x1000,                       \
                .irq            = _irq,                         \
                .regshift       = 2,                            \
-               .iotype         = UPIO_AU,                      \
                .flags          = UPF_SKIP_TEST | UPF_IOREMAP | \
                                  UPF_FIXED_TYPE,               \
                .type           = PORT_16550A,                  \
@@ -124,8 +124,14 @@ static void __init alchemy_setup_uarts(int ctype)
        au1xx0_uart_device.dev.platform_data = ports;
 
        /* Fill up uartclk. */
-       for (s = 0; s < c; s++)
+       for (s = 0; s < c; s++) {
                ports[s].uartclk = uartclk;
+               if (au_platform_setup(&ports[s]) < 0) {
+                       kfree(ports);
+                       printk(KERN_INFO "Alchemy: missing support for UARTs\n");
+                       return;
+               }
+       }
        if (platform_device_register(&au1xx0_uart_device))
                printk(KERN_INFO "Alchemy: failed to register UARTs\n");
 }
index 1e8fe44..5418708 100644 (file)
@@ -167,12 +167,12 @@ static unsigned int __maybe_unused serial_icr_read(struct uart_8250_port *up,
 
 void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p);
 
-static inline int serial_dl_read(struct uart_8250_port *up)
+static inline u32 serial_dl_read(struct uart_8250_port *up)
 {
        return up->dl_read(up);
 }
 
-static inline void serial_dl_write(struct uart_8250_port *up, int value)
+static inline void serial_dl_write(struct uart_8250_port *up, u32 value)
 {
        up->dl_write(up, value);
 }
index 13bf535..4434c32 100644 (file)
@@ -488,6 +488,34 @@ static inline void serial8250_apply_quirks(struct uart_8250_port *up)
        up->port.quirks |= skip_txen_test ? UPQ_NO_TXEN_TEST : 0;
 }
 
+static struct uart_8250_port *serial8250_setup_port(int index)
+{
+       struct uart_8250_port *up;
+
+       if (index >= UART_NR)
+               return NULL;
+
+       up = &serial8250_ports[index];
+       up->port.line = index;
+
+       serial8250_init_port(up);
+       if (!base_ops)
+               base_ops = up->port.ops;
+       up->port.ops = &univ8250_port_ops;
+
+       timer_setup(&up->timer, serial8250_timeout, 0);
+
+       up->ops = &univ8250_driver_ops;
+
+       if (IS_ENABLED(CONFIG_ALPHA_JENSEN) ||
+           (IS_ENABLED(CONFIG_ALPHA_GENERIC) && alpha_jensen()))
+               up->port.set_mctrl = alpha_jensen_set_mctrl;
+
+       serial8250_set_defaults(up);
+
+       return up;
+}
+
 static void __init serial8250_isa_init_ports(void)
 {
        struct uart_8250_port *up;
@@ -501,26 +529,13 @@ static void __init serial8250_isa_init_ports(void)
        if (nr_uarts > UART_NR)
                nr_uarts = UART_NR;
 
-       for (i = 0; i < nr_uarts; i++) {
-               struct uart_8250_port *up = &serial8250_ports[i];
-               struct uart_port *port = &up->port;
-
-               port->line = i;
-               serial8250_init_port(up);
-               if (!base_ops)
-                       base_ops = port->ops;
-               port->ops = &univ8250_port_ops;
-
-               timer_setup(&up->timer, serial8250_timeout, 0);
-
-               up->ops = &univ8250_driver_ops;
-
-               if (IS_ENABLED(CONFIG_ALPHA_JENSEN) ||
-                   (IS_ENABLED(CONFIG_ALPHA_GENERIC) && alpha_jensen()))
-                       port->set_mctrl = alpha_jensen_set_mctrl;
-
-               serial8250_set_defaults(up);
-       }
+       /*
+        * Set up initial isa ports based on nr_uart module param, or else
+        * default to CONFIG_SERIAL_8250_RUNTIME_UARTS. Note that we do not
+        * need to increase nr_uarts when setting up the initial isa ports.
+        */
+       for (i = 0; i < nr_uarts; i++)
+               serial8250_setup_port(i);
 
        /* chain base port ops to support Remote Supervisor Adapter */
        univ8250_port_ops = *base_ops;
@@ -586,16 +601,29 @@ static void univ8250_console_write(struct console *co, const char *s,
 
 static int univ8250_console_setup(struct console *co, char *options)
 {
+       struct uart_8250_port *up;
        struct uart_port *port;
-       int retval;
+       int retval, i;
 
        /*
         * Check whether an invalid uart number has been specified, and
         * if so, search for the first available port that does have
         * console support.
         */
-       if (co->index >= nr_uarts)
+       if (co->index >= UART_NR)
                co->index = 0;
+
+       /*
+        * If the console is past the initial isa ports, init more ports up to
+        * co->index as needed and increment nr_uarts accordingly.
+        */
+       for (i = nr_uarts; i <= co->index; i++) {
+               up = serial8250_setup_port(i);
+               if (!up)
+                       return -ENODEV;
+               nr_uarts++;
+       }
+
        port = &serial8250_ports[co->index].port;
        /* link port to console */
        port->cons = co;
@@ -822,12 +850,16 @@ static int serial8250_probe(struct platform_device *dev)
                uart.port.iotype        = p->iotype;
                uart.port.flags         = p->flags;
                uart.port.mapbase       = p->mapbase;
+               uart.port.mapsize       = p->mapsize;
                uart.port.hub6          = p->hub6;
                uart.port.has_sysrq     = p->has_sysrq;
                uart.port.private_data  = p->private_data;
                uart.port.type          = p->type;
+               uart.bugs               = p->bugs;
                uart.port.serial_in     = p->serial_in;
                uart.port.serial_out    = p->serial_out;
+               uart.dl_read            = p->dl_read;
+               uart.dl_write           = p->dl_write;
                uart.port.handle_irq    = p->handle_irq;
                uart.port.handle_break  = p->handle_break;
                uart.port.set_termios   = p->set_termios;
@@ -990,7 +1022,18 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
        mutex_lock(&serial_mutex);
 
        uart = serial8250_find_match_or_unused(&up->port);
-       if (uart && uart->port.type != PORT_8250_CIR) {
+       if (!uart) {
+               /*
+                * If the port is past the initial isa ports, initialize a new
+                * port and increment nr_uarts accordingly.
+                */
+               uart = serial8250_setup_port(nr_uarts);
+               if (!uart)
+                       goto unlock;
+               nr_uarts++;
+       }
+
+       if (uart->port.type != PORT_8250_CIR) {
                struct mctrl_gpios *gpios;
 
                if (uart->port.dev)
@@ -1120,6 +1163,7 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
                }
        }
 
+unlock:
        mutex_unlock(&serial_mutex);
 
        return ret;
index 0ebde0a..4299a8b 100644 (file)
@@ -36,7 +36,6 @@
 
 static unsigned int serial8250_early_in(struct uart_port *port, int offset)
 {
-       int reg_offset = offset;
        offset <<= port->regshift;
 
        switch (port->iotype) {
@@ -50,8 +49,6 @@ static unsigned int serial8250_early_in(struct uart_port *port, int offset)
                return ioread32be(port->membase + offset);
        case UPIO_PORT:
                return inb(port->iobase + offset);
-       case UPIO_AU:
-               return port->serial_in(port, reg_offset);
        default:
                return 0;
        }
@@ -59,7 +56,6 @@ static unsigned int serial8250_early_in(struct uart_port *port, int offset)
 
 static void serial8250_early_out(struct uart_port *port, int offset, int value)
 {
-       int reg_offset = offset;
        offset <<= port->regshift;
 
        switch (port->iotype) {
@@ -78,9 +74,6 @@ static void serial8250_early_out(struct uart_port *port, int offset, int value)
        case UPIO_PORT:
                outb(value, port->iobase + offset);
                break;
-       case UPIO_AU:
-               port->serial_out(port, reg_offset, value);
-               break;
        }
 }
 
@@ -199,17 +192,3 @@ OF_EARLYCON_DECLARE(omap8250, "ti,omap3-uart", early_omap8250_setup);
 OF_EARLYCON_DECLARE(omap8250, "ti,omap4-uart", early_omap8250_setup);
 
 #endif
-
-#ifdef CONFIG_SERIAL_8250_RT288X
-
-static int __init early_au_setup(struct earlycon_device *dev, const char *opt)
-{
-       dev->port.serial_in = au_serial_in;
-       dev->port.serial_out = au_serial_out;
-       dev->port.iotype = UPIO_AU;
-       dev->con->write = early_serial8250_write;
-       return 0;
-}
-OF_EARLYCON_DECLARE(palmchip, "ralink,rt2880-uart", early_au_setup);
-
-#endif
index 25a9ecf..ef5019e 100644 (file)
@@ -139,12 +139,12 @@ static void serial8250_em_serial_out(struct uart_port *p, int offset, int value)
        }
 }
 
-static int serial8250_em_serial_dl_read(struct uart_8250_port *up)
+static u32 serial8250_em_serial_dl_read(struct uart_8250_port *up)
 {
        return serial_in(up, UART_DLL_EM) | serial_in(up, UART_DLM_EM) << 8;
 }
 
-static void serial8250_em_serial_dl_write(struct uart_8250_port *up, int value)
+static void serial8250_em_serial_dl_write(struct uart_8250_port *up, u32 value)
 {
        serial_out(up, UART_DLL_EM, value & 0xff);
        serial_out(up, UART_DLM_EM, value >> 8 & 0xff);
index 1b461fb..c9f6bd7 100644 (file)
@@ -171,7 +171,9 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
 
        switch (type) {
        case PORT_RT2880:
-               port->iotype = UPIO_AU;
+               ret = rt288x_setup(port);
+               if (ret)
+                       goto err_unprepare;
                break;
        }
 
index 734f092..5c093df 100644 (file)
@@ -32,6 +32,7 @@
 #include "8250.h"
 
 #define DEFAULT_CLK_SPEED      48000000
+#define OMAP_UART_REGSHIFT     2
 
 #define UART_ERRATA_i202_MDR1_ACCESS   (1 << 0)
 #define OMAP_UART_WER_HAS_TX_WAKEUP    (1 << 1)
 #define UART_OMAP_RX_LVL               0x19
 
 struct omap8250_priv {
+       void __iomem *membase;
        int line;
        u8 habit;
        u8 mdr1;
@@ -159,9 +161,14 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p);
 static inline void omap_8250_rx_dma_flush(struct uart_8250_port *p) { }
 #endif
 
-static u32 uart_read(struct uart_8250_port *up, u32 reg)
+static u32 uart_read(struct omap8250_priv *priv, u32 reg)
+{
+       return readl(priv->membase + (reg << OMAP_UART_REGSHIFT));
+}
+
+static void uart_write(struct omap8250_priv *priv, u32 reg, u32 val)
 {
-       return readl(up->port.membase + (reg << up->port.regshift));
+       writel(val, priv->membase + (reg << OMAP_UART_REGSHIFT));
 }
 
 /*
@@ -548,7 +555,7 @@ static void omap_serial_fill_features_erratas(struct uart_8250_port *up,
        u32 mvr, scheme;
        u16 revision, major, minor;
 
-       mvr = uart_read(up, UART_OMAP_MVER);
+       mvr = uart_read(priv, UART_OMAP_MVER);
 
        /* Check revision register scheme */
        scheme = mvr >> OMAP_UART_MVR_SCHEME_SHIFT;
@@ -616,9 +623,9 @@ static int omap_8250_dma_handle_irq(struct uart_port *port);
 
 static irqreturn_t omap8250_irq(int irq, void *dev_id)
 {
-       struct uart_port *port = dev_id;
-       struct omap8250_priv *priv = port->private_data;
-       struct uart_8250_port *up = up_to_u8250p(port);
+       struct omap8250_priv *priv = dev_id;
+       struct uart_8250_port *up = serial8250_get_port(priv->line);
+       struct uart_port *port = &up->port;
        unsigned int iir, lsr;
        int ret;
 
@@ -672,6 +679,7 @@ static int omap_8250_startup(struct uart_port *port)
 {
        struct uart_8250_port *up = up_to_u8250p(port);
        struct omap8250_priv *priv = port->private_data;
+       struct uart_8250_dma *dma = &priv->omap8250_dma;
        int ret;
 
        if (priv->wakeirq) {
@@ -690,23 +698,18 @@ static int omap_8250_startup(struct uart_port *port)
        up->msr_saved_flags = 0;
 
        /* Disable DMA for console UART */
-       if (uart_console(port))
-               up->dma = NULL;
-
-       if (up->dma) {
+       if (dma->fn && !uart_console(port)) {
+               up->dma = &priv->omap8250_dma;
                ret = serial8250_request_dma(up);
                if (ret) {
                        dev_warn_ratelimited(port->dev,
                                             "failed to request DMA\n");
                        up->dma = NULL;
                }
+       } else {
+               up->dma = NULL;
        }
 
-       ret = request_irq(port->irq, omap8250_irq, IRQF_SHARED,
-                         dev_name(port->dev), port);
-       if (ret < 0)
-               goto err;
-
        up->ier = UART_IER_RLSI | UART_IER_RDI;
        serial_out(up, UART_IER, up->ier);
 
@@ -723,14 +726,11 @@ static int omap_8250_startup(struct uart_port *port)
        if (up->dma && !(priv->habit & UART_HAS_EFR2))
                up->dma->rx_dma(up);
 
+       enable_irq(up->port.irq);
+
        pm_runtime_mark_last_busy(port->dev);
        pm_runtime_put_autosuspend(port->dev);
        return 0;
-err:
-       pm_runtime_mark_last_busy(port->dev);
-       pm_runtime_put_autosuspend(port->dev);
-       dev_pm_clear_wake_irq(port->dev);
-       return ret;
 }
 
 static void omap_8250_shutdown(struct uart_port *port)
@@ -750,9 +750,11 @@ static void omap_8250_shutdown(struct uart_port *port)
 
        up->ier = 0;
        serial_out(up, UART_IER, 0);
+       disable_irq_nosync(up->port.irq);
+       dev_pm_clear_wake_irq(port->dev);
 
-       if (up->dma)
-               serial8250_release_dma(up);
+       serial8250_release_dma(up);
+       up->dma = NULL;
 
        /*
         * Disable break condition and FIFOs
@@ -763,8 +765,6 @@ static void omap_8250_shutdown(struct uart_port *port)
 
        pm_runtime_mark_last_busy(port->dev);
        pm_runtime_put_autosuspend(port->dev);
-       free_irq(port->irq, port);
-       dev_pm_clear_wake_irq(port->dev);
 }
 
 static void omap_8250_throttle(struct uart_port *port)
@@ -1394,7 +1394,7 @@ static int omap8250_probe(struct platform_device *pdev)
                UPF_HARD_FLOW;
        up.port.private_data = priv;
 
-       up.port.regshift = 2;
+       up.port.regshift = OMAP_UART_REGSHIFT;
        up.port.fifosize = 64;
        up.tx_loadsz = 64;
        up.capabilities = UART_CAP_FIFO;
@@ -1444,8 +1444,6 @@ static int omap8250_probe(struct platform_device *pdev)
                                 &up.overrun_backoff_time_ms) != 0)
                up.overrun_backoff_time_ms = 0;
 
-       priv->wakeirq = irq_of_parse_and_map(np, 1);
-
        pdata = of_device_get_match_data(&pdev->dev);
        if (pdata)
                priv->habit |= pdata->habit;
@@ -1457,6 +1455,8 @@ static int omap8250_probe(struct platform_device *pdev)
                         DEFAULT_CLK_SPEED);
        }
 
+       priv->membase = membase;
+       priv->line = -ENODEV;
        priv->latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE;
        priv->calc_latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE;
        cpu_latency_qos_add_request(&priv->pm_qos_request, priv->latency);
@@ -1464,6 +1464,8 @@ static int omap8250_probe(struct platform_device *pdev)
 
        spin_lock_init(&priv->rx_dma_lock);
 
+       platform_set_drvdata(pdev, priv);
+
        device_init_wakeup(&pdev->dev, true);
        pm_runtime_enable(&pdev->dev);
        pm_runtime_use_autosuspend(&pdev->dev);
@@ -1498,58 +1500,72 @@ static int omap8250_probe(struct platform_device *pdev)
        ret = of_property_count_strings(np, "dma-names");
        if (ret == 2) {
                struct omap8250_dma_params *dma_params = NULL;
+               struct uart_8250_dma *dma = &priv->omap8250_dma;
 
-               up.dma = &priv->omap8250_dma;
-               up.dma->fn = the_no_dma_filter_fn;
-               up.dma->tx_dma = omap_8250_tx_dma;
-               up.dma->rx_dma = omap_8250_rx_dma;
+               dma->fn = the_no_dma_filter_fn;
+               dma->tx_dma = omap_8250_tx_dma;
+               dma->rx_dma = omap_8250_rx_dma;
                if (pdata)
                        dma_params = pdata->dma_params;
 
                if (dma_params) {
-                       up.dma->rx_size = dma_params->rx_size;
-                       up.dma->rxconf.src_maxburst = dma_params->rx_trigger;
-                       up.dma->txconf.dst_maxburst = dma_params->tx_trigger;
+                       dma->rx_size = dma_params->rx_size;
+                       dma->rxconf.src_maxburst = dma_params->rx_trigger;
+                       dma->txconf.dst_maxburst = dma_params->tx_trigger;
                        priv->rx_trigger = dma_params->rx_trigger;
                        priv->tx_trigger = dma_params->tx_trigger;
                } else {
-                       up.dma->rx_size = RX_TRIGGER;
-                       up.dma->rxconf.src_maxburst = RX_TRIGGER;
-                       up.dma->txconf.dst_maxburst = TX_TRIGGER;
+                       dma->rx_size = RX_TRIGGER;
+                       dma->rxconf.src_maxburst = RX_TRIGGER;
+                       dma->txconf.dst_maxburst = TX_TRIGGER;
                }
        }
 #endif
+
+       irq_set_status_flags(irq, IRQ_NOAUTOEN);
+       ret = devm_request_irq(&pdev->dev, irq, omap8250_irq, 0,
+                              dev_name(&pdev->dev), priv);
+       if (ret < 0)
+               return ret;
+
+       priv->wakeirq = irq_of_parse_and_map(np, 1);
+
        ret = serial8250_register_8250_port(&up);
        if (ret < 0) {
                dev_err(&pdev->dev, "unable to register 8250 port\n");
                goto err;
        }
        priv->line = ret;
-       platform_set_drvdata(pdev, priv);
        pm_runtime_mark_last_busy(&pdev->dev);
        pm_runtime_put_autosuspend(&pdev->dev);
        return 0;
 err:
        pm_runtime_dont_use_autosuspend(&pdev->dev);
        pm_runtime_put_sync(&pdev->dev);
+       flush_work(&priv->qos_work);
        pm_runtime_disable(&pdev->dev);
+       cpu_latency_qos_remove_request(&priv->pm_qos_request);
        return ret;
 }
 
 static int omap8250_remove(struct platform_device *pdev)
 {
        struct omap8250_priv *priv = platform_get_drvdata(pdev);
+       struct uart_8250_port *up;
        int err;
 
        err = pm_runtime_resume_and_get(&pdev->dev);
        if (err)
                return err;
 
+       up = serial8250_get_port(priv->line);
+       omap_8250_shutdown(&up->port);
+       serial8250_unregister_port(priv->line);
+       priv->line = -ENODEV;
        pm_runtime_dont_use_autosuspend(&pdev->dev);
        pm_runtime_put_sync(&pdev->dev);
        flush_work(&priv->qos_work);
        pm_runtime_disable(&pdev->dev);
-       serial8250_unregister_port(priv->line);
        cpu_latency_qos_remove_request(&priv->pm_qos_request);
        device_init_wakeup(&pdev->dev, false);
        return 0;
@@ -1625,7 +1641,6 @@ static int omap8250_lost_context(struct uart_8250_port *up)
 static int omap8250_soft_reset(struct device *dev)
 {
        struct omap8250_priv *priv = dev_get_drvdata(dev);
-       struct uart_8250_port *up = serial8250_get_port(priv->line);
        int timeout = 100;
        int sysc;
        int syss;
@@ -1639,20 +1654,20 @@ static int omap8250_soft_reset(struct device *dev)
         * needing omap8250_soft_reset() quirk. Do it in two writes as
         * recommended in the comment for omap8250_update_scr().
         */
-       serial_out(up, UART_OMAP_SCR, OMAP_UART_SCR_DMAMODE_1);
-       serial_out(up, UART_OMAP_SCR,
+       uart_write(priv, UART_OMAP_SCR, OMAP_UART_SCR_DMAMODE_1);
+       uart_write(priv, UART_OMAP_SCR,
                   OMAP_UART_SCR_DMAMODE_1 | OMAP_UART_SCR_DMAMODE_CTL);
 
-       sysc = serial_in(up, UART_OMAP_SYSC);
+       sysc = uart_read(priv, UART_OMAP_SYSC);
 
        /* softreset the UART */
        sysc |= OMAP_UART_SYSC_SOFTRESET;
-       serial_out(up, UART_OMAP_SYSC, sysc);
+       uart_write(priv, UART_OMAP_SYSC, sysc);
 
        /* By experiments, 1us enough for reset complete on AM335x */
        do {
                udelay(1);
-               syss = serial_in(up, UART_OMAP_SYSS);
+               syss = uart_read(priv, UART_OMAP_SYSS);
        } while (--timeout && !(syss & OMAP_UART_SYSS_RESETDONE));
 
        if (!timeout) {
@@ -1666,13 +1681,10 @@ static int omap8250_soft_reset(struct device *dev)
 static int omap8250_runtime_suspend(struct device *dev)
 {
        struct omap8250_priv *priv = dev_get_drvdata(dev);
-       struct uart_8250_port *up;
+       struct uart_8250_port *up = NULL;
 
-       /* In case runtime-pm tries this before we are setup */
-       if (!priv)
-               return 0;
-
-       up = serial8250_get_port(priv->line);
+       if (priv->line >= 0)
+               up = serial8250_get_port(priv->line);
        /*
         * When using 'no_console_suspend', the console UART must not be
         * suspended. Since driver suspend is managed by runtime suspend,
@@ -1680,7 +1692,7 @@ static int omap8250_runtime_suspend(struct device *dev)
         * active during suspend.
         */
        if (priv->is_suspending && !console_suspend_enabled) {
-               if (uart_console(&up->port))
+               if (up && uart_console(&up->port))
                        return -EBUSY;
        }
 
@@ -1691,13 +1703,15 @@ static int omap8250_runtime_suspend(struct device *dev)
                if (ret)
                        return ret;
 
-               /* Restore to UART mode after reset (for wakeup) */
-               omap8250_update_mdr1(up, priv);
-               /* Restore wakeup enable register */
-               serial_out(up, UART_OMAP_WER, priv->wer);
+               if (up) {
+                       /* Restore to UART mode after reset (for wakeup) */
+                       omap8250_update_mdr1(up, priv);
+                       /* Restore wakeup enable register */
+                       serial_out(up, UART_OMAP_WER, priv->wer);
+               }
        }
 
-       if (up->dma && up->dma->rxchan)
+       if (up && up->dma && up->dma->rxchan)
                omap_8250_rx_dma_flush(up);
 
        priv->latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE;
@@ -1709,18 +1723,15 @@ static int omap8250_runtime_suspend(struct device *dev)
 static int omap8250_runtime_resume(struct device *dev)
 {
        struct omap8250_priv *priv = dev_get_drvdata(dev);
-       struct uart_8250_port *up;
-
-       /* In case runtime-pm tries this before we are setup */
-       if (!priv)
-               return 0;
+       struct uart_8250_port *up = NULL;
 
-       up = serial8250_get_port(priv->line);
+       if (priv->line >= 0)
+               up = serial8250_get_port(priv->line);
 
-       if (omap8250_lost_context(up))
+       if (up && omap8250_lost_context(up))
                omap8250_restore_regs(up);
 
-       if (up->dma && up->dma->rxchan && !(priv->habit & UART_HAS_EFR2))
+       if (up && up->dma && up->dma->rxchan && !(priv->habit & UART_HAS_EFR2))
                omap_8250_rx_dma(up);
 
        priv->latency = priv->calc_latency;
index c153ba3..2d8f87f 100644 (file)
@@ -325,7 +325,7 @@ static const struct serial8250_config uart_config[] = {
 };
 
 /* Uart divisor latch read */
-static int default_serial_dl_read(struct uart_8250_port *up)
+static u32 default_serial_dl_read(struct uart_8250_port *up)
 {
        /* Assign these in pieces to truncate any bits above 7.  */
        unsigned char dll = serial_in(up, UART_DLL);
@@ -335,72 +335,12 @@ static int default_serial_dl_read(struct uart_8250_port *up)
 }
 
 /* Uart divisor latch write */
-static void default_serial_dl_write(struct uart_8250_port *up, int value)
+static void default_serial_dl_write(struct uart_8250_port *up, u32 value)
 {
        serial_out(up, UART_DLL, value & 0xff);
        serial_out(up, UART_DLM, value >> 8 & 0xff);
 }
 
-#ifdef CONFIG_SERIAL_8250_RT288X
-
-#define UART_REG_UNMAPPED      -1
-
-/* Au1x00/RT288x UART hardware has a weird register layout */
-static const s8 au_io_in_map[8] = {
-       [UART_RX]       = 0,
-       [UART_IER]      = 2,
-       [UART_IIR]      = 3,
-       [UART_LCR]      = 5,
-       [UART_MCR]      = 6,
-       [UART_LSR]      = 7,
-       [UART_MSR]      = 8,
-       [UART_SCR]      = UART_REG_UNMAPPED,
-};
-
-static const s8 au_io_out_map[8] = {
-       [UART_TX]       = 1,
-       [UART_IER]      = 2,
-       [UART_FCR]      = 4,
-       [UART_LCR]      = 5,
-       [UART_MCR]      = 6,
-       [UART_LSR]      = UART_REG_UNMAPPED,
-       [UART_MSR]      = UART_REG_UNMAPPED,
-       [UART_SCR]      = UART_REG_UNMAPPED,
-};
-
-unsigned int au_serial_in(struct uart_port *p, int offset)
-{
-       if (offset >= ARRAY_SIZE(au_io_in_map))
-               return UINT_MAX;
-       offset = au_io_in_map[offset];
-       if (offset == UART_REG_UNMAPPED)
-               return UINT_MAX;
-       return __raw_readl(p->membase + (offset << p->regshift));
-}
-
-void au_serial_out(struct uart_port *p, int offset, int value)
-{
-       if (offset >= ARRAY_SIZE(au_io_out_map))
-               return;
-       offset = au_io_out_map[offset];
-       if (offset == UART_REG_UNMAPPED)
-               return;
-       __raw_writel(value, p->membase + (offset << p->regshift));
-}
-
-/* Au1x00 haven't got a standard divisor latch */
-static int au_serial_dl_read(struct uart_8250_port *up)
-{
-       return __raw_readl(up->port.membase + 0x28);
-}
-
-static void au_serial_dl_write(struct uart_8250_port *up, int value)
-{
-       __raw_writel(value, up->port.membase + 0x28);
-}
-
-#endif
-
 static unsigned int hub6_serial_in(struct uart_port *p, int offset)
 {
        offset = offset << p->regshift;
@@ -510,15 +450,6 @@ static void set_io_from_upio(struct uart_port *p)
                p->serial_out = mem32be_serial_out;
                break;
 
-#ifdef CONFIG_SERIAL_8250_RT288X
-       case UPIO_AU:
-               p->serial_in = au_serial_in;
-               p->serial_out = au_serial_out;
-               up->dl_read = au_serial_dl_read;
-               up->dl_write = au_serial_dl_write;
-               break;
-#endif
-
        default:
                p->serial_in = io_serial_in;
                p->serial_out = io_serial_out;
@@ -848,7 +779,7 @@ static void disable_rsa(struct uart_8250_port *up)
 static int size_fifo(struct uart_8250_port *up)
 {
        unsigned char old_fcr, old_mcr, old_lcr;
-       unsigned short old_dl;
+       u32 old_dl;
        int count;
 
        old_lcr = serial_in(up, UART_LCR);
@@ -2969,11 +2900,6 @@ static unsigned int serial8250_port_size(struct uart_8250_port *pt)
 {
        if (pt->port.mapsize)
                return pt->port.mapsize;
-       if (pt->port.iotype == UPIO_AU) {
-               if (pt->port.type == PORT_RT2880)
-                       return 0x100;
-               return 0x1000;
-       }
        if (is_omap1_8250(pt))
                return 0x16 << pt->port.regshift;
 
@@ -3223,10 +3149,6 @@ static void serial8250_config_port(struct uart_port *port, int flags)
        if (flags & UART_CONFIG_TYPE)
                autoconfig(up);
 
-       /* if access method is AU, it is a 16550 with a quirk */
-       if (port->type == PORT_16550A && port->iotype == UPIO_AU)
-               up->bugs |= UART_BUG_NOMSR;
-
        /* HW bugs may trigger IRQ while IIR == NO_INT */
        if (port->type == PORT_TEGRA)
                up->bugs |= UART_BUG_NOMSR;
index 795e551..28b341f 100644 (file)
@@ -60,7 +60,7 @@ static const struct of_device_id serial_pxa_dt_ids[] = {
 MODULE_DEVICE_TABLE(of, serial_pxa_dt_ids);
 
 /* Uart divisor latch write */
-static void serial_pxa_dl_write(struct uart_8250_port *up, int value)
+static void serial_pxa_dl_write(struct uart_8250_port *up, u32 value)
 {
        unsigned int dll;
 
diff --git a/drivers/tty/serial/8250/8250_rt288x.c b/drivers/tty/serial/8250/8250_rt288x.c
new file mode 100644 (file)
index 0000000..6415ca8
--- /dev/null
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RT288x/Au1xxx driver
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+
+#include "8250.h"
+
+#define RT288X_DL      0x28
+
+/* Au1x00/RT288x UART hardware has a weird register layout */
+static const u8 au_io_in_map[7] = {
+       [UART_RX]       = 0,
+       [UART_IER]      = 2,
+       [UART_IIR]      = 3,
+       [UART_LCR]      = 5,
+       [UART_MCR]      = 6,
+       [UART_LSR]      = 7,
+       [UART_MSR]      = 8,
+};
+
+static const u8 au_io_out_map[5] = {
+       [UART_TX]       = 1,
+       [UART_IER]      = 2,
+       [UART_FCR]      = 4,
+       [UART_LCR]      = 5,
+       [UART_MCR]      = 6,
+};
+
+static unsigned int au_serial_in(struct uart_port *p, int offset)
+{
+       if (offset >= ARRAY_SIZE(au_io_in_map))
+               return UINT_MAX;
+       offset = au_io_in_map[offset];
+
+       return __raw_readl(p->membase + (offset << p->regshift));
+}
+
+static void au_serial_out(struct uart_port *p, int offset, int value)
+{
+       if (offset >= ARRAY_SIZE(au_io_out_map))
+               return;
+       offset = au_io_out_map[offset];
+
+       __raw_writel(value, p->membase + (offset << p->regshift));
+}
+
+/* Au1x00 haven't got a standard divisor latch */
+static u32 au_serial_dl_read(struct uart_8250_port *up)
+{
+       return __raw_readl(up->port.membase + RT288X_DL);
+}
+
+static void au_serial_dl_write(struct uart_8250_port *up, u32 value)
+{
+       __raw_writel(value, up->port.membase + RT288X_DL);
+}
+
+int au_platform_setup(struct plat_serial8250_port *p)
+{
+       p->iotype = UPIO_AU;
+
+       p->serial_in = au_serial_in;
+       p->serial_out = au_serial_out;
+       p->dl_read = au_serial_dl_read;
+       p->dl_write = au_serial_dl_write;
+
+       p->mapsize = 0x1000;
+
+       p->bugs |= UART_BUG_NOMSR;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(au_platform_setup);
+
+int rt288x_setup(struct uart_port *p)
+{
+       struct uart_8250_port *up = up_to_u8250p(p);
+
+       p->iotype = UPIO_AU;
+
+       p->serial_in = au_serial_in;
+       p->serial_out = au_serial_out;
+       up->dl_read = au_serial_dl_read;
+       up->dl_write = au_serial_dl_write;
+
+       p->mapsize = 0x100;
+
+       up->bugs |= UART_BUG_NOMSR;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(rt288x_setup);
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static void au_putc(struct uart_port *port, unsigned char c)
+{
+       unsigned int status;
+
+       au_serial_out(port, UART_TX, c);
+
+       for (;;) {
+               status = au_serial_in(port, UART_LSR);
+               if (uart_lsr_tx_empty(status))
+                       break;
+               cpu_relax();
+       }
+}
+
+static void au_early_serial8250_write(struct console *console,
+                                     const char *s, unsigned int count)
+{
+       struct earlycon_device *device = console->data;
+       struct uart_port *port = &device->port;
+
+       uart_console_write(port, s, count, au_putc);
+}
+
+static int __init early_au_setup(struct earlycon_device *dev, const char *opt)
+{
+       rt288x_setup(&dev->port);
+       dev->con->write = au_early_serial8250_write;
+
+       return 0;
+}
+OF_EARLYCON_DECLARE(palmchip, "ralink,rt2880-uart", early_au_setup);
+#endif
+
+MODULE_DESCRIPTION("RT288x/Au1xxx UART driver");
+MODULE_LICENSE("GPL");
index a2978ab..a405155 100644 (file)
@@ -145,12 +145,12 @@ static void uniphier_serial_out(struct uart_port *p, int offset, int value)
  * The divisor latch register exists at different address.
  * Override dl_read/write callbacks.
  */
-static int uniphier_serial_dl_read(struct uart_8250_port *up)
+static u32 uniphier_serial_dl_read(struct uart_8250_port *up)
 {
        return readl(up->port.membase + UNIPHIER_UART_DLR);
 }
 
-static void uniphier_serial_dl_write(struct uart_8250_port *up, int value)
+static void uniphier_serial_dl_write(struct uart_8250_port *up, u32 value)
 {
        writel(value, up->port.membase + UNIPHIER_UART_DLR);
 }
index 4fc2fc1..628b75b 100644 (file)
@@ -35,6 +35,7 @@ obj-$(CONFIG_SERIAL_8250_DW)          += 8250_dw.o
 obj-$(CONFIG_SERIAL_8250_EM)           += 8250_em.o
 obj-$(CONFIG_SERIAL_8250_IOC3)         += 8250_ioc3.o
 obj-$(CONFIG_SERIAL_8250_OMAP)         += 8250_omap.o
+obj-$(CONFIG_SERIAL_8250_RT288X)       += 8250_rt288x.o
 obj-$(CONFIG_SERIAL_8250_LPC18XX)      += 8250_lpc18xx.o
 obj-$(CONFIG_SERIAL_8250_MT6577)       += 8250_mtk.o
 obj-$(CONFIG_SERIAL_8250_UNIPHIER)     += 8250_uniphier.o
index cd9afd9..531ec3a 100644 (file)
@@ -21,7 +21,7 @@ obj-$(CONFIG_SERIAL_SUNSAB) += sunsab.o
 obj-$(CONFIG_SERIAL_21285) += 21285.o
 
 # Now bring in any enabled 8250/16450/16550 type drivers.
-obj-$(CONFIG_SERIAL_8250) += 8250/
+obj-y += 8250/
 
 obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
 obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
index d8c2f34..c5c3f46 100644 (file)
@@ -2166,6 +2166,13 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
         * ----------^----------^----------^----------^-----
         */
        pl011_write_lcr_h(uap, lcr_h);
+
+       /*
+        * Receive was disabled by pl011_disable_uart during shutdown.
+        * Need to reenable receive if you need to use a tty_driver
+        * returns from tty_find_polling_driver() after a port shutdown.
+        */
+       old_cr |= UART011_CR_RXE;
        pl011_write(old_cr, uap, REG_CR);
 
        spin_unlock_irqrestore(&port->lock, flags);
index 9cd7479..6e9192f 100644 (file)
@@ -3006,14 +3006,13 @@ static int atmel_serial_remove(struct platform_device *pdev)
 {
        struct uart_port *port = platform_get_drvdata(pdev);
        struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
-       int ret = 0;
 
        tasklet_kill(&atmel_port->tasklet_rx);
        tasklet_kill(&atmel_port->tasklet_tx);
 
        device_init_wakeup(&pdev->dev, 0);
 
-       ret = uart_remove_one_port(&atmel_uart, port);
+       uart_remove_one_port(&atmel_uart, port);
 
        kfree(atmel_port->rx_ring.buf);
 
@@ -3023,7 +3022,7 @@ static int atmel_serial_remove(struct platform_device *pdev)
 
        pdev->dev.of_node = NULL;
 
-       return ret;
+       return 0;
 }
 
 static SIMPLE_DEV_PM_OPS(atmel_serial_pm_ops, atmel_serial_suspend,
index e190dce..e49bc40 100644 (file)
@@ -514,7 +514,9 @@ static int uart_clps711x_remove(struct platform_device *pdev)
 {
        struct clps711x_port *s = platform_get_drvdata(pdev);
 
-       return uart_remove_one_port(&clps711x_uart, &s->port);
+       uart_remove_one_port(&clps711x_uart, &s->port);
+
+       return 0;
 }
 
 static const struct of_device_id __maybe_unused clps711x_uart_dt_ids[] = {
index 349e7da..66afa9b 100644 (file)
@@ -1431,7 +1431,10 @@ static int cpm_uart_probe(struct platform_device *ofdev)
 static int cpm_uart_remove(struct platform_device *ofdev)
 {
        struct uart_cpm_port *pinfo = platform_get_drvdata(ofdev);
-       return uart_remove_one_port(&cpm_reg, &pinfo->port);
+
+       uart_remove_one_port(&cpm_reg, &pinfo->port);
+
+       return 0;
 }
 
 static const struct of_device_id cpm_uart_match[] = {
index c91916e..0e56fa6 100644 (file)
 
 /* Rx DMA timeout in ms, which is used to calculate Rx ring buffer size */
 #define DMA_RX_TIMEOUT         (10)
+#define DMA_RX_IDLE_CHARS      8
 #define UART_AUTOSUSPEND_TIMEOUT       3000
 
 #define DRIVER_NAME    "fsl-lpuart"
@@ -282,6 +283,7 @@ struct lpuart_port {
        struct scatterlist      rx_sgl, tx_sgl[2];
        struct circ_buf         rx_ring;
        int                     rx_dma_rng_buf_len;
+       int                     last_residue;
        unsigned int            dma_tx_nents;
        wait_queue_head_t       dma_wait;
        bool                    is_cs7; /* Set to true when character size is 7 */
@@ -331,7 +333,7 @@ static struct lpuart_soc_data imx8qxp_data = {
        .devtype = IMX8QXP_LPUART,
        .iotype = UPIO_MEM32,
        .reg_off = IMX_REG_OFF,
-       .rx_watermark = 31,
+       .rx_watermark = 7, /* A lower watermark is ideal for low baud rates. */
 };
 static struct lpuart_soc_data imxrt1050_data = {
        .devtype = IMXRT1050_LPUART,
@@ -1255,6 +1257,8 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport)
                sport->port.icount.rx += copied;
        }
 
+       sport->last_residue = state.residue;
+
 exit:
        dma_sync_sg_for_device(chan->device->dev, &sport->rx_sgl, 1,
                               DMA_FROM_DEVICE);
@@ -1272,11 +1276,37 @@ static void lpuart_dma_rx_complete(void *arg)
        lpuart_copy_rx_to_tty(sport);
 }
 
+/*
+ * Timer function to simulate the hardware EOP (End Of Package) event.
+ * The timer callback is to check for new RX data and copy to TTY buffer.
+ * If no new data are received since last interval, the EOP condition is
+ * met, complete the DMA transfer by copying the data. Otherwise, just
+ * restart timer.
+ */
 static void lpuart_timer_func(struct timer_list *t)
 {
        struct lpuart_port *sport = from_timer(sport, t, lpuart_timer);
+       struct dma_chan *chan = sport->dma_rx_chan;
+       struct circ_buf *ring = &sport->rx_ring;
+       struct dma_tx_state state;
+       unsigned long flags;
+       int count;
 
-       lpuart_copy_rx_to_tty(sport);
+       dmaengine_tx_status(chan, sport->dma_rx_cookie, &state);
+       ring->head = sport->rx_sgl.length - state.residue;
+       count = CIRC_CNT(ring->head, ring->tail, sport->rx_sgl.length);
+
+       /* Check if new data received before copying */
+       if ((count != 0) && (sport->last_residue == state.residue))
+               lpuart_copy_rx_to_tty(sport);
+       else
+               mod_timer(&sport->lpuart_timer,
+                         jiffies + sport->dma_rx_timeout);
+
+       if (spin_trylock_irqsave(&sport->port.lock, flags)) {
+               sport->last_residue = state.residue;
+               spin_unlock_irqrestore(&sport->port.lock, flags);
+       }
 }
 
 static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
@@ -1297,9 +1327,20 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
         */
        sport->rx_dma_rng_buf_len = (DMA_RX_TIMEOUT * baud /  bits / 1000) * 2;
        sport->rx_dma_rng_buf_len = (1 << fls(sport->rx_dma_rng_buf_len));
+       sport->rx_dma_rng_buf_len = max_t(int,
+                                         sport->rxfifo_size * 2,
+                                         sport->rx_dma_rng_buf_len);
+       /*
+        * Keep this condition check in case rxfifo_size is unavailable
+        * for some SoCs.
+        */
        if (sport->rx_dma_rng_buf_len < 16)
                sport->rx_dma_rng_buf_len = 16;
 
+       sport->last_residue = 0;
+       sport->dma_rx_timeout = max(nsecs_to_jiffies(
+               sport->port.frame_time * DMA_RX_IDLE_CHARS), 1UL);
+
        ring->buf = kzalloc(sport->rx_dma_rng_buf_len, GFP_ATOMIC);
        if (!ring->buf)
                return -ENOMEM;
@@ -1687,12 +1728,13 @@ static void lpuart_rx_dma_startup(struct lpuart_port *sport)
        if (!sport->dma_rx_chan)
                goto err;
 
+       /* set default Rx DMA timeout */
+       sport->dma_rx_timeout = msecs_to_jiffies(DMA_RX_TIMEOUT);
+
        ret = lpuart_start_rx_dma(sport);
        if (ret)
                goto err;
 
-       /* set Rx DMA timeout */
-       sport->dma_rx_timeout = msecs_to_jiffies(DMA_RX_TIMEOUT);
        if (!sport->dma_rx_timeout)
                sport->dma_rx_timeout = 1;
 
index c5e1756..b2bf3cb 100644 (file)
@@ -2467,7 +2467,9 @@ static int imx_uart_remove(struct platform_device *pdev)
 {
        struct imx_port *sport = platform_get_drvdata(pdev);
 
-       return uart_remove_one_port(&imx_uart_uart_driver, &sport->port);
+       uart_remove_one_port(&imx_uart_uart_driver, &sport->port);
+
+       return 0;
 }
 
 static void imx_uart_restore_context(struct imx_port *sport)
index a58e927..d413f97 100644 (file)
@@ -889,7 +889,9 @@ static int lqasc_remove(struct platform_device *pdev)
 {
        struct uart_port *port = platform_get_drvdata(pdev);
 
-       return uart_remove_one_port(&lqasc_reg, port);
+       uart_remove_one_port(&lqasc_reg, port);
+
+       return 0;
 }
 
 static const struct ltq_soc_data soc_data_lantiq = {
index 54e82f4..4b98d13 100644 (file)
@@ -3154,13 +3154,12 @@ EXPORT_SYMBOL(uart_add_one_port);
  * This unhooks (and hangs up) the specified port structure from the core
  * driver. No further calls will be made to the low-level code for this port.
  */
-int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
+void uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
 {
        struct uart_state *state = drv->state + uport->line;
        struct tty_port *port = &state->port;
        struct uart_port *uart_port;
        struct tty_struct *tty;
-       int ret = 0;
 
        mutex_lock(&port_mutex);
 
@@ -3176,7 +3175,6 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
 
        if (!uart_port) {
                mutex_unlock(&port->mutex);
-               ret = -EINVAL;
                goto out;
        }
        uport->flags |= UPF_DEAD;
@@ -3219,8 +3217,6 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
        mutex_unlock(&port->mutex);
 out:
        mutex_unlock(&port_mutex);
-
-       return ret;
 }
 EXPORT_SYMBOL(uart_remove_one_port);
 
index 5215e69..dc2f205 100644 (file)
@@ -796,7 +796,9 @@ static int asc_serial_remove(struct platform_device *pdev)
 {
        struct uart_port *port = platform_get_drvdata(pdev);
 
-       return uart_remove_one_port(&asc_uart_driver, port);
+       uart_remove_one_port(&asc_uart_driver, port);
+
+       return 0;
 }
 
 #ifdef CONFIG_PM_SLEEP
index 1e38fc9..e9e11a2 100644 (file)
@@ -1755,13 +1755,10 @@ static int stm32_usart_serial_remove(struct platform_device *pdev)
        struct uart_port *port = platform_get_drvdata(pdev);
        struct stm32_port *stm32_port = to_stm32_port(port);
        const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
-       int err;
        u32 cr3;
 
        pm_runtime_get_sync(&pdev->dev);
-       err = uart_remove_one_port(&stm32_usart_driver, port);
-       if (err)
-               return(err);
+       uart_remove_one_port(&stm32_usart_driver, port);
 
        pm_runtime_disable(&pdev->dev);
        pm_runtime_set_suspended(&pdev->dev);
index 94584e5..6795748 100644 (file)
@@ -685,18 +685,15 @@ static int ulite_assign(struct device *dev, int id, phys_addr_t base, int irq,
  *
  * @dev: pointer to device structure
  */
-static int ulite_release(struct device *dev)
+static void ulite_release(struct device *dev)
 {
        struct uart_port *port = dev_get_drvdata(dev);
-       int rc = 0;
 
        if (port) {
-               rc = uart_remove_one_port(&ulite_uart_driver, port);
+               uart_remove_one_port(&ulite_uart_driver, port);
                dev_set_drvdata(dev, NULL);
                port->mapbase = 0;
        }
-
-       return rc;
 }
 
 /**
@@ -900,14 +897,13 @@ static int ulite_remove(struct platform_device *pdev)
 {
        struct uart_port *port = dev_get_drvdata(&pdev->dev);
        struct uartlite_data *pdata = port->private_data;
-       int rc;
 
        clk_disable_unprepare(pdata->clk);
-       rc = ulite_release(&pdev->dev);
+       ulite_release(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
        pm_runtime_set_suspended(&pdev->dev);
        pm_runtime_dont_use_autosuspend(&pdev->dev);
-       return rc;
+       return 0;
 }
 
 /* work with hotplug and coldplug */
index 8e521c6..20a7516 100644 (file)
@@ -1670,14 +1670,13 @@ static int cdns_uart_remove(struct platform_device *pdev)
 {
        struct uart_port *port = platform_get_drvdata(pdev);
        struct cdns_uart *cdns_uart_data = port->private_data;
-       int rc;
 
        /* Remove the cdns_uart port from the serial core */
 #ifdef CONFIG_COMMON_CLK
        clk_notifier_unregister(cdns_uart_data->uartclk,
                        &cdns_uart_data->clk_rate_change_nb);
 #endif
-       rc = uart_remove_one_port(cdns_uart_data->cdns_uart_driver, port);
+       uart_remove_one_port(cdns_uart_data->cdns_uart_driver, port);
        port->mapbase = 0;
        clk_disable_unprepare(cdns_uart_data->uartclk);
        clk_disable_unprepare(cdns_uart_data->pclk);
@@ -1693,7 +1692,7 @@ static int cdns_uart_remove(struct platform_device *pdev)
 
        if (!--instances)
                uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
-       return rc;
+       return 0;
 }
 
 static struct platform_driver cdns_uart_platform_driver = {
index 6f78f30..eb44420 100644 (file)
@@ -7,17 +7,34 @@
 #ifndef _LINUX_SERIAL_8250_H
 #define _LINUX_SERIAL_8250_H
 
+#include <linux/errno.h>
 #include <linux/serial_core.h>
 #include <linux/serial_reg.h>
 #include <linux/platform_device.h>
 
+struct uart_8250_port;
+
 /*
  * This is the platform device platform_data structure
+ *
+ * @mapsize:   Port size for ioremap()
+ * @bugs:      Port bugs
+ *
+ * @dl_read: ``u32 ()(struct uart_8250_port *up)``
+ *
+ *     UART divisor latch read.
+ *
+ * @dl_write: ``void ()(struct uart_8250_port *up, u32 value)``
+ *
+ *     Write @value into UART divisor latch.
+ *
+ *     Locking: Caller holds port's lock.
  */
 struct plat_serial8250_port {
        unsigned long   iobase;         /* io base address */
        void __iomem    *membase;       /* ioremap cookie or NULL */
        resource_size_t mapbase;        /* resource base */
+       resource_size_t mapsize;
        unsigned int    uartclk;        /* UART clock rate */
        unsigned int    irq;            /* interrupt number */
        unsigned long   irqflags;       /* request_irq flags */
@@ -28,8 +45,11 @@ struct plat_serial8250_port {
        unsigned char   has_sysrq;      /* supports magic SysRq */
        unsigned int    type;           /* If UPF_FIXED_TYPE */
        upf_t           flags;          /* UPF_* flags */
+       u16             bugs;           /* port bugs */
        unsigned int    (*serial_in)(struct uart_port *, int);
        void            (*serial_out)(struct uart_port *, int, int);
+       u32             (*dl_read)(struct uart_8250_port *up);
+       void            (*dl_write)(struct uart_8250_port *up, u32 value);
        void            (*set_termios)(struct uart_port *,
                                       struct ktermios *new,
                                       const struct ktermios *old);
@@ -90,14 +110,23 @@ struct uart_8250_em485 {
  * their own 8250 ports without registering their own
  * platform device.  Using these will make your driver
  * dependent on the 8250 driver.
+ *
+ * @dl_read: ``u32 ()(struct uart_8250_port *port)``
+ *
+ *     UART divisor latch read.
+ *
+ * @dl_write: ``void ()(struct uart_8250_port *port, u32 value)``
+ *
+ *     Write @value into UART divisor latch.
+ *
+ *     Locking: Caller holds port's lock.
  */
-
 struct uart_8250_port {
        struct uart_port        port;
        struct timer_list       timer;          /* "no irq" timer */
        struct list_head        list;           /* ports on this IRQ */
        u32                     capabilities;   /* port capabilities */
-       unsigned short          bugs;           /* port bugs */
+       u16                     bugs;           /* port bugs */
        bool                    fifo_bug;       /* min RX trigger if enabled */
        unsigned int            tx_loadsz;      /* transmit fifo load size */
        unsigned char           acr;
@@ -129,8 +158,8 @@ struct uart_8250_port {
        const struct uart_8250_ops *ops;
 
        /* 8250 specific callbacks */
-       int                     (*dl_read)(struct uart_8250_port *);
-       void                    (*dl_write)(struct uart_8250_port *, int);
+       u32                     (*dl_read)(struct uart_8250_port *up);
+       void                    (*dl_write)(struct uart_8250_port *up, u32 value);
 
        struct uart_8250_em485 *em485;
        void                    (*rs485_start_tx)(struct uart_8250_port *);
@@ -183,8 +212,11 @@ void serial8250_set_isa_configurator(void (*v)(int port, struct uart_port *up,
                                               u32 *capabilities));
 
 #ifdef CONFIG_SERIAL_8250_RT288X
-unsigned int au_serial_in(struct uart_port *p, int offset);
-void au_serial_out(struct uart_port *p, int offset, int value);
+int rt288x_setup(struct uart_port *p);
+int au_platform_setup(struct plat_serial8250_port *p);
+#else
+static inline int rt288x_setup(struct uart_port *p) { return -ENODEV; }
+static inline int au_platform_setup(struct plat_serial8250_port *p) { return -ENODEV; }
 #endif
 
 #endif
index 66ecec1..ddcdb5b 100644 (file)
@@ -853,7 +853,7 @@ void uart_console_write(struct uart_port *port, const char *s,
 int uart_register_driver(struct uart_driver *uart);
 void uart_unregister_driver(struct uart_driver *uart);
 int uart_add_one_port(struct uart_driver *reg, struct uart_port *port);
-int uart_remove_one_port(struct uart_driver *reg, struct uart_port *port);
+void uart_remove_one_port(struct uart_driver *reg, struct uart_port *port);
 bool uart_match_port(const struct uart_port *port1,
                const struct uart_port *port2);