Merge tag 'tty-5.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 11 Jul 2019 22:38:21 +0000 (15:38 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 11 Jul 2019 22:38:21 +0000 (15:38 -0700)
Pull tty / serial driver updates from Greg KH:
 "Here is the "large" TTY and Serial driver update for 5.3-rc1.

  It's in the negative number of lines overall as we removed an obsolete
  serial driver that was causing problems for some people who were
  trying to clean up some apis (the mpsc.c driver, which only worked for
  some pre-production hardware that no one has anymore.)

  Other than that, lots of tiny changes, cleaning up small things along
  with some platform-specific serial driver updates.

  All of these have been in linux-next for a while now with no reported
  issues"

* tag 'tty-5.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (68 commits)
  tty: serial: fsl_lpuart: add imx8qxp support
  serial: imx: set_termios(): preserve RTS state
  serial: imx: set_termios(): clarify RTS/CTS bits calculation
  serial: imx: set_termios(): factor-out 'ucr2' initial value
  serial: sh-sci: Terminate TX DMA during buffer flushing
  serial: sh-sci: Fix TX DMA buffer flushing and workqueue races
  serial: mpsc: Remove obsolete MPSC driver
  serial: 8250: 8250_core: Fix missing unlock on error in serial8250_register_8250_port()
  serial: stm32: add RX and TX FIFO flush
  serial: stm32: add support of RX FIFO threshold
  serial: stm32: add support of TX FIFO threshold
  serial: stm32: update PIO transmission
  serial: stm32: add support of timeout interrupt for RX
  Revert "serial: 8250: Don't service RX FIFO if interrupts are disabled"
  tty/serial/8250: use mctrl_gpio helpers
  serial: mctrl_gpio: Check if GPIO property exisits before requesting it
  serial: 8250: pericom_do_set_divisor can be static
  tty: serial_core: Set port active bit in uart_port_activate
  serial: 8250: Add MSR/MCR TIOCM conversion wrapper functions
  serial: 8250: factor out serial8250_{set,clear}_THRI() helpers
  ...

34 files changed:
Documentation/admin-guide/devices.txt
Documentation/devicetree/bindings/serial/8250.txt
arch/ia64/hp/sim/simserial.c
drivers/ipack/devices/ipoctal.h
drivers/tty/serial/8250/8250.h
drivers/tty/serial/8250/8250_core.c
drivers/tty/serial/8250/8250_dma.c
drivers/tty/serial/8250/8250_mtk.c
drivers/tty/serial/8250/8250_of.c
drivers/tty/serial/8250/8250_omap.c
drivers/tty/serial/8250/8250_pci.c
drivers/tty/serial/8250/8250_pnp.c
drivers/tty/serial/8250/8250_port.c
drivers/tty/serial/8250/Kconfig
drivers/tty/serial/Kconfig
drivers/tty/serial/Makefile
drivers/tty/serial/amba-pl011.c
drivers/tty/serial/cpm_uart/cpm_uart_core.c
drivers/tty/serial/digicolor-usart.c
drivers/tty/serial/fsl_lpuart.c
drivers/tty/serial/imx.c
drivers/tty/serial/max310x.c
drivers/tty/serial/mpsc.c [deleted file]
drivers/tty/serial/msm_serial.c
drivers/tty/serial/serial_core.c
drivers/tty/serial/serial_mctrl_gpio.c
drivers/tty/serial/sh-sci.c
drivers/tty/serial/stm32-usart.c
drivers/tty/serial/stm32-usart.h
drivers/tty/serial/xilinx_uartps.c
drivers/tty/tty_io.c
include/linux/mv643xx.h
include/linux/serial_8250.h
include/uapi/linux/serial_core.h

index 1649117e6087d3eb7462c4a73452654d32a29e00..e56e00655153a7ac3ebef87c3d4cd85f0aa56961 100644 (file)
                 41 = /dev/ttySMX0              Motorola i.MX - port 0
                 42 = /dev/ttySMX1              Motorola i.MX - port 1
                 43 = /dev/ttySMX2              Motorola i.MX - port 2
-                44 = /dev/ttyMM0               Marvell MPSC - port 0
-                45 = /dev/ttyMM1               Marvell MPSC - port 1
+                44 = /dev/ttyMM0               Marvell MPSC - port 0 (obsolete unused)
+                45 = /dev/ttyMM1               Marvell MPSC - port 1 (obsolete unused)
                 46 = /dev/ttyCPM0              PPC CPM (SCC or SMC) - port 0
                    ...
                 47 = /dev/ttyCPM5              PPC CPM (SCC or SMC) - port 5
index 3cba12f855b783b6d672e5935362b5a54080bcad..20d351f268ef3bc5a2ae690310545efe3fa93dfd 100644 (file)
@@ -53,6 +53,9 @@ Optional properties:
   programmable TX FIFO thresholds.
 - resets : phandle + reset specifier pairs
 - overrun-throttle-ms : how long to pause uart rx when input overrun is encountered.
+- {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD
+  line respectively. It will use specified GPIO instead of the peripheral
+  function pin for the UART feature. If unsure, don't specify this property.
 
 Note:
 * fsl,ns16550:
@@ -74,3 +77,19 @@ Example:
                interrupts = <10>;
                reg-shift = <2>;
        };
+
+Example for OMAP UART using GPIO-based modem control signals:
+
+       uart4: serial@49042000 {
+               compatible = "ti,omap3-uart";
+               reg = <0x49042000 0x400>;
+               interrupts = <80>;
+               ti,hwmods = "uart4";
+               clock-frequency = <48000000>;
+               cts-gpios = <&gpio3 5 GPIO_ACTIVE_LOW>;
+               rts-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>;
+               dtr-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
+               dsr-gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+               dcd-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
+               rng-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+       };
index 7aeb48a185763f7b944388634e2dcab38a1b7413..1a338e54133420905a23fb4c68d8a7bcf323053e 100644 (file)
@@ -324,8 +324,6 @@ static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
        return -ENOIOCTLCMD;
 }
 
-#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-
 /*
  * This routine will shutdown a serial port; interrupts are disabled, and
  * DTR is dropped if the hangup on close termio flag is on.
index 920537883238b5521c074578979d17b7140fa642..75f83ba774a4f6224997868dc6ce9b3266ac2a24 100644 (file)
@@ -15,7 +15,6 @@
 #define NR_CHANNELS            8
 #define IPOCTAL_MAX_BOARDS     16
 #define MAX_DEVICES            (NR_CHANNELS * IPOCTAL_MAX_BOARDS)
-#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
 
 /**
  * struct ipoctal_stats -- Stats since last reset
index ebfb0bd5bef59d679c36cd0a2562145a11509f1a..33ad9d6de532342c8d40f86bcd123d23b1ea391b 100644 (file)
@@ -11,6 +11,8 @@
 #include <linux/serial_reg.h>
 #include <linux/dmaengine.h>
 
+#include "../serial_mctrl_gpio.h"
+
 struct uart_8250_dma {
        int (*tx_dma)(struct uart_8250_port *p);
        int (*rx_dma)(struct uart_8250_port *p);
@@ -128,6 +130,24 @@ static inline void serial_dl_write(struct uart_8250_port *up, int value)
        up->dl_write(up, value);
 }
 
+static inline bool serial8250_set_THRI(struct uart_8250_port *up)
+{
+       if (up->ier & UART_IER_THRI)
+               return false;
+       up->ier |= UART_IER_THRI;
+       serial_out(up, UART_IER, up->ier);
+       return true;
+}
+
+static inline bool serial8250_clear_THRI(struct uart_8250_port *up)
+{
+       if (!(up->ier & UART_IER_THRI))
+               return false;
+       up->ier &= ~UART_IER_THRI;
+       serial_out(up, UART_IER, up->ier);
+       return true;
+}
+
 struct uart_8250_port *serial8250_get_port(int line);
 
 void serial8250_rpm_get(struct uart_8250_port *p);
@@ -139,14 +159,82 @@ void serial8250_rpm_put_tx(struct uart_8250_port *p);
 int serial8250_em485_init(struct uart_8250_port *p);
 void serial8250_em485_destroy(struct uart_8250_port *p);
 
+/* MCR <-> TIOCM conversion */
+static inline int serial8250_TIOCM_to_MCR(int tiocm)
+{
+       int mcr = 0;
+
+       if (tiocm & TIOCM_RTS)
+               mcr |= UART_MCR_RTS;
+       if (tiocm & TIOCM_DTR)
+               mcr |= UART_MCR_DTR;
+       if (tiocm & TIOCM_OUT1)
+               mcr |= UART_MCR_OUT1;
+       if (tiocm & TIOCM_OUT2)
+               mcr |= UART_MCR_OUT2;
+       if (tiocm & TIOCM_LOOP)
+               mcr |= UART_MCR_LOOP;
+
+       return mcr;
+}
+
+static inline int serial8250_MCR_to_TIOCM(int mcr)
+{
+       int tiocm = 0;
+
+       if (mcr & UART_MCR_RTS)
+               tiocm |= TIOCM_RTS;
+       if (mcr & UART_MCR_DTR)
+               tiocm |= TIOCM_DTR;
+       if (mcr & UART_MCR_OUT1)
+               tiocm |= TIOCM_OUT1;
+       if (mcr & UART_MCR_OUT2)
+               tiocm |= TIOCM_OUT2;
+       if (mcr & UART_MCR_LOOP)
+               tiocm |= TIOCM_LOOP;
+
+       return tiocm;
+}
+
+/* MSR <-> TIOCM conversion */
+static inline int serial8250_MSR_to_TIOCM(int msr)
+{
+       int tiocm = 0;
+
+       if (msr & UART_MSR_DCD)
+               tiocm |= TIOCM_CAR;
+       if (msr & UART_MSR_RI)
+               tiocm |= TIOCM_RNG;
+       if (msr & UART_MSR_DSR)
+               tiocm |= TIOCM_DSR;
+       if (msr & UART_MSR_CTS)
+               tiocm |= TIOCM_CTS;
+
+       return tiocm;
+}
+
 static inline void serial8250_out_MCR(struct uart_8250_port *up, int value)
 {
        serial_out(up, UART_MCR, value);
+
+       if (up->gpios)
+               mctrl_gpio_set(up->gpios, serial8250_MCR_to_TIOCM(value));
 }
 
 static inline int serial8250_in_MCR(struct uart_8250_port *up)
 {
-       return serial_in(up, UART_MCR);
+       int mctrl;
+
+       mctrl = serial_in(up, UART_MCR);
+
+       if (up->gpios) {
+               unsigned int mctrl_gpio = 0;
+
+               mctrl_gpio = mctrl_gpio_get_outputs(up->gpios, &mctrl_gpio);
+               mctrl |= serial8250_TIOCM_to_MCR(mctrl_gpio);
+       }
+
+       return mctrl;
 }
 
 #if defined(__alpha__) && !defined(CONFIG_PCI)
index e441221e04b9aa67186bf6784236486d6f30cdce..df3bcc0b2d747f920e3411972cc1462b7ad5ee3f 100644 (file)
@@ -14,6 +14,7 @@
  *           serial8250_register_8250_port() ports
  */
 
+#include <linux/acpi.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/ioport.h>
@@ -982,6 +983,8 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
 
        uart = serial8250_find_match_or_unused(&up->port);
        if (uart && uart->port.type != PORT_8250_CIR) {
+               struct mctrl_gpios *gpios;
+
                if (uart->port.dev)
                        uart_remove_one_port(&serial8250_reg, &uart->port);
 
@@ -1016,6 +1019,22 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
                if (up->port.flags & UPF_FIXED_TYPE)
                        uart->port.type = up->port.type;
 
+               /*
+                * Only call mctrl_gpio_init(), if the device has no ACPI
+                * companion device
+                */
+               if (!has_acpi_companion(uart->port.dev)) {
+                       gpios = mctrl_gpio_init(&uart->port, 0);
+                       if (IS_ERR(gpios)) {
+                               if (PTR_ERR(gpios) != -ENOSYS) {
+                                       ret = PTR_ERR(gpios);
+                                       goto out_unlock;
+                               }
+                       } else {
+                               uart->gpios = gpios;
+                       }
+               }
+
                serial8250_set_defaults(uart);
 
                /* Possibly override default I/O functions.  */
@@ -1082,6 +1101,7 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
                }
        }
 
+out_unlock:
        mutex_unlock(&serial_mutex);
 
        return ret;
index bfa1a857f3ffab6bd039e532c68fcf85c1afb0d4..890fa7ddaa7f36650a1b69a8554e5567fd674f84 100644 (file)
@@ -34,10 +34,8 @@ static void __dma_tx_complete(void *param)
                uart_write_wakeup(&p->port);
 
        ret = serial8250_tx_dma(p);
-       if (ret) {
-               p->ier |= UART_IER_THRI;
-               serial_port_out(&p->port, UART_IER, p->ier);
-       }
+       if (ret)
+               serial8250_set_THRI(p);
 
        spin_unlock_irqrestore(&p->port.lock, flags);
 }
@@ -100,10 +98,7 @@ int serial8250_tx_dma(struct uart_8250_port *p)
        dma_async_issue_pending(dma->txchan);
        if (dma->tx_err) {
                dma->tx_err = 0;
-               if (p->ier & UART_IER_THRI) {
-                       p->ier &= ~UART_IER_THRI;
-                       serial_out(p, UART_IER, p->ier);
-               }
+               serial8250_clear_THRI(p);
        }
        return 0;
 err:
index 417c7c810df9bd0d5396dc7a3f37470c5b458bfb..b411ba4eb5e9517082596559722893bed816834b 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/serial_8250.h>
@@ -47,7 +48,6 @@
 #define MTK_UART_DMA_EN_RX     0x5
 
 #define MTK_UART_ESCAPE_CHAR   0x77    /* Escape char added under sw fc */
-#define MTK_UART_TX_SIZE       UART_XMIT_SIZE
 #define MTK_UART_RX_SIZE       0x8000
 #define MTK_UART_TX_TRIGGER    1
 #define MTK_UART_RX_TRIGGER    MTK_UART_RX_SIZE
@@ -70,6 +70,7 @@ struct mtk8250_data {
 #ifdef CONFIG_SERIAL_8250_DMA
        enum dma_rx_status      rx_status;
 #endif
+       int                     rx_wakeup_irq;
 };
 
 /* flow control mode */
@@ -89,28 +90,30 @@ static void mtk8250_dma_rx_complete(void *param)
        struct mtk8250_data *data = up->port.private_data;
        struct tty_port *tty_port = &up->port.state->port;
        struct dma_tx_state state;
+       int copied, total, cnt;
        unsigned char *ptr;
-       int copied;
 
-       dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr,
-                               dma->rx_size, DMA_FROM_DEVICE);
+       if (data->rx_status == DMA_RX_SHUTDOWN)
+               return;
 
        dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
+       total = dma->rx_size - state.residue;
+       cnt = total;
 
-       if (data->rx_status == DMA_RX_SHUTDOWN)
-               return;
+       if ((data->rx_pos + cnt) > dma->rx_size)
+               cnt = dma->rx_size - data->rx_pos;
 
-       if ((data->rx_pos + state.residue) <= dma->rx_size) {
-               ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
-               copied = tty_insert_flip_string(tty_port, ptr, state.residue);
-       } else {
-               ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
-               copied = tty_insert_flip_string(tty_port, ptr,
-                                               dma->rx_size - data->rx_pos);
+       ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
+       copied = tty_insert_flip_string(tty_port, ptr, cnt);
+       data->rx_pos += cnt;
+
+       if (total > cnt) {
                ptr = (unsigned char *)(dma->rx_buf);
-               copied += tty_insert_flip_string(tty_port, ptr,
-                               data->rx_pos + state.residue - dma->rx_size);
+               cnt = total - cnt;
+               copied += tty_insert_flip_string(tty_port, ptr, cnt);
+               data->rx_pos = cnt;
        }
+
        up->port.icount.rx += copied;
 
        tty_flip_buffer_push(tty_port);
@@ -121,9 +124,7 @@ static void mtk8250_dma_rx_complete(void *param)
 static void mtk8250_rx_dma(struct uart_8250_port *up)
 {
        struct uart_8250_dma *dma = up->dma;
-       struct mtk8250_data *data = up->port.private_data;
        struct dma_async_tx_descriptor  *desc;
-       struct dma_tx_state      state;
 
        desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr,
                                           dma->rx_size, DMA_DEV_TO_MEM,
@@ -138,12 +139,6 @@ static void mtk8250_rx_dma(struct uart_8250_port *up)
 
        dma->rx_cookie = dmaengine_submit(desc);
 
-       dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
-       data->rx_pos = state.residue;
-
-       dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr,
-                                  dma->rx_size, DMA_FROM_DEVICE);
-
        dma_async_issue_pending(dma->rxchan);
 }
 
@@ -156,13 +151,11 @@ static void mtk8250_dma_enable(struct uart_8250_port *up)
        if (data->rx_status != DMA_RX_START)
                return;
 
-       dma->rxconf.direction           = DMA_DEV_TO_MEM;
-       dma->rxconf.src_addr_width      = dma->rx_size / 1024;
-       dma->rxconf.src_addr            = dma->rx_addr;
+       dma->rxconf.src_port_window_size        = dma->rx_size;
+       dma->rxconf.src_addr                            = dma->rx_addr;
 
-       dma->txconf.direction           = DMA_MEM_TO_DEV;
-       dma->txconf.dst_addr_width      = MTK_UART_TX_SIZE / 1024;
-       dma->txconf.dst_addr            = dma->tx_addr;
+       dma->txconf.dst_port_window_size        = UART_XMIT_SIZE;
+       dma->txconf.dst_addr                            = dma->tx_addr;
 
        serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
                UART_FCR_CLEAR_XMIT);
@@ -551,6 +544,8 @@ static int mtk8250_probe(struct platform_device *pdev)
        pm_runtime_set_active(&pdev->dev);
        pm_runtime_enable(&pdev->dev);
 
+       data->rx_wakeup_irq = platform_get_irq(pdev, 1);
+
        return 0;
 }
 
@@ -572,15 +567,35 @@ static int mtk8250_remove(struct platform_device *pdev)
 static int __maybe_unused mtk8250_suspend(struct device *dev)
 {
        struct mtk8250_data *data = dev_get_drvdata(dev);
+       int irq = data->rx_wakeup_irq;
+       int err;
 
        serial8250_suspend_port(data->line);
 
+       pinctrl_pm_select_sleep_state(dev);
+       if (irq >= 0) {
+               err = enable_irq_wake(irq);
+               if (err) {
+                       dev_err(dev,
+                               "failed to enable irq wake on IRQ %d: %d\n",
+                               irq, err);
+                       pinctrl_pm_select_default_state(dev);
+                       serial8250_resume_port(data->line);
+                       return err;
+               }
+       }
+
        return 0;
 }
 
 static int __maybe_unused mtk8250_resume(struct device *dev)
 {
        struct mtk8250_data *data = dev_get_drvdata(dev);
+       int irq = data->rx_wakeup_irq;
+
+       if (irq >= 0)
+               disable_irq_wake(irq);
+       pinctrl_pm_select_default_state(dev);
 
        serial8250_resume_port(data->line);
 
index 0277479c87e91f7303fcba6c9f87f3f2762319a8..0826cfdbd40637560a8ccdc77c6be68ba0e2f048 100644 (file)
@@ -70,9 +70,10 @@ static int of_platform_serial_setup(struct platform_device *ofdev,
                /* Get clk rate through clk driver if present */
                info->clk = devm_clk_get(&ofdev->dev, NULL);
                if (IS_ERR(info->clk)) {
-                       dev_warn(&ofdev->dev,
-                               "clk or clock-frequency not defined\n");
                        ret = PTR_ERR(info->clk);
+                       if (ret != -EPROBE_DEFER)
+                               dev_warn(&ofdev->dev,
+                                        "failed to get clock: %d\n", ret);
                        goto err_pmruntime;
                }
 
@@ -205,18 +206,16 @@ err_pmruntime:
 /*
  * Try to register a serial port
  */
-static const struct of_device_id of_platform_serial_table[];
 static int of_platform_serial_probe(struct platform_device *ofdev)
 {
-       const struct of_device_id *match;
        struct of_serial_info *info;
        struct uart_8250_port port8250;
+       unsigned int port_type;
        u32 tx_threshold;
-       int port_type;
        int ret;
 
-       match = of_match_device(of_platform_serial_table, &ofdev->dev);
-       if (!match)
+       port_type = (unsigned long)of_device_get_match_data(&ofdev->dev);
+       if (port_type == PORT_UNKNOWN)
                return -EINVAL;
 
        if (of_property_read_bool(ofdev->dev.of_node, "used-by-rtas"))
@@ -226,7 +225,6 @@ static int of_platform_serial_probe(struct platform_device *ofdev)
        if (info == NULL)
                return -ENOMEM;
 
-       port_type = (unsigned long)match->data;
        memset(&port8250, 0, sizeof(port8250));
        ret = of_platform_serial_setup(ofdev, port_type, &port8250.port, info);
        if (ret)
index 0a8316632d751563ef12fe6b74c69a0570286f97..3ef65cbd2478a5cd36ede984a6c1a6de39ce2bb7 100644 (file)
@@ -141,18 +141,20 @@ static void omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
 
        serial8250_do_set_mctrl(port, mctrl);
 
-       /*
-        * Turn off autoRTS if RTS is lowered and restore autoRTS setting
-        * if RTS is raised
-        */
-       lcr = serial_in(up, UART_LCR);
-       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
-       if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS))
-               priv->efr |= UART_EFR_RTS;
-       else
-               priv->efr &= ~UART_EFR_RTS;
-       serial_out(up, UART_EFR, priv->efr);
-       serial_out(up, UART_LCR, lcr);
+       if (!up->gpios) {
+               /*
+                * Turn off autoRTS if RTS is lowered and restore autoRTS
+                * setting if RTS is raised
+                */
+               lcr = serial_in(up, UART_LCR);
+               serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+               if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS))
+                       priv->efr |= UART_EFR_RTS;
+               else
+                       priv->efr &= ~UART_EFR_RTS;
+               serial_out(up, UART_EFR, priv->efr);
+               serial_out(up, UART_LCR, lcr);
+       }
 }
 
 /*
@@ -453,7 +455,8 @@ static void omap_8250_set_termios(struct uart_port *port,
        priv->efr = 0;
        up->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS | UPSTAT_AUTOXOFF);
 
-       if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW) {
+       if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW &&
+           !up->gpios) {
                /* Enable AUTOCTS (autoRTS is enabled when RTS is raised) */
                up->port.status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS;
                priv->efr |= UART_EFR_CTS;
@@ -923,15 +926,13 @@ static void omap_8250_dma_tx_complete(void *param)
                ret = omap_8250_tx_dma(p);
                if (ret)
                        en_thri = true;
-
        } else if (p->capabilities & UART_CAP_RPM) {
                en_thri = true;
        }
 
        if (en_thri) {
                dma->tx_err = 1;
-               p->ier |= UART_IER_THRI;
-               serial_port_out(&p->port, UART_IER, p->ier);
+               serial8250_set_THRI(p);
        }
 
        spin_unlock_irqrestore(&p->port.lock, flags);
@@ -959,10 +960,7 @@ static int omap_8250_tx_dma(struct uart_8250_port *p)
                        ret = -EBUSY;
                        goto err;
                }
-               if (p->ier & UART_IER_THRI) {
-                       p->ier &= ~UART_IER_THRI;
-                       serial_out(p, UART_IER, p->ier);
-               }
+               serial8250_clear_THRI(p);
                return 0;
        }
 
@@ -1020,10 +1018,7 @@ static int omap_8250_tx_dma(struct uart_8250_port *p)
        if (dma->tx_err)
                dma->tx_err = 0;
 
-       if (p->ier & UART_IER_THRI) {
-               p->ier &= ~UART_IER_THRI;
-               serial_out(p, UART_IER, p->ier);
-       }
+       serial8250_clear_THRI(p);
        if (skip_byte)
                serial_out(p, UART_TX, xmit->buf[xmit->tail]);
        return 0;
index df41397de478ef0412395535a6006e5e36580cd1..7f740b37700b1d91083f7f078faa871d91560e89 100644 (file)
@@ -1326,13 +1326,66 @@ static int pci_default_setup(struct serial_private *priv,
 
        return setup_port(priv, port, bar, offset, board->reg_shift);
 }
-
+static void
+pericom_do_set_divisor(struct uart_port *port, unsigned int baud,
+                              unsigned int quot, unsigned int quot_frac)
+{
+       int scr;
+       int lcr;
+       int actual_baud;
+       int tolerance;
+
+       for (scr = 5 ; scr <= 15 ; scr++) {
+               actual_baud = 921600 * 16 / scr;
+               tolerance = actual_baud / 50;
+
+               if ((baud < actual_baud + tolerance) &&
+                       (baud > actual_baud - tolerance)) {
+
+                       lcr = serial_port_in(port, UART_LCR);
+                       serial_port_out(port, UART_LCR, lcr | 0x80);
+
+                       serial_port_out(port, UART_DLL, 1);
+                       serial_port_out(port, UART_DLM, 0);
+                       serial_port_out(port, 2, 16 - scr);
+                       serial_port_out(port, UART_LCR, lcr);
+                       return;
+               } else if (baud > actual_baud) {
+                       break;
+               }
+       }
+       serial8250_do_set_divisor(port, baud, quot, quot_frac);
+}
 static int pci_pericom_setup(struct serial_private *priv,
                  const struct pciserial_board *board,
                  struct uart_8250_port *port, int idx)
 {
        unsigned int bar, offset = board->first_offset, maxnr;
 
+       bar = FL_GET_BASE(board->flags);
+       if (board->flags & FL_BASE_BARS)
+               bar += idx;
+       else
+               offset += idx * board->uart_offset;
+
+
+       maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) >>
+               (board->reg_shift + 3);
+
+       if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr)
+               return 1;
+
+       port->port.set_divisor = pericom_do_set_divisor;
+
+       return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+
+static int pci_pericom_setup_four_at_eight(struct serial_private *priv,
+                 const struct pciserial_board *board,
+                 struct uart_8250_port *port, int idx)
+{
+       unsigned int bar, offset = board->first_offset, maxnr;
+
        bar = FL_GET_BASE(board->flags);
        if (board->flags & FL_BASE_BARS)
                bar += idx;
@@ -1348,6 +1401,8 @@ static int pci_pericom_setup(struct serial_private *priv,
        if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr)
                return 1;
 
+       port->port.set_divisor = pericom_do_set_divisor;
+
        return setup_port(priv, port, bar, offset, board->reg_shift);
 }
 
@@ -1995,7 +2050,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .device         = PCI_DEVICE_ID_PERICOM_PI7C9X7954,
                .subvendor      = PCI_ANY_ID,
                .subdevice      = PCI_ANY_ID,
-               .setup          = pci_pericom_setup,
+               .setup          = pci_pericom_setup_four_at_eight,
        },
        /*
         * PLX
@@ -2032,107 +2087,113 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SDB,
                .subvendor  = PCI_ANY_ID,
                .subdevice  = PCI_ANY_ID,
-               .setup      = pci_pericom_setup,
+               .setup      = pci_pericom_setup_four_at_eight,
        },
        {
                .vendor     = PCI_VENDOR_ID_ACCESIO,
                .device     = PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4S,
                .subvendor  = PCI_ANY_ID,
                .subdevice  = PCI_ANY_ID,
-               .setup      = pci_pericom_setup,
+               .setup      = pci_pericom_setup_four_at_eight,
        },
        {
                .vendor     = PCI_VENDOR_ID_ACCESIO,
                .device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4DB,
                .subvendor  = PCI_ANY_ID,
                .subdevice  = PCI_ANY_ID,
-               .setup      = pci_pericom_setup,
+               .setup      = pci_pericom_setup_four_at_eight,
        },
        {
                .vendor     = PCI_VENDOR_ID_ACCESIO,
                .device     = PCI_DEVICE_ID_ACCESIO_MPCIE_COM232_4,
                .subvendor  = PCI_ANY_ID,
                .subdevice  = PCI_ANY_ID,
-               .setup      = pci_pericom_setup,
+               .setup      = pci_pericom_setup_four_at_eight,
        },
        {
                .vendor     = PCI_VENDOR_ID_ACCESIO,
                .device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SMDB,
                .subvendor  = PCI_ANY_ID,
                .subdevice  = PCI_ANY_ID,
-               .setup      = pci_pericom_setup,
+               .setup      = pci_pericom_setup_four_at_eight,
        },
        {
                .vendor     = PCI_VENDOR_ID_ACCESIO,
                .device     = PCI_DEVICE_ID_ACCESIO_MPCIE_COM_4SM,
                .subvendor  = PCI_ANY_ID,
                .subdevice  = PCI_ANY_ID,
-               .setup      = pci_pericom_setup,
+               .setup      = pci_pericom_setup_four_at_eight,
        },
        {
                .vendor     = PCI_VENDOR_ID_ACCESIO,
                .device     = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM422_4,
                .subvendor  = PCI_ANY_ID,
                .subdevice  = PCI_ANY_ID,
-               .setup      = pci_pericom_setup,
+               .setup      = pci_pericom_setup_four_at_eight,
        },
        {
                .vendor     = PCI_VENDOR_ID_ACCESIO,
                .device     = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM485_4,
                .subvendor  = PCI_ANY_ID,
                .subdevice  = PCI_ANY_ID,
-               .setup      = pci_pericom_setup,
+               .setup      = pci_pericom_setup_four_at_eight,
        },
        {
                .vendor     = PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4S,
                .device     = PCI_DEVICE_ID_ACCESIO_PCIE_ICM232_4,
                .subvendor  = PCI_ANY_ID,
                .subdevice  = PCI_ANY_ID,
-               .setup      = pci_pericom_setup,
+               .setup      = pci_pericom_setup_four_at_eight,
        },
        {
                .vendor     = PCI_VENDOR_ID_ACCESIO,
                .device     = PCI_DEVICE_ID_ACCESIO_MPCIE_ICM232_4,
                .subvendor  = PCI_ANY_ID,
                .subdevice  = PCI_ANY_ID,
-               .setup      = pci_pericom_setup,
+               .setup      = pci_pericom_setup_four_at_eight,
        },
        {
                .vendor     = PCI_VENDOR_ID_ACCESIO,
                .device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM422_4,
                .subvendor  = PCI_ANY_ID,
                .subdevice  = PCI_ANY_ID,
-               .setup      = pci_pericom_setup,
+               .setup      = pci_pericom_setup_four_at_eight,
        },
        {
                .vendor     = PCI_VENDOR_ID_ACCESIO,
                .device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM485_4,
                .subvendor  = PCI_ANY_ID,
                .subdevice  = PCI_ANY_ID,
-               .setup      = pci_pericom_setup,
+               .setup      = pci_pericom_setup_four_at_eight,
        },
        {
                .vendor     = PCI_VENDOR_ID_ACCESIO,
                .device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM232_4,
                .subvendor  = PCI_ANY_ID,
                .subdevice  = PCI_ANY_ID,
-               .setup      = pci_pericom_setup,
+               .setup      = pci_pericom_setup_four_at_eight,
        },
        {
                .vendor     = PCI_VENDOR_ID_ACCESIO,
                .device     = PCI_DEVICE_ID_ACCESIO_PCIE_COM_4SM,
                .subvendor  = PCI_ANY_ID,
                .subdevice  = PCI_ANY_ID,
-               .setup      = pci_pericom_setup,
+               .setup      = pci_pericom_setup_four_at_eight,
        },
        {
                .vendor     = PCI_VENDOR_ID_ACCESIO,
                .device     = PCI_DEVICE_ID_ACCESIO_PCIE_ICM_4SM,
                .subvendor  = PCI_ANY_ID,
                .subdevice  = PCI_ANY_ID,
-               .setup      = pci_pericom_setup,
+               .setup      = pci_pericom_setup_four_at_eight,
        },
-       /*
+       {
+               .vendor     = PCI_VENDOR_ID_ACCESIO,
+               .device     = PCI_ANY_ID,
+               .subvendor  = PCI_ANY_ID,
+               .subdevice  = PCI_ANY_ID,
+               .setup      = pci_pericom_setup,
+       },      /*
         * SBS Technologies, Inc., PMC-OCTALPRO 232
         */
        {
index 431e69a5a6a053361e3fe147775a35bd376c5f40..dfca33141fcc64f325bce3c51dcdc59a20df1107 100644 (file)
@@ -462,8 +462,8 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
                return -ENODEV;
 
        dev_dbg(&dev->dev,
-                "Setup PNP port: port %lx, mem %pa, irq %d, type %d\n",
-                uart.port.iobase, &uart.port.mapbase,
+                "Setup PNP port: port %#lx, mem %#llx, irq %u, type %u\n",
+                uart.port.iobase, (unsigned long long)uart.port.mapbase,
                 uart.port.irq, uart.port.iotype);
 
        if (flags & CIR_PORT) {
index d2f3310abe543a243304af3b1ae806728eff56d6..c1cec808571b63f498cdb0de6706163fc19b59c6 100644 (file)
@@ -1502,11 +1502,8 @@ static void __stop_tx_rs485(struct uart_8250_port *p)
 
 static inline void __do_stop_tx(struct uart_8250_port *p)
 {
-       if (p->ier & UART_IER_THRI) {
-               p->ier &= ~UART_IER_THRI;
-               serial_out(p, UART_IER, p->ier);
+       if (serial8250_clear_THRI(p))
                serial8250_rpm_put_tx(p);
-       }
 }
 
 static inline void __stop_tx(struct uart_8250_port *p)
@@ -1555,10 +1552,7 @@ static inline void __start_tx(struct uart_port *port)
        if (up->dma && !up->dma->tx_dma(up))
                return;
 
-       if (!(up->ier & UART_IER_THRI)) {
-               up->ier |= UART_IER_THRI;
-               serial_port_out(port, UART_IER, up->ier);
-
+       if (serial8250_set_THRI(up)) {
                if (up->bugs & UART_BUG_TXEN) {
                        unsigned char lsr;
 
@@ -1662,6 +1656,8 @@ static void serial8250_disable_ms(struct uart_port *port)
        if (up->bugs & UART_BUG_NOMSR)
                return;
 
+       mctrl_gpio_disable_ms(up->gpios);
+
        up->ier &= ~UART_IER_MSI;
        serial_port_out(port, UART_IER, up->ier);
 }
@@ -1674,6 +1670,8 @@ static void serial8250_enable_ms(struct uart_port *port)
        if (up->bugs & UART_BUG_NOMSR)
                return;
 
+       mctrl_gpio_enable_ms(up->gpios);
+
        up->ier |= UART_IER_MSI;
 
        serial8250_rpm_get(up);
@@ -1869,13 +1867,13 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
 
        status = serial_port_in(port, UART_LSR);
 
-       if (status & (UART_LSR_DR | UART_LSR_BI) &&
-           iir & UART_IIR_RDI) {
+       if (status & (UART_LSR_DR | UART_LSR_BI)) {
                if (!up->dma || handle_rx_dma(up, iir))
                        status = serial8250_rx_chars(up, status);
        }
        serial8250_modem_status(up);
-       if ((!up->dma || up->dma->tx_err) && (status & UART_LSR_THRE))
+       if ((!up->dma || up->dma->tx_err) && (status & UART_LSR_THRE) &&
+               (up->ier & UART_IER_THRI))
                serial8250_tx_chars(up);
 
        uart_unlock_and_check_sysrq(port, flags);
@@ -1944,22 +1942,17 @@ unsigned int serial8250_do_get_mctrl(struct uart_port *port)
 {
        struct uart_8250_port *up = up_to_u8250p(port);
        unsigned int status;
-       unsigned int ret;
+       unsigned int val;
 
        serial8250_rpm_get(up);
        status = serial8250_modem_status(up);
        serial8250_rpm_put(up);
 
-       ret = 0;
-       if (status & UART_MSR_DCD)
-               ret |= TIOCM_CAR;
-       if (status & UART_MSR_RI)
-               ret |= TIOCM_RNG;
-       if (status & UART_MSR_DSR)
-               ret |= TIOCM_DSR;
-       if (status & UART_MSR_CTS)
-               ret |= TIOCM_CTS;
-       return ret;
+       val = serial8250_MSR_to_TIOCM(status);
+       if (up->gpios)
+               return mctrl_gpio_get(up->gpios, &val);
+
+       return val;
 }
 EXPORT_SYMBOL_GPL(serial8250_do_get_mctrl);
 
@@ -1973,18 +1966,9 @@ static unsigned int serial8250_get_mctrl(struct uart_port *port)
 void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl)
 {
        struct uart_8250_port *up = up_to_u8250p(port);
-       unsigned char mcr = 0;
+       unsigned char mcr;
 
-       if (mctrl & TIOCM_RTS)
-               mcr |= UART_MCR_RTS;
-       if (mctrl & TIOCM_DTR)
-               mcr |= UART_MCR_DTR;
-       if (mctrl & TIOCM_OUT1)
-               mcr |= UART_MCR_OUT1;
-       if (mctrl & TIOCM_OUT2)
-               mcr |= UART_MCR_OUT2;
-       if (mctrl & TIOCM_LOOP)
-               mcr |= UART_MCR_LOOP;
+       mcr = serial8250_TIOCM_to_MCR(mctrl);
 
        mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr;
 
index 296115f6a4d80c02ad49b11470feb976c1f703be..509f6a3bb9ff125ab12e717aa5b77c37fe34d6f4 100644 (file)
@@ -8,6 +8,7 @@ config SERIAL_8250
        tristate "8250/16550 and compatible serial support"
        depends on !S390
        select SERIAL_CORE
+       select SERIAL_MCTRL_GPIO if GPIOLIB
        ---help---
          This selects whether you want to include the driver for the standard
          serial ports.  The standard answer is Y.  People who might say N
index 0d31251e04ccbfdec5e59bf586c9bd7b8651ad93..b416c7b33f49659d777df9f3bb32597af67ad968 100644 (file)
@@ -457,20 +457,6 @@ config SERIAL_21285_CONSOLE
          your boot loader (lilo or loadlin) about how to pass options to the
          kernel at boot time.)
 
-config SERIAL_MPSC
-       bool "Marvell MPSC serial port support"
-       depends on MV64X60
-       select SERIAL_CORE
-       help
-         Say Y here if you want to use the Marvell MPSC serial controller.
-
-config SERIAL_MPSC_CONSOLE
-       bool "Support for console on Marvell MPSC serial port"
-       depends on SERIAL_MPSC
-       select SERIAL_CORE_CONSOLE
-       help
-         Say Y here if you want to support a serial console on a Marvell MPSC.
-
 config SERIAL_PXA
        bool "PXA serial port support (DEPRECATED)"
        depends on ARCH_PXA || ARCH_MMP
index 79c3d513db7e94d3336d9dcf1fa809c8f2816a80..7cd7cabfa6c413688dec0f86840825b4f0041891 100644 (file)
@@ -46,7 +46,6 @@ obj-$(CONFIG_SERIAL_CPM) += cpm_uart/
 obj-$(CONFIG_SERIAL_IMX) += imx.o
 obj-$(CONFIG_SERIAL_MPC52xx) += mpc52xx_uart.o
 obj-$(CONFIG_SERIAL_ICOM) += icom.o
-obj-$(CONFIG_SERIAL_MPSC) += mpsc.o
 obj-$(CONFIG_SERIAL_MESON) += meson_uart.o
 obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o
 obj-$(CONFIG_SERIAL_SCCNXP) += sccnxp.o
index 89ade213a1a9a66c3fa1b1956135456ded401f7b..5921a33b2a0766e7f6549d9cae36779309e0b6fb 100644 (file)
@@ -1717,7 +1717,7 @@ static int pl011_allocate_irq(struct uart_amba_port *uap)
 {
        pl011_write(uap->im, uap, REG_IMSC);
 
-       return request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap);
+       return request_irq(uap->port.irq, pl011_int, IRQF_SHARED, "uart-pl011", uap);
 }
 
 /*
index b929c7ae3a27eab8c28c218d8f467e62ae91862e..de6d02f7abe2b4fc5af6512f3587a457970bc65d 100644 (file)
@@ -407,7 +407,16 @@ static int cpm_uart_startup(struct uart_port *port)
                        clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX);
                }
                cpm_uart_initbd(pinfo);
-               cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX);
+               if (IS_SMC(pinfo)) {
+                       out_be32(&pinfo->smcup->smc_rstate, 0);
+                       out_be32(&pinfo->smcup->smc_tstate, 0);
+                       out_be16(&pinfo->smcup->smc_rbptr,
+                                in_be16(&pinfo->smcup->smc_rbase));
+                       out_be16(&pinfo->smcup->smc_tbptr,
+                                in_be16(&pinfo->smcup->smc_tbase));
+               } else {
+                       cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX);
+               }
        }
        /* Install interrupt handler. */
        retval = request_irq(port->irq, cpm_uart_int, 0, "cpm_uart", port);
@@ -567,8 +576,6 @@ static void cpm_uart_set_termios(struct uart_port *port,
        /*
         * Set up parity check flag
         */
-#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-
        port->read_status_mask = (BD_SC_EMPTY | BD_SC_OV);
        if (termios->c_iflag & INPCK)
                port->read_status_mask |= BD_SC_FR | BD_SC_PR;
@@ -861,16 +868,14 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo)
                 (u8 __iomem *)pinfo->tx_bd_base - DPRAM_BASE);
 
 /*
- *  In case SMC1 is being relocated...
+ *  In case SMC is being relocated...
  */
-#if defined (CONFIG_I2C_SPI_SMC1_UCODE_PATCH)
        out_be16(&up->smc_rbptr, in_be16(&pinfo->smcup->smc_rbase));
        out_be16(&up->smc_tbptr, in_be16(&pinfo->smcup->smc_tbase));
        out_be32(&up->smc_rstate, 0);
        out_be32(&up->smc_tstate, 0);
        out_be16(&up->smc_brkcr, 1);              /* number of break chars */
        out_be16(&up->smc_brkec, 0);
-#endif
 
        /* Set up the uart parameters in the
         * parameter ram.
@@ -884,8 +889,6 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo)
        out_be16(&up->smc_brkec, 0);
        out_be16(&up->smc_brkcr, 1);
 
-       cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX);
-
        /* Set UART mode, 8 bit, no parity, one stop.
         * Enable receive and transmit.
         */
index f460cca139e239c066b9aacaaf8f0c22500d7ade..13ac36e2da4f0f2ea36e48c7619f369dde3239bd 100644 (file)
@@ -541,7 +541,11 @@ static int __init digicolor_uart_init(void)
        if (ret)
                return ret;
 
-       return platform_driver_register(&digicolor_uart_platform);
+       ret = platform_driver_register(&digicolor_uart_platform);
+       if (ret)
+               uart_unregister_driver(&digicolor_uart);
+
+       return ret;
 }
 module_init(digicolor_uart_init);
 
index ea1c85e3b432c67125d3b7c365270b553a9dc053..92dad2b4ec36c0f3e31e558191ee5e421473a9f7 100644 (file)
 
 static DEFINE_IDA(fsl_lpuart_ida);
 
+enum lpuart_type {
+       VF610_LPUART,
+       LS1021A_LPUART,
+       IMX7ULP_LPUART,
+       IMX8QXP_LPUART,
+};
+
 struct lpuart_port {
        struct uart_port        port;
-       struct clk              *clk;
+       enum lpuart_type        devtype;
+       struct clk              *ipg_clk;
+       struct clk              *baud_clk;
        unsigned int            txfifo_size;
        unsigned int            rxfifo_size;
 
@@ -261,19 +270,29 @@ struct lpuart_port {
 };
 
 struct lpuart_soc_data {
-       char    iotype;
-       u8      reg_off;
+       enum lpuart_type devtype;
+       char iotype;
+       u8 reg_off;
 };
 
 static const struct lpuart_soc_data vf_data = {
+       .devtype = VF610_LPUART,
        .iotype = UPIO_MEM,
 };
 
 static const struct lpuart_soc_data ls_data = {
+       .devtype = LS1021A_LPUART,
        .iotype = UPIO_MEM32BE,
 };
 
-static struct lpuart_soc_data imx_data = {
+static struct lpuart_soc_data imx7ulp_data = {
+       .devtype = IMX7ULP_LPUART,
+       .iotype = UPIO_MEM32,
+       .reg_off = IMX_REG_OFF,
+};
+
+static struct lpuart_soc_data imx8qxp_data = {
+       .devtype = IMX8QXP_LPUART,
        .iotype = UPIO_MEM32,
        .reg_off = IMX_REG_OFF,
 };
@@ -281,7 +300,8 @@ static struct lpuart_soc_data imx_data = {
 static const struct of_device_id lpuart_dt_ids[] = {
        { .compatible = "fsl,vf610-lpuart",     .data = &vf_data, },
        { .compatible = "fsl,ls1021a-lpuart",   .data = &ls_data, },
-       { .compatible = "fsl,imx7ulp-lpuart",   .data = &imx_data, },
+       { .compatible = "fsl,imx7ulp-lpuart",   .data = &imx7ulp_data, },
+       { .compatible = "fsl,imx8qxp-lpuart",   .data = &imx8qxp_data, },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, lpuart_dt_ids);
@@ -289,6 +309,11 @@ MODULE_DEVICE_TABLE(of, lpuart_dt_ids);
 /* Forward declare this for the dma callbacks*/
 static void lpuart_dma_tx_complete(void *arg);
 
+static inline bool is_imx8qxp_lpuart(struct lpuart_port *sport)
+{
+       return sport->devtype == IMX8QXP_LPUART;
+}
+
 static inline u32 lpuart32_read(struct uart_port *port, u32 off)
 {
        switch (port->iotype) {
@@ -314,6 +339,39 @@ static inline void lpuart32_write(struct uart_port *port, u32 val,
        }
 }
 
+static int __lpuart_enable_clks(struct lpuart_port *sport, bool is_en)
+{
+       int ret = 0;
+
+       if (is_en) {
+               ret = clk_prepare_enable(sport->ipg_clk);
+               if (ret)
+                       return ret;
+
+               ret = clk_prepare_enable(sport->baud_clk);
+               if (ret) {
+                       clk_disable_unprepare(sport->ipg_clk);
+                       return ret;
+               }
+       } else {
+               clk_disable_unprepare(sport->baud_clk);
+               clk_disable_unprepare(sport->ipg_clk);
+       }
+
+       return 0;
+}
+
+static unsigned int lpuart_get_baud_clk_rate(struct lpuart_port *sport)
+{
+       if (is_imx8qxp_lpuart(sport))
+               return clk_get_rate(sport->baud_clk);
+
+       return clk_get_rate(sport->ipg_clk);
+}
+
+#define lpuart_enable_clks(x)  __lpuart_enable_clks(x, true)
+#define lpuart_disable_clks(x) __lpuart_enable_clks(x, false)
+
 static void lpuart_stop_tx(struct uart_port *port)
 {
        unsigned char temp;
@@ -1040,10 +1098,8 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
                sport->rx_dma_rng_buf_len = 16;
 
        ring->buf = kmalloc(sport->rx_dma_rng_buf_len, GFP_ATOMIC);
-       if (!ring->buf) {
-               dev_err(sport->port.dev, "Ring buf alloc failed\n");
+       if (!ring->buf)
                return -ENOMEM;
-       }
 
        sg_init_one(&sport->rx_sgl, ring->buf, sport->rx_dma_rng_buf_len);
        sg_set_buf(&sport->rx_sgl, ring->buf, sport->rx_dma_rng_buf_len);
@@ -2071,14 +2127,14 @@ lpuart_console_get_options(struct lpuart_port *sport, int *baud,
        brfa = readb(sport->port.membase + UARTCR4);
        brfa &= UARTCR4_BRFA_MASK;
 
-       uartclk = clk_get_rate(sport->clk);
+       uartclk = lpuart_get_baud_clk_rate(sport);
        /*
         * baud = mod_clk/(16*(sbr[13]+(brfa)/32)
         */
        baud_raw = uartclk / (16 * (sbr + brfa / 32));
 
        if (*baud != baud_raw)
-               printk(KERN_INFO "Serial: Console lpuart rounded baud rate"
+               dev_info(sport->port.dev, "Serial: Console lpuart rounded baud rate"
                                "from %d to %d\n", baud_raw, *baud);
 }
 
@@ -2114,14 +2170,14 @@ lpuart32_console_get_options(struct lpuart_port *sport, int *baud,
        bd = lpuart32_read(&sport->port, UARTBAUD);
        bd &= UARTBAUD_SBR_MASK;
        sbr = bd;
-       uartclk = clk_get_rate(sport->clk);
+       uartclk = lpuart_get_baud_clk_rate(sport);
        /*
         * baud = mod_clk/(16*(sbr[13]+(brfa)/32)
         */
        baud_raw = uartclk / (16 * sbr);
 
        if (*baud != baud_raw)
-               printk(KERN_INFO "Serial: Console lpuart rounded baud rate"
+               dev_info(sport->port.dev, "Serial: Console lpuart rounded baud rate"
                                "from %d to %d\n", baud_raw, *baud);
 }
 
@@ -2288,6 +2344,7 @@ static int lpuart_probe(struct platform_device *pdev)
        sport->port.mapbase = res->start;
        sport->port.dev = &pdev->dev;
        sport->port.type = PORT_LPUART;
+       sport->devtype = sdata->devtype;
        ret = platform_get_irq(pdev, 0);
        if (ret < 0) {
                dev_err(&pdev->dev, "cannot obtain irq\n");
@@ -2303,20 +2360,27 @@ static int lpuart_probe(struct platform_device *pdev)
 
        sport->port.rs485_config = lpuart_config_rs485;
 
-       sport->clk = devm_clk_get(&pdev->dev, "ipg");
-       if (IS_ERR(sport->clk)) {
-               ret = PTR_ERR(sport->clk);
-               dev_err(&pdev->dev, "failed to get uart clk: %d\n", ret);
+       sport->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
+       if (IS_ERR(sport->ipg_clk)) {
+               ret = PTR_ERR(sport->ipg_clk);
+               dev_err(&pdev->dev, "failed to get uart ipg clk: %d\n", ret);
                return ret;
        }
 
-       ret = clk_prepare_enable(sport->clk);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to enable uart clk: %d\n", ret);
-               return ret;
+       sport->baud_clk = NULL;
+       if (is_imx8qxp_lpuart(sport)) {
+               sport->baud_clk = devm_clk_get(&pdev->dev, "baud");
+               if (IS_ERR(sport->baud_clk)) {
+                       ret = PTR_ERR(sport->baud_clk);
+                       dev_err(&pdev->dev, "failed to get uart baud clk: %d\n", ret);
+                       return ret;
+               }
        }
 
-       sport->port.uartclk = clk_get_rate(sport->clk);
+       ret = lpuart_enable_clks(sport);
+       if (ret)
+               return ret;
+       sport->port.uartclk = lpuart_get_baud_clk_rate(sport);
 
        lpuart_ports[sport->port.line] = sport;
 
@@ -2364,7 +2428,7 @@ static int lpuart_probe(struct platform_device *pdev)
 
 failed_attach_port:
 failed_irq_request:
-       clk_disable_unprepare(sport->clk);
+       lpuart_disable_clks(sport);
        return ret;
 }
 
@@ -2376,7 +2440,7 @@ static int lpuart_remove(struct platform_device *pdev)
 
        ida_simple_remove(&fsl_lpuart_ida, sport->port.line);
 
-       clk_disable_unprepare(sport->clk);
+       lpuart_disable_clks(sport);
 
        if (sport->dma_tx_chan)
                dma_release_channel(sport->dma_tx_chan);
@@ -2441,7 +2505,7 @@ static int lpuart_suspend(struct device *dev)
        }
 
        if (sport->port.suspended && !irq_wake)
-               clk_disable_unprepare(sport->clk);
+               lpuart_disable_clks(sport);
 
        return 0;
 }
@@ -2453,7 +2517,7 @@ static int lpuart_resume(struct device *dev)
        unsigned long temp;
 
        if (sport->port.suspended && !irq_wake)
-               clk_prepare_enable(sport->clk);
+               lpuart_enable_clks(sport);
 
        if (lpuart_is_32(sport)) {
                lpuart32_setup_watermark(sport);
index 8b752e8950537d4ec706c0dace302e8b00230f53..57d6e6ba556efd83d533093f09fef45ddbc0e523 100644 (file)
@@ -383,6 +383,7 @@ static void imx_uart_ucrs_restore(struct imx_port *sport,
 }
 #endif
 
+/* called with port.lock taken and irqs caller dependent */
 static void imx_uart_rts_active(struct imx_port *sport, u32 *ucr2)
 {
        *ucr2 &= ~(UCR2_CTSC | UCR2_CTS);
@@ -391,6 +392,7 @@ static void imx_uart_rts_active(struct imx_port *sport, u32 *ucr2)
        mctrl_gpio_set(sport->gpios, sport->port.mctrl);
 }
 
+/* called with port.lock taken and irqs caller dependent */
 static void imx_uart_rts_inactive(struct imx_port *sport, u32 *ucr2)
 {
        *ucr2 &= ~UCR2_CTSC;
@@ -400,6 +402,7 @@ static void imx_uart_rts_inactive(struct imx_port *sport, u32 *ucr2)
        mctrl_gpio_set(sport->gpios, sport->port.mctrl);
 }
 
+/* called with port.lock taken and irqs caller dependent */
 static void imx_uart_rts_auto(struct imx_port *sport, u32 *ucr2)
 {
        *ucr2 |= UCR2_CTSC;
@@ -1549,40 +1552,46 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios,
                old_csize = CS8;
        }
 
+       del_timer_sync(&sport->timer);
+
+       /*
+        * Ask the core to calculate the divisor for us.
+        */
+       baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16);
+       quot = uart_get_divisor(port, baud);
+
+       spin_lock_irqsave(&sport->port.lock, flags);
+
+       /*
+        * Read current UCR2 and save it for future use, then clear all the bits
+        * except those we will or may need to preserve.
+        */
+       old_ucr2 = imx_uart_readl(sport, UCR2);
+       ucr2 = old_ucr2 & (UCR2_TXEN | UCR2_RXEN | UCR2_ATEN | UCR2_CTS);
+
+       ucr2 |= UCR2_SRST | UCR2_IRTS;
        if ((termios->c_cflag & CSIZE) == CS8)
-               ucr2 = UCR2_WS | UCR2_SRST | UCR2_IRTS;
-       else
-               ucr2 = UCR2_SRST | UCR2_IRTS;
-
-       if (termios->c_cflag & CRTSCTS) {
-               if (sport->have_rtscts) {
-                       ucr2 &= ~UCR2_IRTS;
-
-                       if (port->rs485.flags & SER_RS485_ENABLED) {
-                               /*
-                                * RTS is mandatory for rs485 operation, so keep
-                                * it under manual control and keep transmitter
-                                * disabled.
-                                */
-                               if (port->rs485.flags &
-                                   SER_RS485_RTS_AFTER_SEND)
-                                       imx_uart_rts_active(sport, &ucr2);
-                               else
-                                       imx_uart_rts_inactive(sport, &ucr2);
-                       } else {
-                               imx_uart_rts_auto(sport, &ucr2);
-                       }
-               } else {
-                       termios->c_cflag &= ~CRTSCTS;
-               }
-       } else if (port->rs485.flags & SER_RS485_ENABLED) {
-               /* disable transmitter */
+               ucr2 |= UCR2_WS;
+
+       if (!sport->have_rtscts)
+               termios->c_cflag &= ~CRTSCTS;
+
+       if (port->rs485.flags & SER_RS485_ENABLED) {
+               /*
+                * RTS is mandatory for rs485 operation, so keep
+                * it under manual control and keep transmitter
+                * disabled.
+                */
                if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
                        imx_uart_rts_active(sport, &ucr2);
                else
                        imx_uart_rts_inactive(sport, &ucr2);
-       }
 
+       } else if (termios->c_cflag & CRTSCTS)
+               imx_uart_rts_auto(sport, &ucr2);
+
+       if (termios->c_cflag & CRTSCTS)
+               ucr2 &= ~UCR2_IRTS;
 
        if (termios->c_cflag & CSTOPB)
                ucr2 |= UCR2_STPB;
@@ -1592,16 +1601,6 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios,
                        ucr2 |= UCR2_PROE;
        }
 
-       del_timer_sync(&sport->timer);
-
-       /*
-        * Ask the core to calculate the divisor for us.
-        */
-       baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16);
-       quot = uart_get_divisor(port, baud);
-
-       spin_lock_irqsave(&sport->port.lock, flags);
-
        sport->port.read_status_mask = 0;
        if (termios->c_iflag & INPCK)
                sport->port.read_status_mask |= (URXD_FRMERR | URXD_PRERR);
@@ -1639,7 +1638,6 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios,
        imx_uart_writel(sport,
                        old_ucr1 & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN),
                        UCR1);
-       old_ucr2 = imx_uart_readl(sport, UCR2);
        imx_uart_writel(sport, old_ucr2 & ~UCR2_ATEN, UCR2);
 
        while (!(imx_uart_readl(sport, USR2) & USR2_TXDC))
@@ -1647,7 +1645,6 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios,
 
        /* then, disable everything */
        imx_uart_writel(sport, old_ucr2 & ~(UCR2_TXEN | UCR2_RXEN | UCR2_ATEN), UCR2);
-       old_ucr2 &= (UCR2_TXEN | UCR2_RXEN | UCR2_ATEN);
 
        /* custom-baudrate handling */
        div = sport->port.uartclk / (baud * 16);
@@ -1685,8 +1682,7 @@ imx_uart_set_termios(struct uart_port *port, struct ktermios *termios,
 
        imx_uart_writel(sport, old_ucr1, UCR1);
 
-       /* set the parity, stop bits and data size */
-       imx_uart_writel(sport, ucr2 | old_ucr2, UCR2);
+       imx_uart_writel(sport, ucr2, UCR2);
 
        if (UART_ENABLE_MS(&sport->port, termios->c_cflag))
                imx_uart_enable_ms(&sport->port);
@@ -2015,7 +2011,7 @@ imx_uart_console_get_options(struct imx_port *sport, int *baud,
                }
 
                if (*baud != baud_raw)
-                       pr_info("Console IMX rounded baud rate from %d to %d\n",
+                       dev_info(sport->port.dev, "Console IMX rounded baud rate from %d to %d\n",
                                baud_raw, *baud);
        }
 }
index e5aebbf5f302f06c7128bd9c0f9433d8e677b142..e6c48a99bd85772730c895d081328368646c1dc8 100644 (file)
@@ -258,12 +258,17 @@ struct max310x_one {
        struct work_struct      tx_work;
        struct work_struct      md_work;
        struct work_struct      rs_work;
+
+       u8 wr_header;
+       u8 rd_header;
+       u8 rx_buf[MAX310X_FIFO_SIZE];
 };
+#define to_max310x_port(_port) \
+       container_of(_port, struct max310x_one, port)
 
 struct max310x_port {
        struct max310x_devtype  *devtype;
        struct regmap           *regmap;
-       struct mutex            mutex;
        struct clk              *clk;
 #ifdef CONFIG_GPIOLIB
        struct gpio_chip        gpio;
@@ -496,37 +501,48 @@ static bool max310x_reg_precious(struct device *dev, unsigned int reg)
 
 static int max310x_set_baud(struct uart_port *port, int baud)
 {
-       unsigned int mode = 0, clk = port->uartclk, div = clk / baud;
-
-       /* Check for minimal value for divider */
-       if (div < 16)
-               div = 16;
+       unsigned int mode = 0, div = 0, frac = 0, c = 0, F = 0;
 
-       if (clk % baud && (div / 16) < 0x8000) {
+       /*
+        * Calculate the integer divisor first. Select a proper mode
+        * in case if the requested baud is too high for the pre-defined
+        * clocks frequency.
+        */
+       div = port->uartclk / baud;
+       if (div < 8) {
+               /* Mode x4 */
+               c = 4;
+               mode = MAX310X_BRGCFG_4XMODE_BIT;
+       } else if (div < 16) {
                /* Mode x2 */
+               c = 8;
                mode = MAX310X_BRGCFG_2XMODE_BIT;
-               clk = port->uartclk * 2;
-               div = clk / baud;
-
-               if (clk % baud && (div / 16) < 0x8000) {
-                       /* Mode x4 */
-                       mode = MAX310X_BRGCFG_4XMODE_BIT;
-                       clk = port->uartclk * 4;
-                       div = clk / baud;
-               }
+       } else {
+               c = 16;
        }
 
-       max310x_port_write(port, MAX310X_BRGDIVMSB_REG, (div / 16) >> 8);
-       max310x_port_write(port, MAX310X_BRGDIVLSB_REG, div / 16);
-       max310x_port_write(port, MAX310X_BRGCFG_REG, (div % 16) | mode);
+       /* Calculate the divisor in accordance with the fraction coefficient */
+       div /= c;
+       F = c*baud;
 
-       return DIV_ROUND_CLOSEST(clk, div);
+       /* Calculate the baud rate fraction */
+       if (div > 0)
+               frac = (16*(port->uartclk % F)) / F;
+       else
+               div = 1;
+
+       max310x_port_write(port, MAX310X_BRGDIVMSB_REG, div >> 8);
+       max310x_port_write(port, MAX310X_BRGDIVLSB_REG, div);
+       max310x_port_write(port, MAX310X_BRGCFG_REG, frac | mode);
+
+       /* Return the actual baud rate we just programmed */
+       return (16*port->uartclk) / (c*(16*div + frac));
 }
 
 static int max310x_update_best_err(unsigned long f, long *besterr)
 {
        /* Use baudrate 115200 for calculate error */
-       long err = f % (115200 * 16);
+       long err = f % (460800 * 16);
 
        if ((*besterr < 0) || (*besterr > err)) {
                *besterr = err;
@@ -607,11 +623,11 @@ static int max310x_set_ref_clk(struct device *dev, struct max310x_port *s,
 
 static void max310x_batch_write(struct uart_port *port, u8 *txbuf, unsigned int len)
 {
-       u8 header[] = { (port->iobase + MAX310X_THR_REG) | MAX310X_WRITE_BIT };
+       struct max310x_one *one = to_max310x_port(port);
        struct spi_transfer xfer[] = {
                {
-                       .tx_buf = &header,
-                       .len = sizeof(header),
+                       .tx_buf = &one->wr_header,
+                       .len = sizeof(one->wr_header),
                }, {
                        .tx_buf = txbuf,
                        .len = len,
@@ -622,11 +638,11 @@ static void max310x_batch_write(struct uart_port *port, u8 *txbuf, unsigned int
 
 static void max310x_batch_read(struct uart_port *port, u8 *rxbuf, unsigned int len)
 {
-       u8 header[] = { port->iobase + MAX310X_RHR_REG };
+       struct max310x_one *one = to_max310x_port(port);
        struct spi_transfer xfer[] = {
                {
-                       .tx_buf = &header,
-                       .len = sizeof(header),
+                       .tx_buf = &one->rd_header,
+                       .len = sizeof(one->rd_header),
                }, {
                        .rx_buf = rxbuf,
                        .len = len,
@@ -637,8 +653,8 @@ static void max310x_batch_read(struct uart_port *port, u8 *rxbuf, unsigned int l
 
 static void max310x_handle_rx(struct uart_port *port, unsigned int rxlen)
 {
+       struct max310x_one *one = to_max310x_port(port);
        unsigned int sts, ch, flag, i;
-       u8 buf[MAX310X_FIFO_SIZE];
 
        if (port->read_status_mask == MAX310X_LSR_RXOVR_BIT) {
                /* We are just reading, happily ignoring any error conditions.
@@ -653,7 +669,7 @@ static void max310x_handle_rx(struct uart_port *port, unsigned int rxlen)
                 * */
 
                sts = max310x_port_read(port, MAX310X_LSR_IRQSTS_REG);
-               max310x_batch_read(port, buf, rxlen);
+               max310x_batch_read(port, one->rx_buf, rxlen);
 
                port->icount.rx += rxlen;
                flag = TTY_NORMAL;
@@ -664,9 +680,16 @@ static void max310x_handle_rx(struct uart_port *port, unsigned int rxlen)
                        port->icount.overrun++;
                }
 
-               for (i = 0; i < rxlen; ++i) {
-                       uart_insert_char(port, sts, MAX310X_LSR_RXOVR_BIT, buf[i], flag);
-               }
+               for (i = 0; i < (rxlen - 1); ++i)
+                       uart_insert_char(port, sts, 0, one->rx_buf[i], flag);
+
+               /*
+                * Handle the overrun case for the last character only, since
+                * the RxFIFO overflow happens after it is pushed to the FIFO
+                * tail.
+                */
+               uart_insert_char(port, sts, MAX310X_LSR_RXOVR_BIT,
+                                one->rx_buf[rxlen], flag);
 
        } else {
                if (unlikely(rxlen >= port->fifosize)) {
@@ -766,10 +789,9 @@ static void max310x_handle_tx(struct uart_port *port)
 
 static void max310x_start_tx(struct uart_port *port)
 {
-       struct max310x_one *one = container_of(port, struct max310x_one, port);
+       struct max310x_one *one = to_max310x_port(port);
 
-       if (!work_pending(&one->tx_work))
-               schedule_work(&one->tx_work);
+       schedule_work(&one->tx_work);
 }
 
 static irqreturn_t max310x_port_irq(struct max310x_port *s, int portno)
@@ -826,14 +848,11 @@ static irqreturn_t max310x_ist(int irq, void *dev_id)
        return IRQ_RETVAL(handled);
 }
 
-static void max310x_wq_proc(struct work_struct *ws)
+static void max310x_tx_proc(struct work_struct *ws)
 {
        struct max310x_one *one = container_of(ws, struct max310x_one, tx_work);
-       struct max310x_port *s = dev_get_drvdata(one->port.dev);
 
-       mutex_lock(&s->mutex);
        max310x_handle_tx(&one->port);
-       mutex_unlock(&s->mutex);
 }
 
 static unsigned int max310x_tx_empty(struct uart_port *port)
@@ -863,7 +882,7 @@ static void max310x_md_proc(struct work_struct *ws)
 
 static void max310x_set_mctrl(struct uart_port *port, unsigned int mctrl)
 {
-       struct max310x_one *one = container_of(port, struct max310x_one, port);
+       struct max310x_one *one = to_max310x_port(port);
 
        schedule_work(&one->md_work);
 }
@@ -962,37 +981,36 @@ static void max310x_set_termios(struct uart_port *port,
 static void max310x_rs_proc(struct work_struct *ws)
 {
        struct max310x_one *one = container_of(ws, struct max310x_one, rs_work);
-       unsigned int val;
+       unsigned int delay, mode1 = 0, mode2 = 0;
 
-       val = (one->port.rs485.delay_rts_before_send << 4) |
+       delay = (one->port.rs485.delay_rts_before_send << 4) |
                one->port.rs485.delay_rts_after_send;
-       max310x_port_write(&one->port, MAX310X_HDPIXDELAY_REG, val);
+       max310x_port_write(&one->port, MAX310X_HDPIXDELAY_REG, delay);
 
        if (one->port.rs485.flags & SER_RS485_ENABLED) {
-               max310x_port_update(&one->port, MAX310X_MODE1_REG,
-                               MAX310X_MODE1_TRNSCVCTRL_BIT,
-                               MAX310X_MODE1_TRNSCVCTRL_BIT);
-               max310x_port_update(&one->port, MAX310X_MODE2_REG,
-                               MAX310X_MODE2_ECHOSUPR_BIT,
-                               MAX310X_MODE2_ECHOSUPR_BIT);
-       } else {
-               max310x_port_update(&one->port, MAX310X_MODE1_REG,
-                               MAX310X_MODE1_TRNSCVCTRL_BIT, 0);
-               max310x_port_update(&one->port, MAX310X_MODE2_REG,
-                               MAX310X_MODE2_ECHOSUPR_BIT, 0);
+               mode1 = MAX310X_MODE1_TRNSCVCTRL_BIT;
+
+               if (!(one->port.rs485.flags & SER_RS485_RX_DURING_TX))
+                       mode2 = MAX310X_MODE2_ECHOSUPR_BIT;
        }
+
+       max310x_port_update(&one->port, MAX310X_MODE1_REG,
+                       MAX310X_MODE1_TRNSCVCTRL_BIT, mode1);
+       max310x_port_update(&one->port, MAX310X_MODE2_REG,
+                       MAX310X_MODE2_ECHOSUPR_BIT, mode2);
 }
 
 static int max310x_rs485_config(struct uart_port *port,
                                struct serial_rs485 *rs485)
 {
-       struct max310x_one *one = container_of(port, struct max310x_one, port);
+       struct max310x_one *one = to_max310x_port(port);
 
        if ((rs485->delay_rts_before_send > 0x0f) ||
            (rs485->delay_rts_after_send > 0x0f))
                return -ERANGE;
 
-       rs485->flags &= SER_RS485_RTS_ON_SEND | SER_RS485_ENABLED;
+       rs485->flags &= SER_RS485_RTS_ON_SEND | SER_RS485_RX_DURING_TX |
+                       SER_RS485_ENABLED;
        memset(rs485->padding, 0, sizeof(rs485->padding));
        port->rs485 = *rs485;
 
@@ -1018,6 +1036,22 @@ static int max310x_startup(struct uart_port *port)
        max310x_port_update(port, MAX310X_MODE2_REG,
                            MAX310X_MODE2_FIFORST_BIT, 0);
 
+       /* Configure mode1/mode2 to have rs485/rs232 enabled at startup */
+       val = (clamp(port->rs485.delay_rts_before_send, 0U, 15U) << 4) |
+               clamp(port->rs485.delay_rts_after_send, 0U, 15U);
+       max310x_port_write(port, MAX310X_HDPIXDELAY_REG, val);
+
+       if (port->rs485.flags & SER_RS485_ENABLED) {
+               max310x_port_update(port, MAX310X_MODE1_REG,
+                                   MAX310X_MODE1_TRNSCVCTRL_BIT,
+                                   MAX310X_MODE1_TRNSCVCTRL_BIT);
+
+               if (!(port->rs485.flags & SER_RS485_RX_DURING_TX))
+                       max310x_port_update(port, MAX310X_MODE2_REG,
+                                           MAX310X_MODE2_ECHOSUPR_BIT,
+                                           MAX310X_MODE2_ECHOSUPR_BIT);
+       }
+
        /* Configure flow control levels */
        /* Flow control halt level 96, resume level 48 */
        max310x_port_write(port, MAX310X_FLOWLVL_REG,
@@ -1269,8 +1303,6 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
        uartclk = max310x_set_ref_clk(dev, s, freq, xtal);
        dev_dbg(dev, "Reference clock set to %i Hz\n", uartclk);
 
-       mutex_init(&s->mutex);
-
        for (i = 0; i < devtype->nr; i++) {
                unsigned int line;
 
@@ -1298,11 +1330,15 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
                /* Clear IRQ status register */
                max310x_port_read(&s->p[i].port, MAX310X_IRQSTS_REG);
                /* Initialize queue for start TX */
-               INIT_WORK(&s->p[i].tx_work, max310x_wq_proc);
+               INIT_WORK(&s->p[i].tx_work, max310x_tx_proc);
                /* Initialize queue for changing LOOPBACK mode */
                INIT_WORK(&s->p[i].md_work, max310x_md_proc);
                /* Initialize queue for changing RS485 mode */
                INIT_WORK(&s->p[i].rs_work, max310x_rs_proc);
+               /* Initialize SPI-transfer buffers */
+               s->p[i].wr_header = (s->p[i].port.iobase + MAX310X_THR_REG) |
+                                   MAX310X_WRITE_BIT;
+               s->p[i].rd_header = (s->p[i].port.iobase + MAX310X_RHR_REG);
 
                /* Register port */
                ret = uart_add_one_port(&max310x_uart, &s->p[i].port);
@@ -1350,8 +1386,6 @@ out_uart:
                }
        }
 
-       mutex_destroy(&s->mutex);
-
 out_clk:
        clk_disable_unprepare(s->clk);
 
@@ -1372,7 +1406,6 @@ static int max310x_remove(struct device *dev)
                s->devtype->power(&s->p[i].port, 0);
        }
 
-       mutex_destroy(&s->mutex);
        clk_disable_unprepare(s->clk);
 
        return 0;
diff --git a/drivers/tty/serial/mpsc.c b/drivers/tty/serial/mpsc.c
deleted file mode 100644 (file)
index 1f60d6f..0000000
+++ /dev/null
@@ -1,2138 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Generic driver for the MPSC (UART mode) on Marvell parts (e.g., GT64240,
- * GT64260, MV64340, MV64360, GT96100, ... ).
- *
- * Author: Mark A. Greer <mgreer@mvista.com>
- *
- * Based on an old MPSC driver that was in the linuxppc tree.  It appears to
- * have been created by Chris Zankel (formerly of MontaVista) but there
- * is no proper Copyright so I'm not sure.  Apparently, parts were also
- * taken from PPCBoot (now U-Boot).  Also based on drivers/serial/8250.c
- * by Russell King.
- *
- * 2004 (c) MontaVista, Software, Inc.
- */
-/*
- * The MPSC interface is much like a typical network controller's interface.
- * That is, you set up separate rings of descriptors for transmitting and
- * receiving data.  There is also a pool of buffers with (one buffer per
- * descriptor) that incoming data are dma'd into or outgoing data are dma'd
- * out of.
- *
- * The MPSC requires two other controllers to be able to work.  The Baud Rate
- * Generator (BRG) provides a clock at programmable frequencies which determines
- * the baud rate.  The Serial DMA Controller (SDMA) takes incoming data from the
- * MPSC and DMA's it into memory or DMA's outgoing data and passes it to the
- * MPSC.  It is actually the SDMA interrupt that the driver uses to keep the
- * transmit and receive "engines" going (i.e., indicate data has been
- * transmitted or received).
- *
- * NOTES:
- *
- * 1) Some chips have an erratum where several regs cannot be
- * read.  To work around that, we keep a local copy of those regs in
- * 'mpsc_port_info'.
- *
- * 2) Some chips have an erratum where the ctlr will hang when the SDMA ctlr
- * accesses system mem with coherency enabled.  For that reason, the driver
- * assumes that coherency for that ctlr has been disabled.  This means
- * that when in a cache coherent system, the driver has to manually manage
- * the data cache on the areas that it touches because the dma_* macro are
- * basically no-ops.
- *
- * 3) There is an erratum (on PPC) where you can't use the instruction to do
- * a DMA_TO_DEVICE/cache clean so DMA_BIDIRECTIONAL/flushes are used in places
- * where a DMA_TO_DEVICE/clean would have [otherwise] sufficed.
- *
- * 4) AFAICT, hardware flow control isn't supported by the controller --MAG.
- */
-
-
-#if defined(CONFIG_SERIAL_MPSC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-#define SUPPORT_SYSRQ
-#endif
-
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/sysrq.h>
-#include <linux/serial.h>
-#include <linux/serial_core.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/mv643xx.h>
-#include <linux/platform_device.h>
-#include <linux/gfp.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#define        MPSC_NUM_CTLRS          2
-
-/*
- * Descriptors and buffers must be cache line aligned.
- * Buffers lengths must be multiple of cache line size.
- * Number of Tx & Rx descriptors must be powers of 2.
- */
-#define        MPSC_RXR_ENTRIES        32
-#define        MPSC_RXRE_SIZE          dma_get_cache_alignment()
-#define        MPSC_RXR_SIZE           (MPSC_RXR_ENTRIES * MPSC_RXRE_SIZE)
-#define        MPSC_RXBE_SIZE          dma_get_cache_alignment()
-#define        MPSC_RXB_SIZE           (MPSC_RXR_ENTRIES * MPSC_RXBE_SIZE)
-
-#define        MPSC_TXR_ENTRIES        32
-#define        MPSC_TXRE_SIZE          dma_get_cache_alignment()
-#define        MPSC_TXR_SIZE           (MPSC_TXR_ENTRIES * MPSC_TXRE_SIZE)
-#define        MPSC_TXBE_SIZE          dma_get_cache_alignment()
-#define        MPSC_TXB_SIZE           (MPSC_TXR_ENTRIES * MPSC_TXBE_SIZE)
-
-#define        MPSC_DMA_ALLOC_SIZE     (MPSC_RXR_SIZE + MPSC_RXB_SIZE + MPSC_TXR_SIZE \
-               + MPSC_TXB_SIZE + dma_get_cache_alignment() /* for alignment */)
-
-/* Rx and Tx Ring entry descriptors -- assume entry size is <= cacheline size */
-struct mpsc_rx_desc {
-       u16 bufsize;
-       u16 bytecnt;
-       u32 cmdstat;
-       u32 link;
-       u32 buf_ptr;
-} __attribute((packed));
-
-struct mpsc_tx_desc {
-       u16 bytecnt;
-       u16 shadow;
-       u32 cmdstat;
-       u32 link;
-       u32 buf_ptr;
-} __attribute((packed));
-
-/*
- * Some regs that have the erratum that you can't read them are are shared
- * between the two MPSC controllers.  This struct contains those shared regs.
- */
-struct mpsc_shared_regs {
-       phys_addr_t mpsc_routing_base_p;
-       phys_addr_t sdma_intr_base_p;
-
-       void __iomem *mpsc_routing_base;
-       void __iomem *sdma_intr_base;
-
-       u32 MPSC_MRR_m;
-       u32 MPSC_RCRR_m;
-       u32 MPSC_TCRR_m;
-       u32 SDMA_INTR_CAUSE_m;
-       u32 SDMA_INTR_MASK_m;
-};
-
-/* The main driver data structure */
-struct mpsc_port_info {
-       struct uart_port port;  /* Overlay uart_port structure */
-
-       /* Internal driver state for this ctlr */
-       u8 ready;
-       u8 rcv_data;
-
-       /* Info passed in from platform */
-       u8 mirror_regs;         /* Need to mirror regs? */
-       u8 cache_mgmt;          /* Need manual cache mgmt? */
-       u8 brg_can_tune;        /* BRG has baud tuning? */
-       u32 brg_clk_src;
-       u16 mpsc_max_idle;
-       int default_baud;
-       int default_bits;
-       int default_parity;
-       int default_flow;
-
-       /* Physical addresses of various blocks of registers (from platform) */
-       phys_addr_t mpsc_base_p;
-       phys_addr_t sdma_base_p;
-       phys_addr_t brg_base_p;
-
-       /* Virtual addresses of various blocks of registers (from platform) */
-       void __iomem *mpsc_base;
-       void __iomem *sdma_base;
-       void __iomem *brg_base;
-
-       /* Descriptor ring and buffer allocations */
-       void *dma_region;
-       dma_addr_t dma_region_p;
-
-       dma_addr_t rxr;         /* Rx descriptor ring */
-       dma_addr_t rxr_p;       /* Phys addr of rxr */
-       u8 *rxb;                /* Rx Ring I/O buf */
-       u8 *rxb_p;              /* Phys addr of rxb */
-       u32 rxr_posn;           /* First desc w/ Rx data */
-
-       dma_addr_t txr;         /* Tx descriptor ring */
-       dma_addr_t txr_p;       /* Phys addr of txr */
-       u8 *txb;                /* Tx Ring I/O buf */
-       u8 *txb_p;              /* Phys addr of txb */
-       int txr_head;           /* Where new data goes */
-       int txr_tail;           /* Where sent data comes off */
-       spinlock_t tx_lock;     /* transmit lock */
-
-       /* Mirrored values of regs we can't read (if 'mirror_regs' set) */
-       u32 MPSC_MPCR_m;
-       u32 MPSC_CHR_1_m;
-       u32 MPSC_CHR_2_m;
-       u32 MPSC_CHR_10_m;
-       u32 BRG_BCR_m;
-       struct mpsc_shared_regs *shared_regs;
-};
-
-/* Hooks to platform-specific code */
-int mpsc_platform_register_driver(void);
-void mpsc_platform_unregister_driver(void);
-
-/* Hooks back in to mpsc common to be called by platform-specific code */
-struct mpsc_port_info *mpsc_device_probe(int index);
-struct mpsc_port_info *mpsc_device_remove(int index);
-
-/* Main MPSC Configuration Register Offsets */
-#define        MPSC_MMCRL                      0x0000
-#define        MPSC_MMCRH                      0x0004
-#define        MPSC_MPCR                       0x0008
-#define        MPSC_CHR_1                      0x000c
-#define        MPSC_CHR_2                      0x0010
-#define        MPSC_CHR_3                      0x0014
-#define        MPSC_CHR_4                      0x0018
-#define        MPSC_CHR_5                      0x001c
-#define        MPSC_CHR_6                      0x0020
-#define        MPSC_CHR_7                      0x0024
-#define        MPSC_CHR_8                      0x0028
-#define        MPSC_CHR_9                      0x002c
-#define        MPSC_CHR_10                     0x0030
-#define        MPSC_CHR_11                     0x0034
-
-#define        MPSC_MPCR_FRZ                   (1 << 9)
-#define        MPSC_MPCR_CL_5                  0
-#define        MPSC_MPCR_CL_6                  1
-#define        MPSC_MPCR_CL_7                  2
-#define        MPSC_MPCR_CL_8                  3
-#define        MPSC_MPCR_SBL_1                 0
-#define        MPSC_MPCR_SBL_2                 1
-
-#define        MPSC_CHR_2_TEV                  (1<<1)
-#define        MPSC_CHR_2_TA                   (1<<7)
-#define        MPSC_CHR_2_TTCS                 (1<<9)
-#define        MPSC_CHR_2_REV                  (1<<17)
-#define        MPSC_CHR_2_RA                   (1<<23)
-#define        MPSC_CHR_2_CRD                  (1<<25)
-#define        MPSC_CHR_2_EH                   (1<<31)
-#define        MPSC_CHR_2_PAR_ODD              0
-#define        MPSC_CHR_2_PAR_SPACE            1
-#define        MPSC_CHR_2_PAR_EVEN             2
-#define        MPSC_CHR_2_PAR_MARK             3
-
-/* MPSC Signal Routing */
-#define        MPSC_MRR                        0x0000
-#define        MPSC_RCRR                       0x0004
-#define        MPSC_TCRR                       0x0008
-
-/* Serial DMA Controller Interface Registers */
-#define        SDMA_SDC                        0x0000
-#define        SDMA_SDCM                       0x0008
-#define        SDMA_RX_DESC                    0x0800
-#define        SDMA_RX_BUF_PTR                 0x0808
-#define        SDMA_SCRDP                      0x0810
-#define        SDMA_TX_DESC                    0x0c00
-#define        SDMA_SCTDP                      0x0c10
-#define        SDMA_SFTDP                      0x0c14
-
-#define        SDMA_DESC_CMDSTAT_PE            (1<<0)
-#define        SDMA_DESC_CMDSTAT_CDL           (1<<1)
-#define        SDMA_DESC_CMDSTAT_FR            (1<<3)
-#define        SDMA_DESC_CMDSTAT_OR            (1<<6)
-#define        SDMA_DESC_CMDSTAT_BR            (1<<9)
-#define        SDMA_DESC_CMDSTAT_MI            (1<<10)
-#define        SDMA_DESC_CMDSTAT_A             (1<<11)
-#define        SDMA_DESC_CMDSTAT_AM            (1<<12)
-#define        SDMA_DESC_CMDSTAT_CT            (1<<13)
-#define        SDMA_DESC_CMDSTAT_C             (1<<14)
-#define        SDMA_DESC_CMDSTAT_ES            (1<<15)
-#define        SDMA_DESC_CMDSTAT_L             (1<<16)
-#define        SDMA_DESC_CMDSTAT_F             (1<<17)
-#define        SDMA_DESC_CMDSTAT_P             (1<<18)
-#define        SDMA_DESC_CMDSTAT_EI            (1<<23)
-#define        SDMA_DESC_CMDSTAT_O             (1<<31)
-
-#define SDMA_DESC_DFLT                 (SDMA_DESC_CMDSTAT_O \
-               | SDMA_DESC_CMDSTAT_EI)
-
-#define        SDMA_SDC_RFT                    (1<<0)
-#define        SDMA_SDC_SFM                    (1<<1)
-#define        SDMA_SDC_BLMR                   (1<<6)
-#define        SDMA_SDC_BLMT                   (1<<7)
-#define        SDMA_SDC_POVR                   (1<<8)
-#define        SDMA_SDC_RIFB                   (1<<9)
-
-#define        SDMA_SDCM_ERD                   (1<<7)
-#define        SDMA_SDCM_AR                    (1<<15)
-#define        SDMA_SDCM_STD                   (1<<16)
-#define        SDMA_SDCM_TXD                   (1<<23)
-#define        SDMA_SDCM_AT                    (1<<31)
-
-#define        SDMA_0_CAUSE_RXBUF              (1<<0)
-#define        SDMA_0_CAUSE_RXERR              (1<<1)
-#define        SDMA_0_CAUSE_TXBUF              (1<<2)
-#define        SDMA_0_CAUSE_TXEND              (1<<3)
-#define        SDMA_1_CAUSE_RXBUF              (1<<8)
-#define        SDMA_1_CAUSE_RXERR              (1<<9)
-#define        SDMA_1_CAUSE_TXBUF              (1<<10)
-#define        SDMA_1_CAUSE_TXEND              (1<<11)
-
-#define        SDMA_CAUSE_RX_MASK      (SDMA_0_CAUSE_RXBUF | SDMA_0_CAUSE_RXERR \
-               | SDMA_1_CAUSE_RXBUF | SDMA_1_CAUSE_RXERR)
-#define        SDMA_CAUSE_TX_MASK      (SDMA_0_CAUSE_TXBUF | SDMA_0_CAUSE_TXEND \
-               | SDMA_1_CAUSE_TXBUF | SDMA_1_CAUSE_TXEND)
-
-/* SDMA Interrupt registers */
-#define        SDMA_INTR_CAUSE                 0x0000
-#define        SDMA_INTR_MASK                  0x0080
-
-/* Baud Rate Generator Interface Registers */
-#define        BRG_BCR                         0x0000
-#define        BRG_BTR                         0x0004
-
-/*
- * Define how this driver is known to the outside (we've been assigned a
- * range on the "Low-density serial ports" major).
- */
-#define MPSC_MAJOR                     204
-#define MPSC_MINOR_START               44
-#define        MPSC_DRIVER_NAME                "MPSC"
-#define        MPSC_DEV_NAME                   "ttyMM"
-#define        MPSC_VERSION                    "1.00"
-
-static struct mpsc_port_info mpsc_ports[MPSC_NUM_CTLRS];
-static struct mpsc_shared_regs mpsc_shared_regs;
-static struct uart_driver mpsc_reg;
-
-static void mpsc_start_rx(struct mpsc_port_info *pi);
-static void mpsc_free_ring_mem(struct mpsc_port_info *pi);
-static void mpsc_release_port(struct uart_port *port);
-/*
- ******************************************************************************
- *
- * Baud Rate Generator Routines (BRG)
- *
- ******************************************************************************
- */
-static void mpsc_brg_init(struct mpsc_port_info *pi, u32 clk_src)
-{
-       u32     v;
-
-       v = (pi->mirror_regs) ? pi->BRG_BCR_m : readl(pi->brg_base + BRG_BCR);
-       v = (v & ~(0xf << 18)) | ((clk_src & 0xf) << 18);
-
-       if (pi->brg_can_tune)
-               v &= ~(1 << 25);
-
-       if (pi->mirror_regs)
-               pi->BRG_BCR_m = v;
-       writel(v, pi->brg_base + BRG_BCR);
-
-       writel(readl(pi->brg_base + BRG_BTR) & 0xffff0000,
-               pi->brg_base + BRG_BTR);
-}
-
-static void mpsc_brg_enable(struct mpsc_port_info *pi)
-{
-       u32     v;
-
-       v = (pi->mirror_regs) ? pi->BRG_BCR_m : readl(pi->brg_base + BRG_BCR);
-       v |= (1 << 16);
-
-       if (pi->mirror_regs)
-               pi->BRG_BCR_m = v;
-       writel(v, pi->brg_base + BRG_BCR);
-}
-
-static void mpsc_brg_disable(struct mpsc_port_info *pi)
-{
-       u32     v;
-
-       v = (pi->mirror_regs) ? pi->BRG_BCR_m : readl(pi->brg_base + BRG_BCR);
-       v &= ~(1 << 16);
-
-       if (pi->mirror_regs)
-               pi->BRG_BCR_m = v;
-       writel(v, pi->brg_base + BRG_BCR);
-}
-
-/*
- * To set the baud, we adjust the CDV field in the BRG_BCR reg.
- * From manual: Baud = clk / ((CDV+1)*2) ==> CDV = (clk / (baud*2)) - 1.
- * However, the input clock is divided by 16 in the MPSC b/c of how
- * 'MPSC_MMCRH' was set up so we have to divide the 'clk' used in our
- * calculation by 16 to account for that.  So the real calculation
- * that accounts for the way the mpsc is set up is:
- * CDV = (clk / (baud*2*16)) - 1 ==> CDV = (clk / (baud << 5)) - 1.
- */
-static void mpsc_set_baudrate(struct mpsc_port_info *pi, u32 baud)
-{
-       u32     cdv = (pi->port.uartclk / (baud << 5)) - 1;
-       u32     v;
-
-       mpsc_brg_disable(pi);
-       v = (pi->mirror_regs) ? pi->BRG_BCR_m : readl(pi->brg_base + BRG_BCR);
-       v = (v & 0xffff0000) | (cdv & 0xffff);
-
-       if (pi->mirror_regs)
-               pi->BRG_BCR_m = v;
-       writel(v, pi->brg_base + BRG_BCR);
-       mpsc_brg_enable(pi);
-}
-
-/*
- ******************************************************************************
- *
- * Serial DMA Routines (SDMA)
- *
- ******************************************************************************
- */
-
-static void mpsc_sdma_burstsize(struct mpsc_port_info *pi, u32 burst_size)
-{
-       u32     v;
-
-       pr_debug("mpsc_sdma_burstsize[%d]: burst_size: %d\n",
-                       pi->port.line, burst_size);
-
-       burst_size >>= 3; /* Divide by 8 b/c reg values are 8-byte chunks */
-
-       if (burst_size < 2)
-               v = 0x0;        /* 1 64-bit word */
-       else if (burst_size < 4)
-               v = 0x1;        /* 2 64-bit words */
-       else if (burst_size < 8)
-               v = 0x2;        /* 4 64-bit words */
-       else
-               v = 0x3;        /* 8 64-bit words */
-
-       writel((readl(pi->sdma_base + SDMA_SDC) & (0x3 << 12)) | (v << 12),
-               pi->sdma_base + SDMA_SDC);
-}
-
-static void mpsc_sdma_init(struct mpsc_port_info *pi, u32 burst_size)
-{
-       pr_debug("mpsc_sdma_init[%d]: burst_size: %d\n", pi->port.line,
-               burst_size);
-
-       writel((readl(pi->sdma_base + SDMA_SDC) & 0x3ff) | 0x03f,
-               pi->sdma_base + SDMA_SDC);
-       mpsc_sdma_burstsize(pi, burst_size);
-}
-
-static u32 mpsc_sdma_intr_mask(struct mpsc_port_info *pi, u32 mask)
-{
-       u32     old, v;
-
-       pr_debug("mpsc_sdma_intr_mask[%d]: mask: 0x%x\n", pi->port.line, mask);
-
-       old = v = (pi->mirror_regs) ? pi->shared_regs->SDMA_INTR_MASK_m :
-               readl(pi->shared_regs->sdma_intr_base + SDMA_INTR_MASK);
-
-       mask &= 0xf;
-       if (pi->port.line)
-               mask <<= 8;
-       v &= ~mask;
-
-       if (pi->mirror_regs)
-               pi->shared_regs->SDMA_INTR_MASK_m = v;
-       writel(v, pi->shared_regs->sdma_intr_base + SDMA_INTR_MASK);
-
-       if (pi->port.line)
-               old >>= 8;
-       return old & 0xf;
-}
-
-static void mpsc_sdma_intr_unmask(struct mpsc_port_info *pi, u32 mask)
-{
-       u32     v;
-
-       pr_debug("mpsc_sdma_intr_unmask[%d]: mask: 0x%x\n", pi->port.line,mask);
-
-       v = (pi->mirror_regs) ? pi->shared_regs->SDMA_INTR_MASK_m
-               : readl(pi->shared_regs->sdma_intr_base + SDMA_INTR_MASK);
-
-       mask &= 0xf;
-       if (pi->port.line)
-               mask <<= 8;
-       v |= mask;
-
-       if (pi->mirror_regs)
-               pi->shared_regs->SDMA_INTR_MASK_m = v;
-       writel(v, pi->shared_regs->sdma_intr_base + SDMA_INTR_MASK);
-}
-
-static void mpsc_sdma_intr_ack(struct mpsc_port_info *pi)
-{
-       pr_debug("mpsc_sdma_intr_ack[%d]: Acknowledging IRQ\n", pi->port.line);
-
-       if (pi->mirror_regs)
-               pi->shared_regs->SDMA_INTR_CAUSE_m = 0;
-       writeb(0x00, pi->shared_regs->sdma_intr_base + SDMA_INTR_CAUSE
-                       + pi->port.line);
-}
-
-static void mpsc_sdma_set_rx_ring(struct mpsc_port_info *pi,
-               struct mpsc_rx_desc *rxre_p)
-{
-       pr_debug("mpsc_sdma_set_rx_ring[%d]: rxre_p: 0x%x\n",
-               pi->port.line, (u32)rxre_p);
-
-       writel((u32)rxre_p, pi->sdma_base + SDMA_SCRDP);
-}
-
-static void mpsc_sdma_set_tx_ring(struct mpsc_port_info *pi,
-               struct mpsc_tx_desc *txre_p)
-{
-       writel((u32)txre_p, pi->sdma_base + SDMA_SFTDP);
-       writel((u32)txre_p, pi->sdma_base + SDMA_SCTDP);
-}
-
-static void mpsc_sdma_cmd(struct mpsc_port_info *pi, u32 val)
-{
-       u32     v;
-
-       v = readl(pi->sdma_base + SDMA_SDCM);
-       if (val)
-               v |= val;
-       else
-               v = 0;
-       wmb();
-       writel(v, pi->sdma_base + SDMA_SDCM);
-       wmb();
-}
-
-static uint mpsc_sdma_tx_active(struct mpsc_port_info *pi)
-{
-       return readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_TXD;
-}
-
-static void mpsc_sdma_start_tx(struct mpsc_port_info *pi)
-{
-       struct mpsc_tx_desc *txre, *txre_p;
-
-       /* If tx isn't running & there's a desc ready to go, start it */
-       if (!mpsc_sdma_tx_active(pi)) {
-               txre = (struct mpsc_tx_desc *)(pi->txr
-                               + (pi->txr_tail * MPSC_TXRE_SIZE));
-               dma_cache_sync(pi->port.dev, (void *)txre, MPSC_TXRE_SIZE,
-                               DMA_FROM_DEVICE);
-#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
-               if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
-                       invalidate_dcache_range((ulong)txre,
-                                       (ulong)txre + MPSC_TXRE_SIZE);
-#endif
-
-               if (be32_to_cpu(txre->cmdstat) & SDMA_DESC_CMDSTAT_O) {
-                       txre_p = (struct mpsc_tx_desc *)
-                               (pi->txr_p + (pi->txr_tail * MPSC_TXRE_SIZE));
-
-                       mpsc_sdma_set_tx_ring(pi, txre_p);
-                       mpsc_sdma_cmd(pi, SDMA_SDCM_STD | SDMA_SDCM_TXD);
-               }
-       }
-}
-
-static void mpsc_sdma_stop(struct mpsc_port_info *pi)
-{
-       pr_debug("mpsc_sdma_stop[%d]: Stopping SDMA\n", pi->port.line);
-
-       /* Abort any SDMA transfers */
-       mpsc_sdma_cmd(pi, 0);
-       mpsc_sdma_cmd(pi, SDMA_SDCM_AR | SDMA_SDCM_AT);
-
-       /* Clear the SDMA current and first TX and RX pointers */
-       mpsc_sdma_set_tx_ring(pi, NULL);
-       mpsc_sdma_set_rx_ring(pi, NULL);
-
-       /* Disable interrupts */
-       mpsc_sdma_intr_mask(pi, 0xf);
-       mpsc_sdma_intr_ack(pi);
-}
-
-/*
- ******************************************************************************
- *
- * Multi-Protocol Serial Controller Routines (MPSC)
- *
- ******************************************************************************
- */
-
-static void mpsc_hw_init(struct mpsc_port_info *pi)
-{
-       u32     v;
-
-       pr_debug("mpsc_hw_init[%d]: Initializing hardware\n", pi->port.line);
-
-       /* Set up clock routing */
-       if (pi->mirror_regs) {
-               v = pi->shared_regs->MPSC_MRR_m;
-               v &= ~0x1c7;
-               pi->shared_regs->MPSC_MRR_m = v;
-               writel(v, pi->shared_regs->mpsc_routing_base + MPSC_MRR);
-
-               v = pi->shared_regs->MPSC_RCRR_m;
-               v = (v & ~0xf0f) | 0x100;
-               pi->shared_regs->MPSC_RCRR_m = v;
-               writel(v, pi->shared_regs->mpsc_routing_base + MPSC_RCRR);
-
-               v = pi->shared_regs->MPSC_TCRR_m;
-               v = (v & ~0xf0f) | 0x100;
-               pi->shared_regs->MPSC_TCRR_m = v;
-               writel(v, pi->shared_regs->mpsc_routing_base + MPSC_TCRR);
-       } else {
-               v = readl(pi->shared_regs->mpsc_routing_base + MPSC_MRR);
-               v &= ~0x1c7;
-               writel(v, pi->shared_regs->mpsc_routing_base + MPSC_MRR);
-
-               v = readl(pi->shared_regs->mpsc_routing_base + MPSC_RCRR);
-               v = (v & ~0xf0f) | 0x100;
-               writel(v, pi->shared_regs->mpsc_routing_base + MPSC_RCRR);
-
-               v = readl(pi->shared_regs->mpsc_routing_base + MPSC_TCRR);
-               v = (v & ~0xf0f) | 0x100;
-               writel(v, pi->shared_regs->mpsc_routing_base + MPSC_TCRR);
-       }
-
-       /* Put MPSC in UART mode & enabel Tx/Rx egines */
-       writel(0x000004c4, pi->mpsc_base + MPSC_MMCRL);
-
-       /* No preamble, 16x divider, low-latency, */
-       writel(0x04400400, pi->mpsc_base + MPSC_MMCRH);
-       mpsc_set_baudrate(pi, pi->default_baud);
-
-       if (pi->mirror_regs) {
-               pi->MPSC_CHR_1_m = 0;
-               pi->MPSC_CHR_2_m = 0;
-       }
-       writel(0, pi->mpsc_base + MPSC_CHR_1);
-       writel(0, pi->mpsc_base + MPSC_CHR_2);
-       writel(pi->mpsc_max_idle, pi->mpsc_base + MPSC_CHR_3);
-       writel(0, pi->mpsc_base + MPSC_CHR_4);
-       writel(0, pi->mpsc_base + MPSC_CHR_5);
-       writel(0, pi->mpsc_base + MPSC_CHR_6);
-       writel(0, pi->mpsc_base + MPSC_CHR_7);
-       writel(0, pi->mpsc_base + MPSC_CHR_8);
-       writel(0, pi->mpsc_base + MPSC_CHR_9);
-       writel(0, pi->mpsc_base + MPSC_CHR_10);
-}
-
-static void mpsc_enter_hunt(struct mpsc_port_info *pi)
-{
-       pr_debug("mpsc_enter_hunt[%d]: Hunting...\n", pi->port.line);
-
-       if (pi->mirror_regs) {
-               writel(pi->MPSC_CHR_2_m | MPSC_CHR_2_EH,
-                       pi->mpsc_base + MPSC_CHR_2);
-               /* Erratum prevents reading CHR_2 so just delay for a while */
-               udelay(100);
-       } else {
-               writel(readl(pi->mpsc_base + MPSC_CHR_2) | MPSC_CHR_2_EH,
-                               pi->mpsc_base + MPSC_CHR_2);
-
-               while (readl(pi->mpsc_base + MPSC_CHR_2) & MPSC_CHR_2_EH)
-                       udelay(10);
-       }
-}
-
-static void mpsc_freeze(struct mpsc_port_info *pi)
-{
-       u32     v;
-
-       pr_debug("mpsc_freeze[%d]: Freezing\n", pi->port.line);
-
-       v = (pi->mirror_regs) ? pi->MPSC_MPCR_m :
-               readl(pi->mpsc_base + MPSC_MPCR);
-       v |= MPSC_MPCR_FRZ;
-
-       if (pi->mirror_regs)
-               pi->MPSC_MPCR_m = v;
-       writel(v, pi->mpsc_base + MPSC_MPCR);
-}
-
-static void mpsc_unfreeze(struct mpsc_port_info *pi)
-{
-       u32     v;
-
-       v = (pi->mirror_regs) ? pi->MPSC_MPCR_m :
-               readl(pi->mpsc_base + MPSC_MPCR);
-       v &= ~MPSC_MPCR_FRZ;
-
-       if (pi->mirror_regs)
-               pi->MPSC_MPCR_m = v;
-       writel(v, pi->mpsc_base + MPSC_MPCR);
-
-       pr_debug("mpsc_unfreeze[%d]: Unfrozen\n", pi->port.line);
-}
-
-static void mpsc_set_char_length(struct mpsc_port_info *pi, u32 len)
-{
-       u32     v;
-
-       pr_debug("mpsc_set_char_length[%d]: char len: %d\n", pi->port.line,len);
-
-       v = (pi->mirror_regs) ? pi->MPSC_MPCR_m :
-               readl(pi->mpsc_base + MPSC_MPCR);
-       v = (v & ~(0x3 << 12)) | ((len & 0x3) << 12);
-
-       if (pi->mirror_regs)
-               pi->MPSC_MPCR_m = v;
-       writel(v, pi->mpsc_base + MPSC_MPCR);
-}
-
-static void mpsc_set_stop_bit_length(struct mpsc_port_info *pi, u32 len)
-{
-       u32     v;
-
-       pr_debug("mpsc_set_stop_bit_length[%d]: stop bits: %d\n",
-               pi->port.line, len);
-
-       v = (pi->mirror_regs) ? pi->MPSC_MPCR_m :
-               readl(pi->mpsc_base + MPSC_MPCR);
-
-       v = (v & ~(1 << 14)) | ((len & 0x1) << 14);
-
-       if (pi->mirror_regs)
-               pi->MPSC_MPCR_m = v;
-       writel(v, pi->mpsc_base + MPSC_MPCR);
-}
-
-static void mpsc_set_parity(struct mpsc_port_info *pi, u32 p)
-{
-       u32     v;
-
-       pr_debug("mpsc_set_parity[%d]: parity bits: 0x%x\n", pi->port.line, p);
-
-       v = (pi->mirror_regs) ? pi->MPSC_CHR_2_m :
-               readl(pi->mpsc_base + MPSC_CHR_2);
-
-       p &= 0x3;
-       v = (v & ~0xc000c) | (p << 18) | (p << 2);
-
-       if (pi->mirror_regs)
-               pi->MPSC_CHR_2_m = v;
-       writel(v, pi->mpsc_base + MPSC_CHR_2);
-}
-
-/*
- ******************************************************************************
- *
- * Driver Init Routines
- *
- ******************************************************************************
- */
-
-static void mpsc_init_hw(struct mpsc_port_info *pi)
-{
-       pr_debug("mpsc_init_hw[%d]: Initializing\n", pi->port.line);
-
-       mpsc_brg_init(pi, pi->brg_clk_src);
-       mpsc_brg_enable(pi);
-       mpsc_sdma_init(pi, dma_get_cache_alignment());  /* burst a cacheline */
-       mpsc_sdma_stop(pi);
-       mpsc_hw_init(pi);
-}
-
-static int mpsc_alloc_ring_mem(struct mpsc_port_info *pi)
-{
-       int rc = 0;
-
-       pr_debug("mpsc_alloc_ring_mem[%d]: Allocating ring mem\n",
-               pi->port.line);
-
-       if (!pi->dma_region) {
-               if (!dma_set_mask(pi->port.dev, 0xffffffff)) {
-                       printk(KERN_ERR "MPSC: Inadequate DMA support\n");
-                       rc = -ENXIO;
-               } else if ((pi->dma_region = dma_alloc_attrs(pi->port.dev,
-                                               MPSC_DMA_ALLOC_SIZE,
-                                               &pi->dma_region_p, GFP_KERNEL,
-                                               DMA_ATTR_NON_CONSISTENT))
-                               == NULL) {
-                       printk(KERN_ERR "MPSC: Can't alloc Desc region\n");
-                       rc = -ENOMEM;
-               }
-       }
-
-       return rc;
-}
-
-static void mpsc_free_ring_mem(struct mpsc_port_info *pi)
-{
-       pr_debug("mpsc_free_ring_mem[%d]: Freeing ring mem\n", pi->port.line);
-
-       if (pi->dma_region) {
-               dma_free_attrs(pi->port.dev, MPSC_DMA_ALLOC_SIZE,
-                               pi->dma_region, pi->dma_region_p,
-                               DMA_ATTR_NON_CONSISTENT);
-               pi->dma_region = NULL;
-               pi->dma_region_p = (dma_addr_t)NULL;
-       }
-}
-
-static void mpsc_init_rings(struct mpsc_port_info *pi)
-{
-       struct mpsc_rx_desc *rxre;
-       struct mpsc_tx_desc *txre;
-       dma_addr_t dp, dp_p;
-       u8 *bp, *bp_p;
-       int i;
-
-       pr_debug("mpsc_init_rings[%d]: Initializing rings\n", pi->port.line);
-
-       BUG_ON(pi->dma_region == NULL);
-
-       memset(pi->dma_region, 0, MPSC_DMA_ALLOC_SIZE);
-
-       /*
-        * Descriptors & buffers are multiples of cacheline size and must be
-        * cacheline aligned.
-        */
-       dp = ALIGN((u32)pi->dma_region, dma_get_cache_alignment());
-       dp_p = ALIGN((u32)pi->dma_region_p, dma_get_cache_alignment());
-
-       /*
-        * Partition dma region into rx ring descriptor, rx buffers,
-        * tx ring descriptors, and tx buffers.
-        */
-       pi->rxr = dp;
-       pi->rxr_p = dp_p;
-       dp += MPSC_RXR_SIZE;
-       dp_p += MPSC_RXR_SIZE;
-
-       pi->rxb = (u8 *)dp;
-       pi->rxb_p = (u8 *)dp_p;
-       dp += MPSC_RXB_SIZE;
-       dp_p += MPSC_RXB_SIZE;
-
-       pi->rxr_posn = 0;
-
-       pi->txr = dp;
-       pi->txr_p = dp_p;
-       dp += MPSC_TXR_SIZE;
-       dp_p += MPSC_TXR_SIZE;
-
-       pi->txb = (u8 *)dp;
-       pi->txb_p = (u8 *)dp_p;
-
-       pi->txr_head = 0;
-       pi->txr_tail = 0;
-
-       /* Init rx ring descriptors */
-       dp = pi->rxr;
-       dp_p = pi->rxr_p;
-       bp = pi->rxb;
-       bp_p = pi->rxb_p;
-
-       for (i = 0; i < MPSC_RXR_ENTRIES; i++) {
-               rxre = (struct mpsc_rx_desc *)dp;
-
-               rxre->bufsize = cpu_to_be16(MPSC_RXBE_SIZE);
-               rxre->bytecnt = cpu_to_be16(0);
-               rxre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O
-                               | SDMA_DESC_CMDSTAT_EI | SDMA_DESC_CMDSTAT_F
-                               | SDMA_DESC_CMDSTAT_L);
-               rxre->link = cpu_to_be32(dp_p + MPSC_RXRE_SIZE);
-               rxre->buf_ptr = cpu_to_be32(bp_p);
-
-               dp += MPSC_RXRE_SIZE;
-               dp_p += MPSC_RXRE_SIZE;
-               bp += MPSC_RXBE_SIZE;
-               bp_p += MPSC_RXBE_SIZE;
-       }
-       rxre->link = cpu_to_be32(pi->rxr_p);    /* Wrap last back to first */
-
-       /* Init tx ring descriptors */
-       dp = pi->txr;
-       dp_p = pi->txr_p;
-       bp = pi->txb;
-       bp_p = pi->txb_p;
-
-       for (i = 0; i < MPSC_TXR_ENTRIES; i++) {
-               txre = (struct mpsc_tx_desc *)dp;
-
-               txre->link = cpu_to_be32(dp_p + MPSC_TXRE_SIZE);
-               txre->buf_ptr = cpu_to_be32(bp_p);
-
-               dp += MPSC_TXRE_SIZE;
-               dp_p += MPSC_TXRE_SIZE;
-               bp += MPSC_TXBE_SIZE;
-               bp_p += MPSC_TXBE_SIZE;
-       }
-       txre->link = cpu_to_be32(pi->txr_p);    /* Wrap last back to first */
-
-       dma_cache_sync(pi->port.dev, (void *)pi->dma_region,
-                       MPSC_DMA_ALLOC_SIZE, DMA_BIDIRECTIONAL);
-#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
-               if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
-                       flush_dcache_range((ulong)pi->dma_region,
-                                       (ulong)pi->dma_region
-                                       + MPSC_DMA_ALLOC_SIZE);
-#endif
-
-       return;
-}
-
-static void mpsc_uninit_rings(struct mpsc_port_info *pi)
-{
-       pr_debug("mpsc_uninit_rings[%d]: Uninitializing rings\n",pi->port.line);
-
-       BUG_ON(pi->dma_region == NULL);
-
-       pi->rxr = 0;
-       pi->rxr_p = 0;
-       pi->rxb = NULL;
-       pi->rxb_p = NULL;
-       pi->rxr_posn = 0;
-
-       pi->txr = 0;
-       pi->txr_p = 0;
-       pi->txb = NULL;
-       pi->txb_p = NULL;
-       pi->txr_head = 0;
-       pi->txr_tail = 0;
-}
-
-static int mpsc_make_ready(struct mpsc_port_info *pi)
-{
-       int rc;
-
-       pr_debug("mpsc_make_ready[%d]: Making cltr ready\n", pi->port.line);
-
-       if (!pi->ready) {
-               mpsc_init_hw(pi);
-               rc = mpsc_alloc_ring_mem(pi);
-               if (rc)
-                       return rc;
-               mpsc_init_rings(pi);
-               pi->ready = 1;
-       }
-
-       return 0;
-}
-
-#ifdef CONFIG_CONSOLE_POLL
-static int serial_polled;
-#endif
-
-/*
- ******************************************************************************
- *
- * Interrupt Handling Routines
- *
- ******************************************************************************
- */
-
-static int mpsc_rx_intr(struct mpsc_port_info *pi, unsigned long *flags)
-{
-       struct mpsc_rx_desc *rxre;
-       struct tty_port *port = &pi->port.state->port;
-       u32     cmdstat, bytes_in, i;
-       int     rc = 0;
-       u8      *bp;
-       char    flag = TTY_NORMAL;
-
-       pr_debug("mpsc_rx_intr[%d]: Handling Rx intr\n", pi->port.line);
-
-       rxre = (struct mpsc_rx_desc *)(pi->rxr + (pi->rxr_posn*MPSC_RXRE_SIZE));
-
-       dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE,
-                       DMA_FROM_DEVICE);
-#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
-       if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
-               invalidate_dcache_range((ulong)rxre,
-                               (ulong)rxre + MPSC_RXRE_SIZE);
-#endif
-
-       /*
-        * Loop through Rx descriptors handling ones that have been completed.
-        */
-       while (!((cmdstat = be32_to_cpu(rxre->cmdstat))
-                               & SDMA_DESC_CMDSTAT_O)) {
-               bytes_in = be16_to_cpu(rxre->bytecnt);
-#ifdef CONFIG_CONSOLE_POLL
-               if (unlikely(serial_polled)) {
-                       serial_polled = 0;
-                       return 0;
-               }
-#endif
-               /* Following use of tty struct directly is deprecated */
-               if (tty_buffer_request_room(port, bytes_in) < bytes_in) {
-                       if (port->low_latency) {
-                               spin_unlock_irqrestore(&pi->port.lock, *flags);
-                               tty_flip_buffer_push(port);
-                               spin_lock_irqsave(&pi->port.lock, *flags);
-                       }
-                       /*
-                        * If this failed then we will throw away the bytes
-                        * but must do so to clear interrupts.
-                        */
-               }
-
-               bp = pi->rxb + (pi->rxr_posn * MPSC_RXBE_SIZE);
-               dma_cache_sync(pi->port.dev, (void *)bp, MPSC_RXBE_SIZE,
-                               DMA_FROM_DEVICE);
-#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
-               if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
-                       invalidate_dcache_range((ulong)bp,
-                                       (ulong)bp + MPSC_RXBE_SIZE);
-#endif
-
-               /*
-                * Other than for parity error, the manual provides little
-                * info on what data will be in a frame flagged by any of
-                * these errors.  For parity error, it is the last byte in
-                * the buffer that had the error.  As for the rest, I guess
-                * we'll assume there is no data in the buffer.
-                * If there is...it gets lost.
-                */
-               if (unlikely(cmdstat & (SDMA_DESC_CMDSTAT_BR
-                                               | SDMA_DESC_CMDSTAT_FR
-                                               | SDMA_DESC_CMDSTAT_OR))) {
-
-                       pi->port.icount.rx++;
-
-                       if (cmdstat & SDMA_DESC_CMDSTAT_BR) {   /* Break */
-                               pi->port.icount.brk++;
-
-                               if (uart_handle_break(&pi->port))
-                                       goto next_frame;
-                       } else if (cmdstat & SDMA_DESC_CMDSTAT_FR) {
-                               pi->port.icount.frame++;
-                       } else if (cmdstat & SDMA_DESC_CMDSTAT_OR) {
-                               pi->port.icount.overrun++;
-                       }
-
-                       cmdstat &= pi->port.read_status_mask;
-
-                       if (cmdstat & SDMA_DESC_CMDSTAT_BR)
-                               flag = TTY_BREAK;
-                       else if (cmdstat & SDMA_DESC_CMDSTAT_FR)
-                               flag = TTY_FRAME;
-                       else if (cmdstat & SDMA_DESC_CMDSTAT_OR)
-                               flag = TTY_OVERRUN;
-                       else if (cmdstat & SDMA_DESC_CMDSTAT_PE)
-                               flag = TTY_PARITY;
-               }
-
-               if (uart_handle_sysrq_char(&pi->port, *bp)) {
-                       bp++;
-                       bytes_in--;
-#ifdef CONFIG_CONSOLE_POLL
-                       if (unlikely(serial_polled)) {
-                               serial_polled = 0;
-                               return 0;
-                       }
-#endif
-                       goto next_frame;
-               }
-
-               if ((unlikely(cmdstat & (SDMA_DESC_CMDSTAT_BR
-                                               | SDMA_DESC_CMDSTAT_FR
-                                               | SDMA_DESC_CMDSTAT_OR)))
-                               && !(cmdstat & pi->port.ignore_status_mask)) {
-                       tty_insert_flip_char(port, *bp, flag);
-               } else {
-                       for (i=0; i<bytes_in; i++)
-                               tty_insert_flip_char(port, *bp++, TTY_NORMAL);
-
-                       pi->port.icount.rx += bytes_in;
-               }
-
-next_frame:
-               rxre->bytecnt = cpu_to_be16(0);
-               wmb();
-               rxre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O
-                               | SDMA_DESC_CMDSTAT_EI | SDMA_DESC_CMDSTAT_F
-                               | SDMA_DESC_CMDSTAT_L);
-               wmb();
-               dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE,
-                               DMA_BIDIRECTIONAL);
-#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
-               if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
-                       flush_dcache_range((ulong)rxre,
-                                       (ulong)rxre + MPSC_RXRE_SIZE);
-#endif
-
-               /* Advance to next descriptor */
-               pi->rxr_posn = (pi->rxr_posn + 1) & (MPSC_RXR_ENTRIES - 1);
-               rxre = (struct mpsc_rx_desc *)
-                       (pi->rxr + (pi->rxr_posn * MPSC_RXRE_SIZE));
-               dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE,
-                               DMA_FROM_DEVICE);
-#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
-               if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
-                       invalidate_dcache_range((ulong)rxre,
-                                       (ulong)rxre + MPSC_RXRE_SIZE);
-#endif
-               rc = 1;
-       }
-
-       /* Restart rx engine, if its stopped */
-       if ((readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_ERD) == 0)
-               mpsc_start_rx(pi);
-
-       spin_unlock_irqrestore(&pi->port.lock, *flags);
-       tty_flip_buffer_push(port);
-       spin_lock_irqsave(&pi->port.lock, *flags);
-       return rc;
-}
-
-static void mpsc_setup_tx_desc(struct mpsc_port_info *pi, u32 count, u32 intr)
-{
-       struct mpsc_tx_desc *txre;
-
-       txre = (struct mpsc_tx_desc *)(pi->txr
-                       + (pi->txr_head * MPSC_TXRE_SIZE));
-
-       txre->bytecnt = cpu_to_be16(count);
-       txre->shadow = txre->bytecnt;
-       wmb();                  /* ensure cmdstat is last field updated */
-       txre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O | SDMA_DESC_CMDSTAT_F
-                       | SDMA_DESC_CMDSTAT_L
-                       | ((intr) ? SDMA_DESC_CMDSTAT_EI : 0));
-       wmb();
-       dma_cache_sync(pi->port.dev, (void *)txre, MPSC_TXRE_SIZE,
-                       DMA_BIDIRECTIONAL);
-#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
-       if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
-               flush_dcache_range((ulong)txre,
-                               (ulong)txre + MPSC_TXRE_SIZE);
-#endif
-}
-
-static void mpsc_copy_tx_data(struct mpsc_port_info *pi)
-{
-       struct circ_buf *xmit = &pi->port.state->xmit;
-       u8 *bp;
-       u32 i;
-
-       /* Make sure the desc ring isn't full */
-       while (CIRC_CNT(pi->txr_head, pi->txr_tail, MPSC_TXR_ENTRIES)
-                       < (MPSC_TXR_ENTRIES - 1)) {
-               if (pi->port.x_char) {
-                       /*
-                        * Ideally, we should use the TCS field in
-                        * CHR_1 to put the x_char out immediately but
-                        * errata prevents us from being able to read
-                        * CHR_2 to know that its safe to write to
-                        * CHR_1.  Instead, just put it in-band with
-                        * all the other Tx data.
-                        */
-                       bp = pi->txb + (pi->txr_head * MPSC_TXBE_SIZE);
-                       *bp = pi->port.x_char;
-                       pi->port.x_char = 0;
-                       i = 1;
-               } else if (!uart_circ_empty(xmit)
-                               && !uart_tx_stopped(&pi->port)) {
-                       i = min((u32)MPSC_TXBE_SIZE,
-                               (u32)uart_circ_chars_pending(xmit));
-                       i = min(i, (u32)CIRC_CNT_TO_END(xmit->head, xmit->tail,
-                               UART_XMIT_SIZE));
-                       bp = pi->txb + (pi->txr_head * MPSC_TXBE_SIZE);
-                       memcpy(bp, &xmit->buf[xmit->tail], i);
-                       xmit->tail = (xmit->tail + i) & (UART_XMIT_SIZE - 1);
-
-                       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-                               uart_write_wakeup(&pi->port);
-               } else { /* All tx data copied into ring bufs */
-                       return;
-               }
-
-               dma_cache_sync(pi->port.dev, (void *)bp, MPSC_TXBE_SIZE,
-                               DMA_BIDIRECTIONAL);
-#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
-               if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
-                       flush_dcache_range((ulong)bp,
-                                       (ulong)bp + MPSC_TXBE_SIZE);
-#endif
-               mpsc_setup_tx_desc(pi, i, 1);
-
-               /* Advance to next descriptor */
-               pi->txr_head = (pi->txr_head + 1) & (MPSC_TXR_ENTRIES - 1);
-       }
-}
-
-static int mpsc_tx_intr(struct mpsc_port_info *pi)
-{
-       struct mpsc_tx_desc *txre;
-       int rc = 0;
-       unsigned long iflags;
-
-       spin_lock_irqsave(&pi->tx_lock, iflags);
-
-       if (!mpsc_sdma_tx_active(pi)) {
-               txre = (struct mpsc_tx_desc *)(pi->txr
-                               + (pi->txr_tail * MPSC_TXRE_SIZE));
-
-               dma_cache_sync(pi->port.dev, (void *)txre, MPSC_TXRE_SIZE,
-                               DMA_FROM_DEVICE);
-#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
-               if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
-                       invalidate_dcache_range((ulong)txre,
-                                       (ulong)txre + MPSC_TXRE_SIZE);
-#endif
-
-               while (!(be32_to_cpu(txre->cmdstat) & SDMA_DESC_CMDSTAT_O)) {
-                       rc = 1;
-                       pi->port.icount.tx += be16_to_cpu(txre->bytecnt);
-                       pi->txr_tail = (pi->txr_tail+1) & (MPSC_TXR_ENTRIES-1);
-
-                       /* If no more data to tx, fall out of loop */
-                       if (pi->txr_head == pi->txr_tail)
-                               break;
-
-                       txre = (struct mpsc_tx_desc *)(pi->txr
-                                       + (pi->txr_tail * MPSC_TXRE_SIZE));
-                       dma_cache_sync(pi->port.dev, (void *)txre,
-                                       MPSC_TXRE_SIZE, DMA_FROM_DEVICE);
-#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
-                       if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
-                               invalidate_dcache_range((ulong)txre,
-                                               (ulong)txre + MPSC_TXRE_SIZE);
-#endif
-               }
-
-               mpsc_copy_tx_data(pi);
-               mpsc_sdma_start_tx(pi); /* start next desc if ready */
-       }
-
-       spin_unlock_irqrestore(&pi->tx_lock, iflags);
-       return rc;
-}
-
-/*
- * This is the driver's interrupt handler.  To avoid a race, we first clear
- * the interrupt, then handle any completed Rx/Tx descriptors.  When done
- * handling those descriptors, we restart the Rx/Tx engines if they're stopped.
- */
-static irqreturn_t mpsc_sdma_intr(int irq, void *dev_id)
-{
-       struct mpsc_port_info *pi = dev_id;
-       ulong iflags;
-       int rc = IRQ_NONE;
-
-       pr_debug("mpsc_sdma_intr[%d]: SDMA Interrupt Received\n",pi->port.line);
-
-       spin_lock_irqsave(&pi->port.lock, iflags);
-       mpsc_sdma_intr_ack(pi);
-       if (mpsc_rx_intr(pi, &iflags))
-               rc = IRQ_HANDLED;
-       if (mpsc_tx_intr(pi))
-               rc = IRQ_HANDLED;
-       spin_unlock_irqrestore(&pi->port.lock, iflags);
-
-       pr_debug("mpsc_sdma_intr[%d]: SDMA Interrupt Handled\n", pi->port.line);
-       return rc;
-}
-
-/*
- ******************************************************************************
- *
- * serial_core.c Interface routines
- *
- ******************************************************************************
- */
-static uint mpsc_tx_empty(struct uart_port *port)
-{
-       struct mpsc_port_info *pi =
-               container_of(port, struct mpsc_port_info, port);
-       ulong iflags;
-       uint rc;
-
-       spin_lock_irqsave(&pi->port.lock, iflags);
-       rc = mpsc_sdma_tx_active(pi) ? 0 : TIOCSER_TEMT;
-       spin_unlock_irqrestore(&pi->port.lock, iflags);
-
-       return rc;
-}
-
-static void mpsc_set_mctrl(struct uart_port *port, uint mctrl)
-{
-       /* Have no way to set modem control lines AFAICT */
-}
-
-static uint mpsc_get_mctrl(struct uart_port *port)
-{
-       struct mpsc_port_info *pi =
-               container_of(port, struct mpsc_port_info, port);
-       u32 mflags, status;
-
-       status = (pi->mirror_regs) ? pi->MPSC_CHR_10_m
-               : readl(pi->mpsc_base + MPSC_CHR_10);
-
-       mflags = 0;
-       if (status & 0x1)
-               mflags |= TIOCM_CTS;
-       if (status & 0x2)
-               mflags |= TIOCM_CAR;
-
-       return mflags | TIOCM_DSR;      /* No way to tell if DSR asserted */
-}
-
-static void mpsc_stop_tx(struct uart_port *port)
-{
-       struct mpsc_port_info *pi =
-               container_of(port, struct mpsc_port_info, port);
-
-       pr_debug("mpsc_stop_tx[%d]\n", port->line);
-
-       mpsc_freeze(pi);
-}
-
-static void mpsc_start_tx(struct uart_port *port)
-{
-       struct mpsc_port_info *pi =
-               container_of(port, struct mpsc_port_info, port);
-       unsigned long iflags;
-
-       spin_lock_irqsave(&pi->tx_lock, iflags);
-
-       mpsc_unfreeze(pi);
-       mpsc_copy_tx_data(pi);
-       mpsc_sdma_start_tx(pi);
-
-       spin_unlock_irqrestore(&pi->tx_lock, iflags);
-
-       pr_debug("mpsc_start_tx[%d]\n", port->line);
-}
-
-static void mpsc_start_rx(struct mpsc_port_info *pi)
-{
-       pr_debug("mpsc_start_rx[%d]: Starting...\n", pi->port.line);
-
-       if (pi->rcv_data) {
-               mpsc_enter_hunt(pi);
-               mpsc_sdma_cmd(pi, SDMA_SDCM_ERD);
-       }
-}
-
-static void mpsc_stop_rx(struct uart_port *port)
-{
-       struct mpsc_port_info *pi =
-               container_of(port, struct mpsc_port_info, port);
-
-       pr_debug("mpsc_stop_rx[%d]: Stopping...\n", port->line);
-
-       if (pi->mirror_regs) {
-               writel(pi->MPSC_CHR_2_m | MPSC_CHR_2_RA,
-                               pi->mpsc_base + MPSC_CHR_2);
-               /* Erratum prevents reading CHR_2 so just delay for a while */
-               udelay(100);
-       } else {
-               writel(readl(pi->mpsc_base + MPSC_CHR_2) | MPSC_CHR_2_RA,
-                               pi->mpsc_base + MPSC_CHR_2);
-
-               while (readl(pi->mpsc_base + MPSC_CHR_2) & MPSC_CHR_2_RA)
-                       udelay(10);
-       }
-
-       mpsc_sdma_cmd(pi, SDMA_SDCM_AR);
-}
-
-static void mpsc_break_ctl(struct uart_port *port, int ctl)
-{
-       struct mpsc_port_info *pi =
-               container_of(port, struct mpsc_port_info, port);
-       ulong   flags;
-       u32     v;
-
-       v = ctl ? 0x00ff0000 : 0;
-
-       spin_lock_irqsave(&pi->port.lock, flags);
-       if (pi->mirror_regs)
-               pi->MPSC_CHR_1_m = v;
-       writel(v, pi->mpsc_base + MPSC_CHR_1);
-       spin_unlock_irqrestore(&pi->port.lock, flags);
-}
-
-static int mpsc_startup(struct uart_port *port)
-{
-       struct mpsc_port_info *pi =
-               container_of(port, struct mpsc_port_info, port);
-       u32 flag = 0;
-       int rc;
-
-       pr_debug("mpsc_startup[%d]: Starting up MPSC, irq: %d\n",
-               port->line, pi->port.irq);
-
-       if ((rc = mpsc_make_ready(pi)) == 0) {
-               /* Setup IRQ handler */
-               mpsc_sdma_intr_ack(pi);
-
-               /* If irq's are shared, need to set flag */
-               if (mpsc_ports[0].port.irq == mpsc_ports[1].port.irq)
-                       flag = IRQF_SHARED;
-
-               if (request_irq(pi->port.irq, mpsc_sdma_intr, flag,
-                                       "mpsc-sdma", pi))
-                       printk(KERN_ERR "MPSC: Can't get SDMA IRQ %d\n",
-                                       pi->port.irq);
-
-               mpsc_sdma_intr_unmask(pi, 0xf);
-               mpsc_sdma_set_rx_ring(pi, (struct mpsc_rx_desc *)(pi->rxr_p
-                                       + (pi->rxr_posn * MPSC_RXRE_SIZE)));
-       }
-
-       return rc;
-}
-
-static void mpsc_shutdown(struct uart_port *port)
-{
-       struct mpsc_port_info *pi =
-               container_of(port, struct mpsc_port_info, port);
-
-       pr_debug("mpsc_shutdown[%d]: Shutting down MPSC\n", port->line);
-
-       mpsc_sdma_stop(pi);
-       free_irq(pi->port.irq, pi);
-}
-
-static void mpsc_set_termios(struct uart_port *port, struct ktermios *termios,
-                struct ktermios *old)
-{
-       struct mpsc_port_info *pi =
-               container_of(port, struct mpsc_port_info, port);
-       u32 baud;
-       ulong flags;
-       u32 chr_bits, stop_bits, par;
-
-       switch (termios->c_cflag & CSIZE) {
-       case CS5:
-               chr_bits = MPSC_MPCR_CL_5;
-               break;
-       case CS6:
-               chr_bits = MPSC_MPCR_CL_6;
-               break;
-       case CS7:
-               chr_bits = MPSC_MPCR_CL_7;
-               break;
-       case CS8:
-       default:
-               chr_bits = MPSC_MPCR_CL_8;
-               break;
-       }
-
-       if (termios->c_cflag & CSTOPB)
-               stop_bits = MPSC_MPCR_SBL_2;
-       else
-               stop_bits = MPSC_MPCR_SBL_1;
-
-       par = MPSC_CHR_2_PAR_EVEN;
-       if (termios->c_cflag & PARENB)
-               if (termios->c_cflag & PARODD)
-                       par = MPSC_CHR_2_PAR_ODD;
-#ifdef CMSPAR
-               if (termios->c_cflag & CMSPAR) {
-                       if (termios->c_cflag & PARODD)
-                               par = MPSC_CHR_2_PAR_MARK;
-                       else
-                               par = MPSC_CHR_2_PAR_SPACE;
-               }
-#endif
-
-       baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk);
-
-       spin_lock_irqsave(&pi->port.lock, flags);
-
-       uart_update_timeout(port, termios->c_cflag, baud);
-
-       mpsc_set_char_length(pi, chr_bits);
-       mpsc_set_stop_bit_length(pi, stop_bits);
-       mpsc_set_parity(pi, par);
-       mpsc_set_baudrate(pi, baud);
-
-       /* Characters/events to read */
-       pi->port.read_status_mask = SDMA_DESC_CMDSTAT_OR;
-
-       if (termios->c_iflag & INPCK)
-               pi->port.read_status_mask |= SDMA_DESC_CMDSTAT_PE
-                       | SDMA_DESC_CMDSTAT_FR;
-
-       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
-               pi->port.read_status_mask |= SDMA_DESC_CMDSTAT_BR;
-
-       /* Characters/events to ignore */
-       pi->port.ignore_status_mask = 0;
-
-       if (termios->c_iflag & IGNPAR)
-               pi->port.ignore_status_mask |= SDMA_DESC_CMDSTAT_PE
-                       | SDMA_DESC_CMDSTAT_FR;
-
-       if (termios->c_iflag & IGNBRK) {
-               pi->port.ignore_status_mask |= SDMA_DESC_CMDSTAT_BR;
-
-               if (termios->c_iflag & IGNPAR)
-                       pi->port.ignore_status_mask |= SDMA_DESC_CMDSTAT_OR;
-       }
-
-       if ((termios->c_cflag & CREAD)) {
-               if (!pi->rcv_data) {
-                       pi->rcv_data = 1;
-                       mpsc_start_rx(pi);
-               }
-       } else if (pi->rcv_data) {
-               mpsc_stop_rx(port);
-               pi->rcv_data = 0;
-       }
-
-       spin_unlock_irqrestore(&pi->port.lock, flags);
-}
-
-static const char *mpsc_type(struct uart_port *port)
-{
-       pr_debug("mpsc_type[%d]: port type: %s\n", port->line,MPSC_DRIVER_NAME);
-       return MPSC_DRIVER_NAME;
-}
-
-static int mpsc_request_port(struct uart_port *port)
-{
-       /* Should make chip/platform specific call */
-       return 0;
-}
-
-static void mpsc_release_port(struct uart_port *port)
-{
-       struct mpsc_port_info *pi =
-               container_of(port, struct mpsc_port_info, port);
-
-       if (pi->ready) {
-               mpsc_uninit_rings(pi);
-               mpsc_free_ring_mem(pi);
-               pi->ready = 0;
-       }
-}
-
-static void mpsc_config_port(struct uart_port *port, int flags)
-{
-}
-
-static int mpsc_verify_port(struct uart_port *port, struct serial_struct *ser)
-{
-       struct mpsc_port_info *pi =
-               container_of(port, struct mpsc_port_info, port);
-       int rc = 0;
-
-       pr_debug("mpsc_verify_port[%d]: Verifying port data\n", pi->port.line);
-
-       if (ser->type != PORT_UNKNOWN && ser->type != PORT_MPSC)
-               rc = -EINVAL;
-       else if (pi->port.irq != ser->irq)
-               rc = -EINVAL;
-       else if (ser->io_type != SERIAL_IO_MEM)
-               rc = -EINVAL;
-       else if (pi->port.uartclk / 16 != ser->baud_base) /* Not sure */
-               rc = -EINVAL;
-       else if ((void *)pi->port.mapbase != ser->iomem_base)
-               rc = -EINVAL;
-       else if (pi->port.iobase != ser->port)
-               rc = -EINVAL;
-       else if (ser->hub6 != 0)
-               rc = -EINVAL;
-
-       return rc;
-}
-#ifdef CONFIG_CONSOLE_POLL
-/* Serial polling routines for writing and reading from the uart while
- * in an interrupt or debug context.
- */
-
-static char poll_buf[2048];
-static int poll_ptr;
-static int poll_cnt;
-static void mpsc_put_poll_char(struct uart_port *port,
-                                                          unsigned char c);
-
-static int mpsc_get_poll_char(struct uart_port *port)
-{
-       struct mpsc_port_info *pi =
-               container_of(port, struct mpsc_port_info, port);
-       struct mpsc_rx_desc *rxre;
-       u32     cmdstat, bytes_in, i;
-       u8      *bp;
-
-       if (!serial_polled)
-               serial_polled = 1;
-
-       pr_debug("mpsc_rx_intr[%d]: Handling Rx intr\n", pi->port.line);
-
-       if (poll_cnt) {
-               poll_cnt--;
-               return poll_buf[poll_ptr++];
-       }
-       poll_ptr = 0;
-       poll_cnt = 0;
-
-       while (poll_cnt == 0) {
-               rxre = (struct mpsc_rx_desc *)(pi->rxr +
-                      (pi->rxr_posn*MPSC_RXRE_SIZE));
-               dma_cache_sync(pi->port.dev, (void *)rxre,
-                              MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
-#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
-               if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
-                       invalidate_dcache_range((ulong)rxre,
-                       (ulong)rxre + MPSC_RXRE_SIZE);
-#endif
-               /*
-                * Loop through Rx descriptors handling ones that have
-                * been completed.
-                */
-               while (poll_cnt == 0 &&
-                      !((cmdstat = be32_to_cpu(rxre->cmdstat)) &
-                        SDMA_DESC_CMDSTAT_O)){
-                       bytes_in = be16_to_cpu(rxre->bytecnt);
-                       bp = pi->rxb + (pi->rxr_posn * MPSC_RXBE_SIZE);
-                       dma_cache_sync(pi->port.dev, (void *) bp,
-                                      MPSC_RXBE_SIZE, DMA_FROM_DEVICE);
-#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
-                       if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
-                               invalidate_dcache_range((ulong)bp,
-                                       (ulong)bp + MPSC_RXBE_SIZE);
-#endif
-                       if ((unlikely(cmdstat & (SDMA_DESC_CMDSTAT_BR |
-                        SDMA_DESC_CMDSTAT_FR | SDMA_DESC_CMDSTAT_OR))) &&
-                               !(cmdstat & pi->port.ignore_status_mask)) {
-                               poll_buf[poll_cnt] = *bp;
-                               poll_cnt++;
-                       } else {
-                               for (i = 0; i < bytes_in; i++) {
-                                       poll_buf[poll_cnt] = *bp++;
-                                       poll_cnt++;
-                               }
-                               pi->port.icount.rx += bytes_in;
-                       }
-                       rxre->bytecnt = cpu_to_be16(0);
-                       wmb();
-                       rxre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O |
-                                                   SDMA_DESC_CMDSTAT_EI |
-                                                   SDMA_DESC_CMDSTAT_F |
-                                                   SDMA_DESC_CMDSTAT_L);
-                       wmb();
-                       dma_cache_sync(pi->port.dev, (void *)rxre,
-                                      MPSC_RXRE_SIZE, DMA_BIDIRECTIONAL);
-#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
-                       if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
-                               flush_dcache_range((ulong)rxre,
-                                          (ulong)rxre + MPSC_RXRE_SIZE);
-#endif
-
-                       /* Advance to next descriptor */
-                       pi->rxr_posn = (pi->rxr_posn + 1) &
-                               (MPSC_RXR_ENTRIES - 1);
-                       rxre = (struct mpsc_rx_desc *)(pi->rxr +
-                                      (pi->rxr_posn * MPSC_RXRE_SIZE));
-                       dma_cache_sync(pi->port.dev, (void *)rxre,
-                                      MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
-#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
-                       if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
-                               invalidate_dcache_range((ulong)rxre,
-                                               (ulong)rxre + MPSC_RXRE_SIZE);
-#endif
-               }
-
-               /* Restart rx engine, if its stopped */
-               if ((readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_ERD) == 0)
-                       mpsc_start_rx(pi);
-       }
-       if (poll_cnt) {
-               poll_cnt--;
-               return poll_buf[poll_ptr++];
-       }
-
-       return 0;
-}
-
-
-static void mpsc_put_poll_char(struct uart_port *port,
-                        unsigned char c)
-{
-       struct mpsc_port_info *pi =
-               container_of(port, struct mpsc_port_info, port);
-       u32 data;
-
-       data = readl(pi->mpsc_base + MPSC_MPCR);
-       writeb(c, pi->mpsc_base + MPSC_CHR_1);
-       mb();
-       data = readl(pi->mpsc_base + MPSC_CHR_2);
-       data |= MPSC_CHR_2_TTCS;
-       writel(data, pi->mpsc_base + MPSC_CHR_2);
-       mb();
-
-       while (readl(pi->mpsc_base + MPSC_CHR_2) & MPSC_CHR_2_TTCS);
-}
-#endif
-
-static const struct uart_ops mpsc_pops = {
-       .tx_empty       = mpsc_tx_empty,
-       .set_mctrl      = mpsc_set_mctrl,
-       .get_mctrl      = mpsc_get_mctrl,
-       .stop_tx        = mpsc_stop_tx,
-       .start_tx       = mpsc_start_tx,
-       .stop_rx        = mpsc_stop_rx,
-       .break_ctl      = mpsc_break_ctl,
-       .startup        = mpsc_startup,
-       .shutdown       = mpsc_shutdown,
-       .set_termios    = mpsc_set_termios,
-       .type           = mpsc_type,
-       .release_port   = mpsc_release_port,
-       .request_port   = mpsc_request_port,
-       .config_port    = mpsc_config_port,
-       .verify_port    = mpsc_verify_port,
-#ifdef CONFIG_CONSOLE_POLL
-       .poll_get_char = mpsc_get_poll_char,
-       .poll_put_char = mpsc_put_poll_char,
-#endif
-};
-
-/*
- ******************************************************************************
- *
- * Console Interface Routines
- *
- ******************************************************************************
- */
-
-#ifdef CONFIG_SERIAL_MPSC_CONSOLE
-static void mpsc_console_write(struct console *co, const char *s, uint count)
-{
-       struct mpsc_port_info *pi = &mpsc_ports[co->index];
-       u8 *bp, *dp, add_cr = 0;
-       int i;
-       unsigned long iflags;
-
-       spin_lock_irqsave(&pi->tx_lock, iflags);
-
-       while (pi->txr_head != pi->txr_tail) {
-               while (mpsc_sdma_tx_active(pi))
-                       udelay(100);
-               mpsc_sdma_intr_ack(pi);
-               mpsc_tx_intr(pi);
-       }
-
-       while (mpsc_sdma_tx_active(pi))
-               udelay(100);
-
-       while (count > 0) {
-               bp = dp = pi->txb + (pi->txr_head * MPSC_TXBE_SIZE);
-
-               for (i = 0; i < MPSC_TXBE_SIZE; i++) {
-                       if (count == 0)
-                               break;
-
-                       if (add_cr) {
-                               *(dp++) = '\r';
-                               add_cr = 0;
-                       } else {
-                               *(dp++) = *s;
-
-                               if (*(s++) == '\n') { /* add '\r' after '\n' */
-                                       add_cr = 1;
-                                       count++;
-                               }
-                       }
-
-                       count--;
-               }
-
-               dma_cache_sync(pi->port.dev, (void *)bp, MPSC_TXBE_SIZE,
-                               DMA_BIDIRECTIONAL);
-#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
-               if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
-                       flush_dcache_range((ulong)bp,
-                                       (ulong)bp + MPSC_TXBE_SIZE);
-#endif
-               mpsc_setup_tx_desc(pi, i, 0);
-               pi->txr_head = (pi->txr_head + 1) & (MPSC_TXR_ENTRIES - 1);
-               mpsc_sdma_start_tx(pi);
-
-               while (mpsc_sdma_tx_active(pi))
-                       udelay(100);
-
-               pi->txr_tail = (pi->txr_tail + 1) & (MPSC_TXR_ENTRIES - 1);
-       }
-
-       spin_unlock_irqrestore(&pi->tx_lock, iflags);
-}
-
-static int __init mpsc_console_setup(struct console *co, char *options)
-{
-       struct mpsc_port_info *pi;
-       int baud, bits, parity, flow;
-
-       pr_debug("mpsc_console_setup[%d]: options: %s\n", co->index, options);
-
-       if (co->index >= MPSC_NUM_CTLRS)
-               co->index = 0;
-
-       pi = &mpsc_ports[co->index];
-
-       baud = pi->default_baud;
-       bits = pi->default_bits;
-       parity = pi->default_parity;
-       flow = pi->default_flow;
-
-       if (!pi->port.ops)
-               return -ENODEV;
-
-       spin_lock_init(&pi->port.lock); /* Temporary fix--copied from 8250.c */
-
-       if (options)
-               uart_parse_options(options, &baud, &parity, &bits, &flow);
-
-       return uart_set_options(&pi->port, co, baud, parity, bits, flow);
-}
-
-static struct console mpsc_console = {
-       .name   = MPSC_DEV_NAME,
-       .write  = mpsc_console_write,
-       .device = uart_console_device,
-       .setup  = mpsc_console_setup,
-       .flags  = CON_PRINTBUFFER,
-       .index  = -1,
-       .data   = &mpsc_reg,
-};
-
-static int __init mpsc_late_console_init(void)
-{
-       pr_debug("mpsc_late_console_init: Enter\n");
-
-       if (!(mpsc_console.flags & CON_ENABLED))
-               register_console(&mpsc_console);
-       return 0;
-}
-
-late_initcall(mpsc_late_console_init);
-
-#define MPSC_CONSOLE   &mpsc_console
-#else
-#define MPSC_CONSOLE   NULL
-#endif
-/*
- ******************************************************************************
- *
- * Dummy Platform Driver to extract & map shared register regions
- *
- ******************************************************************************
- */
-static void mpsc_resource_err(char *s)
-{
-       printk(KERN_WARNING "MPSC: Platform device resource error in %s\n", s);
-}
-
-static int mpsc_shared_map_regs(struct platform_device *pd)
-{
-       struct resource *r;
-
-       if ((r = platform_get_resource(pd, IORESOURCE_MEM,
-                                       MPSC_ROUTING_BASE_ORDER))
-                       && request_mem_region(r->start,
-                               MPSC_ROUTING_REG_BLOCK_SIZE,
-                               "mpsc_routing_regs")) {
-               mpsc_shared_regs.mpsc_routing_base = ioremap(r->start,
-                               MPSC_ROUTING_REG_BLOCK_SIZE);
-               mpsc_shared_regs.mpsc_routing_base_p = r->start;
-       } else {
-               mpsc_resource_err("MPSC routing base");
-               return -ENOMEM;
-       }
-
-       if ((r = platform_get_resource(pd, IORESOURCE_MEM,
-                                       MPSC_SDMA_INTR_BASE_ORDER))
-                       && request_mem_region(r->start,
-                               MPSC_SDMA_INTR_REG_BLOCK_SIZE,
-                               "sdma_intr_regs")) {
-               mpsc_shared_regs.sdma_intr_base = ioremap(r->start,
-                       MPSC_SDMA_INTR_REG_BLOCK_SIZE);
-               mpsc_shared_regs.sdma_intr_base_p = r->start;
-       } else {
-               iounmap(mpsc_shared_regs.mpsc_routing_base);
-               release_mem_region(mpsc_shared_regs.mpsc_routing_base_p,
-                               MPSC_ROUTING_REG_BLOCK_SIZE);
-               mpsc_resource_err("SDMA intr base");
-               return -ENOMEM;
-       }
-
-       return 0;
-}
-
-static void mpsc_shared_unmap_regs(void)
-{
-       if (mpsc_shared_regs.mpsc_routing_base) {
-               iounmap(mpsc_shared_regs.mpsc_routing_base);
-               release_mem_region(mpsc_shared_regs.mpsc_routing_base_p,
-                               MPSC_ROUTING_REG_BLOCK_SIZE);
-       }
-       if (mpsc_shared_regs.sdma_intr_base) {
-               iounmap(mpsc_shared_regs.sdma_intr_base);
-               release_mem_region(mpsc_shared_regs.sdma_intr_base_p,
-                               MPSC_SDMA_INTR_REG_BLOCK_SIZE);
-       }
-
-       mpsc_shared_regs.mpsc_routing_base = NULL;
-       mpsc_shared_regs.sdma_intr_base = NULL;
-
-       mpsc_shared_regs.mpsc_routing_base_p = 0;
-       mpsc_shared_regs.sdma_intr_base_p = 0;
-}
-
-static int mpsc_shared_drv_probe(struct platform_device *dev)
-{
-       struct mpsc_shared_pdata        *pdata;
-       int rc;
-
-       if (dev->id != 0)
-               return -ENODEV;
-
-       rc = mpsc_shared_map_regs(dev);
-       if (rc)
-               return rc;
-
-       pdata = dev_get_platdata(&dev->dev);
-
-       mpsc_shared_regs.MPSC_MRR_m = pdata->mrr_val;
-       mpsc_shared_regs.MPSC_RCRR_m= pdata->rcrr_val;
-       mpsc_shared_regs.MPSC_TCRR_m= pdata->tcrr_val;
-       mpsc_shared_regs.SDMA_INTR_CAUSE_m = pdata->intr_cause_val;
-       mpsc_shared_regs.SDMA_INTR_MASK_m = pdata->intr_mask_val;
-
-       return 0;
-}
-
-static int mpsc_shared_drv_remove(struct platform_device *dev)
-{
-       if (dev->id != 0)
-               return -ENODEV;
-
-       mpsc_shared_unmap_regs();
-       mpsc_shared_regs.MPSC_MRR_m = 0;
-       mpsc_shared_regs.MPSC_RCRR_m = 0;
-       mpsc_shared_regs.MPSC_TCRR_m = 0;
-       mpsc_shared_regs.SDMA_INTR_CAUSE_m = 0;
-       mpsc_shared_regs.SDMA_INTR_MASK_m = 0;
-
-       return 0;
-}
-
-static struct platform_driver mpsc_shared_driver = {
-       .probe  = mpsc_shared_drv_probe,
-       .remove = mpsc_shared_drv_remove,
-       .driver = {
-               .name   = MPSC_SHARED_NAME,
-       },
-};
-
-/*
- ******************************************************************************
- *
- * Driver Interface Routines
- *
- ******************************************************************************
- */
-static struct uart_driver mpsc_reg = {
-       .owner          = THIS_MODULE,
-       .driver_name    = MPSC_DRIVER_NAME,
-       .dev_name       = MPSC_DEV_NAME,
-       .major          = MPSC_MAJOR,
-       .minor          = MPSC_MINOR_START,
-       .nr             = MPSC_NUM_CTLRS,
-       .cons           = MPSC_CONSOLE,
-};
-
-static int mpsc_drv_map_regs(struct mpsc_port_info *pi,
-               struct platform_device *pd)
-{
-       struct resource *r;
-
-       if ((r = platform_get_resource(pd, IORESOURCE_MEM, MPSC_BASE_ORDER))
-                       && request_mem_region(r->start, MPSC_REG_BLOCK_SIZE,
-                       "mpsc_regs")) {
-               pi->mpsc_base = ioremap(r->start, MPSC_REG_BLOCK_SIZE);
-               pi->mpsc_base_p = r->start;
-       } else {
-               mpsc_resource_err("MPSC base");
-               goto err;
-       }
-
-       if ((r = platform_get_resource(pd, IORESOURCE_MEM,
-                                       MPSC_SDMA_BASE_ORDER))
-                       && request_mem_region(r->start,
-                               MPSC_SDMA_REG_BLOCK_SIZE, "sdma_regs")) {
-               pi->sdma_base = ioremap(r->start,MPSC_SDMA_REG_BLOCK_SIZE);
-               pi->sdma_base_p = r->start;
-       } else {
-               mpsc_resource_err("SDMA base");
-               goto err;
-       }
-
-       if ((r = platform_get_resource(pd,IORESOURCE_MEM,MPSC_BRG_BASE_ORDER))
-                       && request_mem_region(r->start,
-                               MPSC_BRG_REG_BLOCK_SIZE, "brg_regs")) {
-               pi->brg_base = ioremap(r->start, MPSC_BRG_REG_BLOCK_SIZE);
-               pi->brg_base_p = r->start;
-       } else {
-               mpsc_resource_err("BRG base");
-               goto err;
-       }
-       return 0;
-
-err:
-       if (pi->sdma_base) {
-               iounmap(pi->sdma_base);
-               pi->sdma_base = NULL;
-       }
-       if (pi->mpsc_base) {
-               iounmap(pi->mpsc_base);
-               pi->mpsc_base = NULL;
-       }
-       return -ENOMEM;
-}
-
-static void mpsc_drv_unmap_regs(struct mpsc_port_info *pi)
-{
-       if (pi->mpsc_base) {
-               iounmap(pi->mpsc_base);
-               release_mem_region(pi->mpsc_base_p, MPSC_REG_BLOCK_SIZE);
-       }
-       if (pi->sdma_base) {
-               iounmap(pi->sdma_base);
-               release_mem_region(pi->sdma_base_p, MPSC_SDMA_REG_BLOCK_SIZE);
-       }
-       if (pi->brg_base) {
-               iounmap(pi->brg_base);
-               release_mem_region(pi->brg_base_p, MPSC_BRG_REG_BLOCK_SIZE);
-       }
-
-       pi->mpsc_base = NULL;
-       pi->sdma_base = NULL;
-       pi->brg_base = NULL;
-
-       pi->mpsc_base_p = 0;
-       pi->sdma_base_p = 0;
-       pi->brg_base_p = 0;
-}
-
-static void mpsc_drv_get_platform_data(struct mpsc_port_info *pi,
-               struct platform_device *pd, int num)
-{
-       struct mpsc_pdata       *pdata;
-
-       pdata = dev_get_platdata(&pd->dev);
-
-       pi->port.uartclk = pdata->brg_clk_freq;
-       pi->port.iotype = UPIO_MEM;
-       pi->port.line = num;
-       pi->port.type = PORT_MPSC;
-       pi->port.fifosize = MPSC_TXBE_SIZE;
-       pi->port.membase = pi->mpsc_base;
-       pi->port.mapbase = (ulong)pi->mpsc_base;
-       pi->port.ops = &mpsc_pops;
-
-       pi->mirror_regs = pdata->mirror_regs;
-       pi->cache_mgmt = pdata->cache_mgmt;
-       pi->brg_can_tune = pdata->brg_can_tune;
-       pi->brg_clk_src = pdata->brg_clk_src;
-       pi->mpsc_max_idle = pdata->max_idle;
-       pi->default_baud = pdata->default_baud;
-       pi->default_bits = pdata->default_bits;
-       pi->default_parity = pdata->default_parity;
-       pi->default_flow = pdata->default_flow;
-
-       /* Initial values of mirrored regs */
-       pi->MPSC_CHR_1_m = pdata->chr_1_val;
-       pi->MPSC_CHR_2_m = pdata->chr_2_val;
-       pi->MPSC_CHR_10_m = pdata->chr_10_val;
-       pi->MPSC_MPCR_m = pdata->mpcr_val;
-       pi->BRG_BCR_m = pdata->bcr_val;
-
-       pi->shared_regs = &mpsc_shared_regs;
-
-       pi->port.irq = platform_get_irq(pd, 0);
-}
-
-static int mpsc_drv_probe(struct platform_device *dev)
-{
-       struct mpsc_port_info *pi;
-       int rc;
-
-       dev_dbg(&dev->dev, "mpsc_drv_probe: Adding MPSC %d\n", dev->id);
-
-       if (dev->id >= MPSC_NUM_CTLRS)
-               return -ENODEV;
-
-       pi = &mpsc_ports[dev->id];
-
-       rc = mpsc_drv_map_regs(pi, dev);
-       if (rc)
-               return rc;
-
-       mpsc_drv_get_platform_data(pi, dev, dev->id);
-       pi->port.dev = &dev->dev;
-
-       rc = mpsc_make_ready(pi);
-       if (rc)
-               goto err_unmap;
-
-       spin_lock_init(&pi->tx_lock);
-       rc = uart_add_one_port(&mpsc_reg, &pi->port);
-       if (rc)
-               goto err_relport;
-
-       return 0;
-err_relport:
-       mpsc_release_port(&pi->port);
-err_unmap:
-       mpsc_drv_unmap_regs(pi);
-       return rc;
-}
-
-static struct platform_driver mpsc_driver = {
-       .probe  = mpsc_drv_probe,
-       .driver = {
-               .name                   = MPSC_CTLR_NAME,
-               .suppress_bind_attrs    = true,
-       },
-};
-
-static int __init mpsc_drv_init(void)
-{
-       int     rc;
-
-       printk(KERN_INFO "Serial: MPSC driver\n");
-
-       memset(mpsc_ports, 0, sizeof(mpsc_ports));
-       memset(&mpsc_shared_regs, 0, sizeof(mpsc_shared_regs));
-
-       rc = uart_register_driver(&mpsc_reg);
-       if (rc)
-               return rc;
-
-       rc = platform_driver_register(&mpsc_shared_driver);
-       if (rc)
-               goto err_unreg_uart;
-
-       rc = platform_driver_register(&mpsc_driver);
-       if (rc)
-               goto err_unreg_plat;
-
-       return 0;
-err_unreg_plat:
-       platform_driver_unregister(&mpsc_shared_driver);
-err_unreg_uart:
-       uart_unregister_driver(&mpsc_reg);
-       return rc;
-}
-device_initcall(mpsc_drv_init);
-
-/*
-MODULE_AUTHOR("Mark A. Greer <mgreer@mvista.com>");
-MODULE_DESCRIPTION("Generic Marvell MPSC serial/UART driver");
-MODULE_LICENSE("GPL");
-*/
index 23833ad952ba3aa7ad64d1314618536790f8af19..3657a24913fc991c01521a0d7022e7a3b393e57d 100644 (file)
@@ -383,10 +383,14 @@ no_rx:
 
 static inline void msm_wait_for_xmitr(struct uart_port *port)
 {
+       unsigned int timeout = 500000;
+
        while (!(msm_read(port, UART_SR) & UART_SR_TX_EMPTY)) {
                if (msm_read(port, UART_ISR) & UART_ISR_TX_READY)
                        break;
                udelay(1);
+               if (!timeout--)
+                       break;
        }
        msm_write(port, UART_CR_CMD_RESET_TX_READY, UART_CR);
 }
index 83f4dd0bfd74552fe813646aa9abb71fed72ace9..4223cb4967646696afab42943715d964e77da3f0 100644 (file)
@@ -1777,6 +1777,7 @@ static int uart_port_activate(struct tty_port *port, struct tty_struct *tty)
 {
        struct uart_state *state = container_of(port, struct uart_state, port);
        struct uart_port *uport;
+       int ret;
 
        uport = uart_port_check(state);
        if (!uport || uport->flags & UPF_DEAD)
@@ -1787,7 +1788,11 @@ static int uart_port_activate(struct tty_port *port, struct tty_struct *tty)
        /*
         * Start up the serial port.
         */
-       return uart_startup(tty, state, 0);
+       ret = uart_startup(tty, state, 0);
+       if (ret > 0)
+               tty_port_set_active(port, 1);
+
+       return ret;
 }
 
 static const char *uart_type(struct uart_port *port)
index 39ed56214cd32c32447ef30baf1997dc27d2a003..2b400189be911cbe0d9ef8fa5893166aab9181e1 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/termios.h>
 #include <linux/serial_core.h>
 #include <linux/module.h>
+#include <linux/property.h>
 
 #include "serial_mctrl_gpio.h"
 
@@ -116,6 +117,19 @@ struct mctrl_gpios *mctrl_gpio_init_noauto(struct device *dev, unsigned int idx)
 
        for (i = 0; i < UART_GPIO_MAX; i++) {
                enum gpiod_flags flags;
+               char *gpio_str;
+               bool present;
+
+               /* Check if GPIO property exists and continue if not */
+               gpio_str = kasprintf(GFP_KERNEL, "%s-gpios",
+                                    mctrl_gpios_desc[i].name);
+               if (!gpio_str)
+                       continue;
+
+               present = device_property_present(dev, gpio_str);
+               kfree(gpio_str);
+               if (!present)
+                       continue;
 
                if (mctrl_gpios_desc[i].dir_out)
                        flags = GPIOD_OUT_LOW;
index abc705716aa094fde652c3bc77c18210a5b8b280..d18c680aa64b34273075d9388413c954996d193f 100644 (file)
@@ -1398,6 +1398,7 @@ static void sci_dma_tx_work_fn(struct work_struct *work)
        struct circ_buf *xmit = &port->state->xmit;
        unsigned long flags;
        dma_addr_t buf;
+       int head, tail;
 
        /*
         * DMA is idle now.
@@ -1407,16 +1408,23 @@ static void sci_dma_tx_work_fn(struct work_struct *work)
         * consistent xmit buffer state.
         */
        spin_lock_irq(&port->lock);
-       buf = s->tx_dma_addr + (xmit->tail & (UART_XMIT_SIZE - 1));
+       head = xmit->head;
+       tail = xmit->tail;
+       buf = s->tx_dma_addr + (tail & (UART_XMIT_SIZE - 1));
        s->tx_dma_len = min_t(unsigned int,
-               CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE),
-               CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE));
-       spin_unlock_irq(&port->lock);
+               CIRC_CNT(head, tail, UART_XMIT_SIZE),
+               CIRC_CNT_TO_END(head, tail, UART_XMIT_SIZE));
+       if (!s->tx_dma_len) {
+               /* Transmit buffer has been flushed */
+               spin_unlock_irq(&port->lock);
+               return;
+       }
 
        desc = dmaengine_prep_slave_single(chan, buf, s->tx_dma_len,
                                           DMA_MEM_TO_DEV,
                                           DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
        if (!desc) {
+               spin_unlock_irq(&port->lock);
                dev_warn(port->dev, "Failed preparing Tx DMA descriptor\n");
                goto switch_to_pio;
        }
@@ -1424,18 +1432,18 @@ static void sci_dma_tx_work_fn(struct work_struct *work)
        dma_sync_single_for_device(chan->device->dev, buf, s->tx_dma_len,
                                   DMA_TO_DEVICE);
 
-       spin_lock_irq(&port->lock);
        desc->callback = sci_dma_tx_complete;
        desc->callback_param = s;
-       spin_unlock_irq(&port->lock);
        s->cookie_tx = dmaengine_submit(desc);
        if (dma_submit_error(s->cookie_tx)) {
+               spin_unlock_irq(&port->lock);
                dev_warn(port->dev, "Failed submitting Tx DMA descriptor\n");
                goto switch_to_pio;
        }
 
+       spin_unlock_irq(&port->lock);
        dev_dbg(port->dev, "%s: %p: %d...%d, cookie %d\n",
-               __func__, xmit->buf, xmit->tail, xmit->head, s->cookie_tx);
+               __func__, xmit->buf, tail, head, s->cookie_tx);
 
        dma_async_issue_pending(chan);
        return;
@@ -1648,11 +1656,18 @@ static void sci_free_dma(struct uart_port *port)
 
 static void sci_flush_buffer(struct uart_port *port)
 {
+       struct sci_port *s = to_sci_port(port);
+
        /*
         * In uart_flush_buffer(), the xmit circular buffer has just been
-        * cleared, so we have to reset tx_dma_len accordingly.
+        * cleared, so we have to reset tx_dma_len accordingly, and stop any
+        * pending transfers
         */
-       to_sci_port(port)->tx_dma_len = 0;
+       s->tx_dma_len = 0;
+       if (s->chan_tx) {
+               dmaengine_terminate_async(s->chan_tx);
+               s->cookie_tx = -EINVAL;
+       }
 }
 #else /* !CONFIG_SERIAL_SH_SCI_DMA */
 static inline void sci_request_dma(struct uart_port *port)
index e8d7a7bb4339e4ef40fc22cb433588c54dbd43c0..24a2261f879a16aabbf4484fa84952f107dca101 100644 (file)
@@ -105,9 +105,7 @@ static int stm32_config_rs485(struct uart_port *port,
        struct stm32_usart_config *cfg = &stm32_port->info->cfg;
        u32 usartdiv, baud, cr1, cr3;
        bool over8;
-       unsigned long flags;
 
-       spin_lock_irqsave(&port->lock, flags);
        stm32_clr_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit));
 
        port->rs485 = *rs485conf;
@@ -147,7 +145,6 @@ static int stm32_config_rs485(struct uart_port *port,
        }
 
        stm32_set_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit));
-       spin_unlock_irqrestore(&port->lock, flags);
 
        return 0;
 }
@@ -194,8 +191,8 @@ static int stm32_pending_rx(struct uart_port *port, u32 *sr, int *last_res,
        return 0;
 }
 
-static unsigned long
-stm32_get_char(struct uart_port *port, u32 *sr, int *last_res)
+static unsigned long stm32_get_char(struct uart_port *port, u32 *sr,
+                                   int *last_res)
 {
        struct stm32_port *stm32_port = to_stm32_port(port);
        struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
@@ -205,10 +202,13 @@ stm32_get_char(struct uart_port *port, u32 *sr, int *last_res)
                c = stm32_port->rx_buf[RX_BUF_L - (*last_res)--];
                if ((*last_res) == 0)
                        *last_res = RX_BUF_L;
-               return c;
        } else {
-               return readl_relaxed(port->membase + ofs->rdr);
+               c = readl_relaxed(port->membase + ofs->rdr);
+               /* apply RDR data mask */
+               c &= stm32_port->rdr_mask;
        }
+
+       return c;
 }
 
 static void stm32_receive_chars(struct uart_port *port, bool threaded)
@@ -225,35 +225,51 @@ static void stm32_receive_chars(struct uart_port *port, bool threaded)
 
        while (stm32_pending_rx(port, &sr, &stm32_port->last_res, threaded)) {
                sr |= USART_SR_DUMMY_RX;
-               c = stm32_get_char(port, &sr, &stm32_port->last_res);
                flag = TTY_NORMAL;
-               port->icount.rx++;
 
+               /*
+                * Status bits has to be cleared before reading the RDR:
+                * In FIFO mode, reading the RDR will pop the next data
+                * (if any) along with its status bits into the SR.
+                * Not doing so leads to misalignement between RDR and SR,
+                * and clear status bits of the next rx data.
+                *
+                * Clear errors flags for stm32f7 and stm32h7 compatible
+                * devices. On stm32f4 compatible devices, the error bit is
+                * cleared by the sequence [read SR - read DR].
+                */
+               if ((sr & USART_SR_ERR_MASK) && ofs->icr != UNDEF_REG)
+                       stm32_clr_bits(port, ofs->icr, USART_ICR_ORECF |
+                                      USART_ICR_PECF | USART_ICR_FECF);
+
+               c = stm32_get_char(port, &sr, &stm32_port->last_res);
+               port->icount.rx++;
                if (sr & USART_SR_ERR_MASK) {
-                       if (sr & USART_SR_LBD) {
-                               port->icount.brk++;
-                               if (uart_handle_break(port))
-                                       continue;
-                       } else if (sr & USART_SR_ORE) {
-                               if (ofs->icr != UNDEF_REG)
-                                       writel_relaxed(USART_ICR_ORECF,
-                                                      port->membase +
-                                                      ofs->icr);
+                       if (sr & USART_SR_ORE) {
                                port->icount.overrun++;
                        } else if (sr & USART_SR_PE) {
                                port->icount.parity++;
                        } else if (sr & USART_SR_FE) {
-                               port->icount.frame++;
+                               /* Break detection if character is null */
+                               if (!c) {
+                                       port->icount.brk++;
+                                       if (uart_handle_break(port))
+                                               continue;
+                               } else {
+                                       port->icount.frame++;
+                               }
                        }
 
                        sr &= port->read_status_mask;
 
-                       if (sr & USART_SR_LBD)
-                               flag = TTY_BREAK;
-                       else if (sr & USART_SR_PE)
+                       if (sr & USART_SR_PE) {
                                flag = TTY_PARITY;
-                       else if (sr & USART_SR_FE)
-                               flag = TTY_FRAME;
+                       } else if (sr & USART_SR_FE) {
+                               if (!c)
+                                       flag = TTY_BREAK;
+                               else
+                                       flag = TTY_FRAME;
+                       }
                }
 
                if (uart_handle_sysrq_char(port, c))
@@ -271,21 +287,6 @@ static void stm32_tx_dma_complete(void *arg)
        struct uart_port *port = arg;
        struct stm32_port *stm32port = to_stm32_port(port);
        struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
-       unsigned int isr;
-       int ret;
-
-       ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr,
-                                               isr,
-                                               (isr & USART_SR_TC),
-                                               10, 100000);
-
-       if (ret)
-               dev_err(port->dev, "terminal count not set\n");
-
-       if (ofs->icr == UNDEF_REG)
-               stm32_clr_bits(port, ofs->isr, USART_SR_TC);
-       else
-               stm32_set_bits(port, ofs->icr, USART_CR_TC);
 
        stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
        stm32port->tx_dma_busy = false;
@@ -294,32 +295,57 @@ static void stm32_tx_dma_complete(void *arg)
        stm32_transmit_chars(port);
 }
 
+static void stm32_tx_interrupt_enable(struct uart_port *port)
+{
+       struct stm32_port *stm32_port = to_stm32_port(port);
+       struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+
+       /*
+        * Enables TX FIFO threashold irq when FIFO is enabled,
+        * or TX empty irq when FIFO is disabled
+        */
+       if (stm32_port->fifoen)
+               stm32_set_bits(port, ofs->cr3, USART_CR3_TXFTIE);
+       else
+               stm32_set_bits(port, ofs->cr1, USART_CR1_TXEIE);
+}
+
+static void stm32_tx_interrupt_disable(struct uart_port *port)
+{
+       struct stm32_port *stm32_port = to_stm32_port(port);
+       struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+
+       if (stm32_port->fifoen)
+               stm32_clr_bits(port, ofs->cr3, USART_CR3_TXFTIE);
+       else
+               stm32_clr_bits(port, ofs->cr1, USART_CR1_TXEIE);
+}
+
 static void stm32_transmit_chars_pio(struct uart_port *port)
 {
        struct stm32_port *stm32_port = to_stm32_port(port);
        struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
        struct circ_buf *xmit = &port->state->xmit;
-       unsigned int isr;
-       int ret;
 
        if (stm32_port->tx_dma_busy) {
                stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
                stm32_port->tx_dma_busy = false;
        }
 
-       ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr,
-                                               isr,
-                                               (isr & USART_SR_TXE),
-                                               10, 100000);
-
-       if (ret)
-               dev_err(port->dev, "tx empty not set\n");
-
-       stm32_set_bits(port, ofs->cr1, USART_CR1_TXEIE);
+       while (!uart_circ_empty(xmit)) {
+               /* Check that TDR is empty before filling FIFO */
+               if (!(readl_relaxed(port->membase + ofs->isr) & USART_SR_TXE))
+                       break;
+               writel_relaxed(xmit->buf[xmit->tail], port->membase + ofs->tdr);
+               xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+               port->icount.tx++;
+       }
 
-       writel_relaxed(xmit->buf[xmit->tail], port->membase + ofs->tdr);
-       xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-       port->icount.tx++;
+       /* rely on TXE irq (mask or unmask) for sending remaining data */
+       if (uart_circ_empty(xmit))
+               stm32_tx_interrupt_disable(port);
+       else
+               stm32_tx_interrupt_enable(port);
 }
 
 static void stm32_transmit_chars_dma(struct uart_port *port)
@@ -377,7 +403,6 @@ static void stm32_transmit_chars_dma(struct uart_port *port)
        /* Issue pending DMA TX requests */
        dma_async_issue_pending(stm32port->tx_ch);
 
-       stm32_clr_bits(port, ofs->isr, USART_SR_TC);
        stm32_set_bits(port, ofs->cr3, USART_CR3_DMAT);
 
        xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
@@ -401,15 +426,15 @@ static void stm32_transmit_chars(struct uart_port *port)
                return;
        }
 
-       if (uart_tx_stopped(port)) {
-               stm32_stop_tx(port);
+       if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+               stm32_tx_interrupt_disable(port);
                return;
        }
 
-       if (uart_circ_empty(xmit)) {
-               stm32_stop_tx(port);
-               return;
-       }
+       if (ofs->icr == UNDEF_REG)
+               stm32_clr_bits(port, ofs->isr, USART_SR_TC);
+       else
+               stm32_set_bits(port, ofs->icr, USART_ICR_TCCF);
 
        if (stm32_port->tx_ch)
                stm32_transmit_chars_dma(port);
@@ -420,7 +445,7 @@ static void stm32_transmit_chars(struct uart_port *port)
                uart_write_wakeup(port);
 
        if (uart_circ_empty(xmit))
-               stm32_stop_tx(port);
+               stm32_tx_interrupt_disable(port);
 }
 
 static irqreturn_t stm32_interrupt(int irq, void *ptr)
@@ -434,6 +459,10 @@ static irqreturn_t stm32_interrupt(int irq, void *ptr)
 
        sr = readl_relaxed(port->membase + ofs->isr);
 
+       if ((sr & USART_SR_RTOF) && ofs->icr != UNDEF_REG)
+               writel_relaxed(USART_ICR_RTOCF,
+                              port->membase + ofs->icr);
+
        if ((sr & USART_SR_WUF) && (ofs->icr != UNDEF_REG))
                writel_relaxed(USART_ICR_WUCF,
                               port->membase + ofs->icr);
@@ -495,10 +524,7 @@ static unsigned int stm32_get_mctrl(struct uart_port *port)
 /* Transmit stop */
 static void stm32_stop_tx(struct uart_port *port)
 {
-       struct stm32_port *stm32_port = to_stm32_port(port);
-       struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
-
-       stm32_clr_bits(port, ofs->cr1, USART_CR1_TXEIE);
+       stm32_tx_interrupt_disable(port);
 }
 
 /* There are probably characters waiting to be transmitted. */
@@ -520,7 +546,10 @@ static void stm32_throttle(struct uart_port *port)
        unsigned long flags;
 
        spin_lock_irqsave(&port->lock, flags);
-       stm32_clr_bits(port, ofs->cr1, USART_CR1_RXNEIE);
+       stm32_clr_bits(port, ofs->cr1, stm32_port->cr1_irq);
+       if (stm32_port->cr3_irq)
+               stm32_clr_bits(port, ofs->cr3, stm32_port->cr3_irq);
+
        spin_unlock_irqrestore(&port->lock, flags);
 }
 
@@ -532,7 +561,10 @@ static void stm32_unthrottle(struct uart_port *port)
        unsigned long flags;
 
        spin_lock_irqsave(&port->lock, flags);
-       stm32_set_bits(port, ofs->cr1, USART_CR1_RXNEIE);
+       stm32_set_bits(port, ofs->cr1, stm32_port->cr1_irq);
+       if (stm32_port->cr3_irq)
+               stm32_set_bits(port, ofs->cr3, stm32_port->cr3_irq);
+
        spin_unlock_irqrestore(&port->lock, flags);
 }
 
@@ -542,7 +574,10 @@ static void stm32_stop_rx(struct uart_port *port)
        struct stm32_port *stm32_port = to_stm32_port(port);
        struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
 
-       stm32_clr_bits(port, ofs->cr1, USART_CR1_RXNEIE);
+       stm32_clr_bits(port, ofs->cr1, stm32_port->cr1_irq);
+       if (stm32_port->cr3_irq)
+               stm32_clr_bits(port, ofs->cr3, stm32_port->cr3_irq);
+
 }
 
 /* Handle breaks - ignored by us */
@@ -554,7 +589,6 @@ static int stm32_startup(struct uart_port *port)
 {
        struct stm32_port *stm32_port = to_stm32_port(port);
        struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
-       struct stm32_usart_config *cfg = &stm32_port->info->cfg;
        const char *name = to_platform_device(port->dev)->name;
        u32 val;
        int ret;
@@ -565,16 +599,21 @@ static int stm32_startup(struct uart_port *port)
        if (ret)
                return ret;
 
-       if (cfg->has_wakeup && stm32_port->wakeirq >= 0) {
-               ret = dev_pm_set_dedicated_wake_irq(port->dev,
-                                                   stm32_port->wakeirq);
-               if (ret) {
-                       free_irq(port->irq, port);
-                       return ret;
-               }
+       /* RX FIFO Flush */
+       if (ofs->rqr != UNDEF_REG)
+               stm32_set_bits(port, ofs->rqr, USART_RQR_RXFRQ);
+
+       /* Tx and RX FIFO configuration */
+       if (stm32_port->fifoen) {
+               val = readl_relaxed(port->membase + ofs->cr3);
+               val &= ~(USART_CR3_TXFTCFG_MASK | USART_CR3_RXFTCFG_MASK);
+               val |= USART_CR3_TXFTCFG_HALF << USART_CR3_TXFTCFG_SHIFT;
+               val |= USART_CR3_RXFTCFG_HALF << USART_CR3_RXFTCFG_SHIFT;
+               writel_relaxed(val, port->membase + ofs->cr3);
        }
 
-       val = USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
+       /* RX FIFO enabling */
+       val = stm32_port->cr1_irq | USART_CR1_RE;
        if (stm32_port->fifoen)
                val |= USART_CR1_FIFOEN;
        stm32_set_bits(port, ofs->cr1, val);
@@ -587,18 +626,57 @@ static void stm32_shutdown(struct uart_port *port)
        struct stm32_port *stm32_port = to_stm32_port(port);
        struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
        struct stm32_usart_config *cfg = &stm32_port->info->cfg;
-       u32 val;
+       u32 val, isr;
+       int ret;
 
-       val = USART_CR1_TXEIE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
+       val = USART_CR1_TXEIE | USART_CR1_TE;
+       val |= stm32_port->cr1_irq | USART_CR1_RE;
        val |= BIT(cfg->uart_enable_bit);
        if (stm32_port->fifoen)
                val |= USART_CR1_FIFOEN;
+
+       ret = readl_relaxed_poll_timeout(port->membase + ofs->isr,
+                                        isr, (isr & USART_SR_TC),
+                                        10, 100000);
+
+       if (ret)
+               dev_err(port->dev, "transmission complete not set\n");
+
        stm32_clr_bits(port, ofs->cr1, val);
 
-       dev_pm_clear_wake_irq(port->dev);
        free_irq(port->irq, port);
 }
 
+static unsigned int stm32_get_databits(struct ktermios *termios)
+{
+       unsigned int bits;
+
+       tcflag_t cflag = termios->c_cflag;
+
+       switch (cflag & CSIZE) {
+       /*
+        * CSIZE settings are not necessarily supported in hardware.
+        * CSIZE unsupported configurations are handled here to set word length
+        * to 8 bits word as default configuration and to print debug message.
+        */
+       case CS5:
+               bits = 5;
+               break;
+       case CS6:
+               bits = 6;
+               break;
+       case CS7:
+               bits = 7;
+               break;
+       /* default including CS8 */
+       default:
+               bits = 8;
+               break;
+       }
+
+       return bits;
+}
+
 static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
                            struct ktermios *old)
 {
@@ -606,7 +684,7 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
        struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
        struct stm32_usart_config *cfg = &stm32_port->info->cfg;
        struct serial_rs485 *rs485conf = &port->rs485;
-       unsigned int baud;
+       unsigned int baud, bits;
        u32 usartdiv, mantissa, fraction, oversampling;
        tcflag_t cflag = termios->c_cflag;
        u32 cr1, cr2, cr3;
@@ -622,26 +700,64 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
        /* Stop serial port and reset value */
        writel_relaxed(0, port->membase + ofs->cr1);
 
-       cr1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE;
+       /* flush RX & TX FIFO */
+       if (ofs->rqr != UNDEF_REG)
+               stm32_set_bits(port, ofs->rqr,
+                              USART_RQR_TXFRQ | USART_RQR_RXFRQ);
 
+       cr1 = USART_CR1_TE | USART_CR1_RE;
        if (stm32_port->fifoen)
                cr1 |= USART_CR1_FIFOEN;
        cr2 = 0;
-       cr3 = 0;
+       cr3 = readl_relaxed(port->membase + ofs->cr3);
+       cr3 &= USART_CR3_TXFTIE | USART_CR3_RXFTCFG_MASK | USART_CR3_RXFTIE
+               | USART_CR3_TXFTCFG_MASK;
 
        if (cflag & CSTOPB)
                cr2 |= USART_CR2_STOP_2B;
 
+       bits = stm32_get_databits(termios);
+       stm32_port->rdr_mask = (BIT(bits) - 1);
+
        if (cflag & PARENB) {
+               bits++;
                cr1 |= USART_CR1_PCE;
-               if ((cflag & CSIZE) == CS8) {
-                       if (cfg->has_7bits_data)
-                               cr1 |= USART_CR1_M0;
-                       else
-                               cr1 |= USART_CR1_M;
-               }
        }
 
+       /*
+        * Word length configuration:
+        * CS8 + parity, 9 bits word aka [M1:M0] = 0b01
+        * CS7 or (CS6 + parity), 7 bits word aka [M1:M0] = 0b10
+        * CS8 or (CS7 + parity), 8 bits word aka [M1:M0] = 0b00
+        * M0 and M1 already cleared by cr1 initialization.
+        */
+       if (bits == 9)
+               cr1 |= USART_CR1_M0;
+       else if ((bits == 7) && cfg->has_7bits_data)
+               cr1 |= USART_CR1_M1;
+       else if (bits != 8)
+               dev_dbg(port->dev, "Unsupported data bits config: %u bits\n"
+                       , bits);
+
+       if (ofs->rtor != UNDEF_REG && (stm32_port->rx_ch ||
+                                      stm32_port->fifoen)) {
+               if (cflag & CSTOPB)
+                       bits = bits + 3; /* 1 start bit + 2 stop bits */
+               else
+                       bits = bits + 2; /* 1 start bit + 1 stop bit */
+
+               /* RX timeout irq to occur after last stop bit + bits */
+               stm32_port->cr1_irq = USART_CR1_RTOIE;
+               writel_relaxed(bits, port->membase + ofs->rtor);
+               cr2 |= USART_CR2_RTOEN;
+               /* Not using dma, enable fifo threshold irq */
+               if (!stm32_port->rx_ch)
+                       stm32_port->cr3_irq =  USART_CR3_RXFTIE;
+       }
+
+       cr1 |= stm32_port->cr1_irq;
+       cr3 |= stm32_port->cr3_irq;
+
        if (cflag & PARODD)
                cr1 |= USART_CR1_PS;
 
@@ -679,14 +795,14 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
        if (termios->c_iflag & INPCK)
                port->read_status_mask |= USART_SR_PE | USART_SR_FE;
        if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
-               port->read_status_mask |= USART_SR_LBD;
+               port->read_status_mask |= USART_SR_FE;
 
        /* Characters to ignore */
        port->ignore_status_mask = 0;
        if (termios->c_iflag & IGNPAR)
                port->ignore_status_mask = USART_SR_PE | USART_SR_FE;
        if (termios->c_iflag & IGNBRK) {
-               port->ignore_status_mask |= USART_SR_LBD;
+               port->ignore_status_mask |= USART_SR_FE;
                /*
                 * If we're ignoring parity and break indicators,
                 * ignore overruns too (for real raw support).
@@ -808,12 +924,32 @@ static int stm32_init_port(struct stm32_port *stm32port,
        port->flags     = UPF_BOOT_AUTOCONF;
        port->ops       = &stm32_uart_ops;
        port->dev       = &pdev->dev;
-       port->irq       = platform_get_irq(pdev, 0);
+       port->fifosize  = stm32port->info->cfg.fifosize;
+
+       ret = platform_get_irq(pdev, 0);
+       if (ret <= 0) {
+               if (ret != -EPROBE_DEFER)
+                       dev_err(&pdev->dev, "Can't get event IRQ: %d\n", ret);
+               return ret ? ret : -ENODEV;
+       }
+       port->irq = ret;
+
        port->rs485_config = stm32_config_rs485;
 
        stm32_init_rs485(port, pdev);
 
-       stm32port->wakeirq = platform_get_irq(pdev, 1);
+       if (stm32port->info->cfg.has_wakeup) {
+               stm32port->wakeirq = platform_get_irq(pdev, 1);
+               if (stm32port->wakeirq <= 0 && stm32port->wakeirq != -ENXIO) {
+                       if (stm32port->wakeirq != -EPROBE_DEFER)
+                               dev_err(&pdev->dev,
+                                       "Can't get event wake IRQ: %d\n",
+                                       stm32port->wakeirq);
+                       return stm32port->wakeirq ? stm32port->wakeirq :
+                               -ENODEV;
+               }
+       }
+
        stm32port->fifoen = stm32port->info->cfg.has_fifo;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -862,6 +998,8 @@ static struct stm32_port *stm32_of_get_stm32_port(struct platform_device *pdev)
        stm32_ports[id].hw_flow_control = of_property_read_bool(np,
                                                        "st,hw-flow-ctrl");
        stm32_ports[id].port.line = id;
+       stm32_ports[id].cr1_irq = USART_CR1_RXNEIE;
+       stm32_ports[id].cr3_irq = 0;
        stm32_ports[id].last_res = RX_BUF_L;
        return &stm32_ports[id];
 }
@@ -1020,15 +1158,22 @@ static int stm32_serial_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
-       if (stm32port->info->cfg.has_wakeup && stm32port->wakeirq >= 0) {
+       if (stm32port->wakeirq > 0) {
                ret = device_init_wakeup(&pdev->dev, true);
                if (ret)
                        goto err_uninit;
+
+               ret = dev_pm_set_dedicated_wake_irq(&pdev->dev,
+                                                   stm32port->wakeirq);
+               if (ret)
+                       goto err_nowup;
+
+               device_set_wakeup_enable(&pdev->dev, false);
        }
 
        ret = uart_add_one_port(&stm32_usart_driver, &stm32port->port);
        if (ret)
-               goto err_nowup;
+               goto err_wirq;
 
        ret = stm32_of_dma_rx_probe(stm32port, pdev);
        if (ret)
@@ -1042,8 +1187,12 @@ static int stm32_serial_probe(struct platform_device *pdev)
 
        return 0;
 
+err_wirq:
+       if (stm32port->wakeirq > 0)
+               dev_pm_clear_wake_irq(&pdev->dev);
+
 err_nowup:
-       if (stm32port->info->cfg.has_wakeup && stm32port->wakeirq >= 0)
+       if (stm32port->wakeirq > 0)
                device_init_wakeup(&pdev->dev, false);
 
 err_uninit:
@@ -1057,7 +1206,6 @@ static int stm32_serial_remove(struct platform_device *pdev)
        struct uart_port *port = platform_get_drvdata(pdev);
        struct stm32_port *stm32_port = to_stm32_port(port);
        struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
-       struct stm32_usart_config *cfg = &stm32_port->info->cfg;
 
        stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAR);
 
@@ -1079,8 +1227,10 @@ static int stm32_serial_remove(struct platform_device *pdev)
                                  TX_BUF_L, stm32_port->tx_buf,
                                  stm32_port->tx_dma_buf);
 
-       if (cfg->has_wakeup && stm32_port->wakeirq >= 0)
+       if (stm32_port->wakeirq > 0) {
+               dev_pm_clear_wake_irq(&pdev->dev);
                device_init_wakeup(&pdev->dev, false);
+       }
 
        clk_disable_unprepare(stm32_port->clk);
 
@@ -1195,7 +1345,7 @@ static void stm32_serial_enable_wakeup(struct uart_port *port, bool enable)
        struct stm32_usart_config *cfg = &stm32_port->info->cfg;
        u32 val;
 
-       if (!cfg->has_wakeup || stm32_port->wakeirq < 0)
+       if (stm32_port->wakeirq <= 0)
                return;
 
        if (enable) {
index 6f294e280ea301a72be694b53f3dfa1374b397c3..a175c1094dc8dfa0551b81c4ed5cc73cc87d16c1 100644 (file)
@@ -27,6 +27,7 @@ struct stm32_usart_config {
        bool has_7bits_data;
        bool has_wakeup;
        bool has_fifo;
+       int fifosize;
 };
 
 struct stm32_usart_info {
@@ -54,6 +55,7 @@ struct stm32_usart_info stm32f4_info = {
        .cfg = {
                .uart_enable_bit = 13,
                .has_7bits_data = false,
+               .fifosize = 1,
        }
 };
 
@@ -74,6 +76,7 @@ struct stm32_usart_info stm32f7_info = {
        .cfg = {
                .uart_enable_bit = 0,
                .has_7bits_data = true,
+               .fifosize = 1,
        }
 };
 
@@ -96,6 +99,7 @@ struct stm32_usart_info stm32h7_info = {
                .has_7bits_data = true,
                .has_wakeup = true,
                .has_fifo = true,
+               .fifosize = 16,
        }
 };
 
@@ -108,7 +112,6 @@ struct stm32_usart_info stm32h7_info = {
 #define USART_SR_RXNE          BIT(5)
 #define USART_SR_TC            BIT(6)
 #define USART_SR_TXE           BIT(7)
-#define USART_SR_LBD           BIT(8)
 #define USART_SR_CTSIF         BIT(9)
 #define USART_SR_CTS           BIT(10)         /* F7 */
 #define USART_SR_RTOF          BIT(11)         /* F7 */
@@ -120,8 +123,7 @@ struct stm32_usart_info stm32h7_info = {
 #define USART_SR_SBKF          BIT(18)         /* F7 */
 #define USART_SR_WUF           BIT(20)         /* H7 */
 #define USART_SR_TEACK         BIT(21)         /* F7 */
-#define USART_SR_ERR_MASK      (USART_SR_LBD | USART_SR_ORE | \
-                                USART_SR_FE | USART_SR_PE)
+#define USART_SR_ERR_MASK      (USART_SR_ORE | USART_SR_FE | USART_SR_PE)
 /* Dummy bits */
 #define USART_SR_DUMMY_RX      BIT(16)
 
@@ -151,8 +153,7 @@ struct stm32_usart_info stm32h7_info = {
 #define USART_CR1_PS           BIT(9)
 #define USART_CR1_PCE          BIT(10)
 #define USART_CR1_WAKE         BIT(11)
-#define USART_CR1_M            BIT(12)
-#define USART_CR1_M0           BIT(12)         /* F7 */
+#define USART_CR1_M0           BIT(12)         /* F7 (CR1_M for F4) */
 #define USART_CR1_MME          BIT(13)         /* F7 */
 #define USART_CR1_CMIE         BIT(14)         /* F7 */
 #define USART_CR1_OVER8                BIT(15)
@@ -169,8 +170,6 @@ struct stm32_usart_info stm32h7_info = {
 /* USART_CR2 */
 #define USART_CR2_ADD_MASK     GENMASK(3, 0)   /* F4 */
 #define USART_CR2_ADDM7                BIT(4)          /* F7 */
-#define USART_CR2_LBDL         BIT(5)
-#define USART_CR2_LBDIE                BIT(6)
 #define USART_CR2_LBCL         BIT(8)
 #define USART_CR2_CPHA         BIT(9)
 #define USART_CR2_CPOL         BIT(10)
@@ -209,6 +208,19 @@ struct stm32_usart_info stm32h7_info = {
 #define USART_CR3_WUS_MASK     GENMASK(21, 20) /* H7 */
 #define USART_CR3_WUS_START_BIT        BIT(21)         /* H7 */
 #define USART_CR3_WUFIE                BIT(22)         /* H7 */
+#define USART_CR3_TXFTIE       BIT(23)         /* H7 */
+#define USART_CR3_TCBGTIE      BIT(24)         /* H7 */
+#define USART_CR3_RXFTCFG_MASK GENMASK(27, 25) /* H7 */
+#define USART_CR3_RXFTCFG_SHIFT        25              /* H7 */
+#define USART_CR3_RXFTIE       BIT(28)         /* H7 */
+#define USART_CR3_TXFTCFG_MASK GENMASK(31, 29) /* H7 */
+#define USART_CR3_TXFTCFG_SHIFT        29              /* H7 */
+
+/* TX FIFO threashold set to half of its depth */
+#define USART_CR3_TXFTCFG_HALF 0x2
+
+/* RX FIFO threashold set to half of its depth */
+#define USART_CR3_RXFTCFG_HALF 0x2
 
 /* USART_GTPR */
 #define USART_GTPR_PSC_MASK    GENMASK(7, 0)
@@ -227,12 +239,10 @@ struct stm32_usart_info stm32h7_info = {
 
 /* USART_ICR */
 #define USART_ICR_PECF         BIT(0)          /* F7 */
-#define USART_ICR_FFECF                BIT(1)          /* F7 */
-#define USART_ICR_NCF          BIT(2)          /* F7 */
+#define USART_ICR_FECF         BIT(1)          /* F7 */
 #define USART_ICR_ORECF                BIT(3)          /* F7 */
 #define USART_ICR_IDLECF       BIT(4)          /* F7 */
 #define USART_ICR_TCCF         BIT(6)          /* F7 */
-#define USART_ICR_LBDCF                BIT(8)          /* F7 */
 #define USART_ICR_CTSCF                BIT(9)          /* F7 */
 #define USART_ICR_RTOCF                BIT(11)         /* F7 */
 #define USART_ICR_EOBCF                BIT(12)         /* F7 */
@@ -256,11 +266,14 @@ struct stm32_port {
        struct dma_chan *tx_ch;  /* dma tx channel            */
        dma_addr_t tx_dma_buf;   /* dma tx buffer bus address */
        unsigned char *tx_buf;   /* dma tx buffer cpu address */
+       u32 cr1_irq;             /* USART_CR1_RXNEIE or RTOIE */
+       u32 cr3_irq;             /* USART_CR3_RXFTIE */
        int last_res;
        bool tx_dma_busy;        /* dma tx busy               */
        bool hw_flow_control;
        bool fifoen;
        int wakeirq;
+       int rdr_mask;           /* receive data register mask */
 };
 
 static struct stm32_port stm32_ports[STM32_MAX_PORTS];
index 605354fd60b1c5a110ecb4f4a46785a64980a211..f145946f659b424ffa5e79ec0ac3086ed6ef19c1 100644 (file)
 #include <linux/of.h>
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
+#include <linux/iopoll.h>
 
 #define CDNS_UART_TTY_NAME     "ttyPS"
 #define CDNS_UART_NAME         "xuartps"
-#define CDNS_UART_MAJOR                0       /* use dynamic node allocation */
 #define CDNS_UART_FIFO_SIZE    64      /* FIFO size */
 #define CDNS_UART_REGISTER_SPACE       0x1000
+#define TX_TIMEOUT             500000
 
 /* Rx Trigger level */
 static int rx_trigger_level = 56;
-module_param(rx_trigger_level, uint, S_IRUGO);
+static int uartps_major;
+module_param(rx_trigger_level, uint, 0444);
 MODULE_PARM_DESC(rx_trigger_level, "Rx trigger level, 1-63 bytes");
 
 /* Rx Timeout */
 static int rx_timeout = 10;
-module_param(rx_timeout, uint, S_IRUGO);
+module_param(rx_timeout, uint, 0444);
 MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255");
 
 /* Register offsets for the UART. */
@@ -199,7 +201,7 @@ struct cdns_platform_data {
        u32 quirks;
 };
 #define to_cdns_uart(_nb) container_of(_nb, struct cdns_uart, \
-               clk_rate_change_nb);
+               clk_rate_change_nb)
 
 /**
  * cdns_uart_handle_rx - Handle the received bytes along with Rx errors.
@@ -312,15 +314,16 @@ static void cdns_uart_handle_tx(void *dev_id)
        } else {
                numbytes = port->fifosize;
                while (numbytes && !uart_circ_empty(&port->state->xmit) &&
-                      !(readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_TXFULL)) {
+                      !(readl(port->membase + CDNS_UART_SR) &
+                                               CDNS_UART_SR_TXFULL)) {
                        /*
                         * Get the data from the UART circular buffer
                         * and write it to the cdns_uart's TX_FIFO
                         * register.
                         */
                        writel(
-                               port->state->xmit.buf[port->state->xmit.
-                               tail], port->membase + CDNS_UART_FIFO);
+                               port->state->xmit.buf[port->state->xmit.tail],
+                                       port->membase + CDNS_UART_FIFO);
 
                        port->icount.tx++;
 
@@ -684,18 +687,21 @@ static void cdns_uart_set_termios(struct uart_port *port,
        unsigned int cval = 0;
        unsigned int baud, minbaud, maxbaud;
        unsigned long flags;
-       unsigned int ctrl_reg, mode_reg;
-
-       spin_lock_irqsave(&port->lock, flags);
+       unsigned int ctrl_reg, mode_reg, val;
+       int err;
 
        /* Wait for the transmit FIFO to empty before making changes */
        if (!(readl(port->membase + CDNS_UART_CR) &
                                CDNS_UART_CR_TX_DIS)) {
-               while (!(readl(port->membase + CDNS_UART_SR) &
-                               CDNS_UART_SR_TXEMPTY)) {
-                       cpu_relax();
+               err = readl_poll_timeout(port->membase + CDNS_UART_SR,
+                                        val, (val & CDNS_UART_SR_TXEMPTY),
+                                        1000, TX_TIMEOUT);
+               if (err) {
+                       dev_err(port->dev, "timed out waiting for tx empty");
+                       return;
                }
        }
+       spin_lock_irqsave(&port->lock, flags);
 
        /* Disable the TX and RX to set baud rate */
        ctrl_reg = readl(port->membase + CDNS_UART_CR);
@@ -1073,8 +1079,6 @@ static void cdns_uart_poll_put_char(struct uart_port *port, unsigned char c)
                cpu_relax();
 
        spin_unlock_irqrestore(&port->lock, flags);
-
-       return;
 }
 #endif
 
@@ -1517,7 +1521,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
        cdns_uart_uart_driver->owner = THIS_MODULE;
        cdns_uart_uart_driver->driver_name = driver_name;
        cdns_uart_uart_driver->dev_name = CDNS_UART_TTY_NAME;
-       cdns_uart_uart_driver->major = CDNS_UART_MAJOR;
+       cdns_uart_uart_driver->major = uartps_major;
        cdns_uart_uart_driver->minor = cdns_uart_data->id;
        cdns_uart_uart_driver->nr = 1;
 
@@ -1546,6 +1550,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
                goto err_out_id;
        }
 
+       uartps_major = cdns_uart_uart_driver->tty_driver->major;
        cdns_uart_data->cdns_uart_driver = cdns_uart_uart_driver;
 
        /*
index 033ac7e6a70dbfe1fc28e71ab03cf17d43b45b88..566728fbaf3cd4717af9da3380c389592f67ab61 100644 (file)
@@ -1837,7 +1837,7 @@ static struct tty_struct *tty_open_current_tty(dev_t device, struct file *filp)
 static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp,
                int *index)
 {
-       struct tty_driver *driver;
+       struct tty_driver *driver = NULL;
 
        switch (device) {
 #ifdef CONFIG_VT
@@ -1858,6 +1858,8 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp,
                                break;
                        }
                }
+               if (driver)
+                       tty_driver_kref_put(driver);
                return ERR_PTR(-ENODEV);
        }
        default:
index 4471cf96ef6990588364973506101023a6326b02..47e5679b48e15fc14cdd8843d24d3915c6273c3b 100644 (file)
 
 extern void mv64340_irq_init(unsigned int base);
 
-/* MPSC Platform Device, Driver Data (Shared register regions) */
-#define        MPSC_SHARED_NAME                "mpsc_shared"
-
-#define        MPSC_ROUTING_BASE_ORDER         0
-#define        MPSC_SDMA_INTR_BASE_ORDER       1
-
-#define MPSC_ROUTING_REG_BLOCK_SIZE    0x000c
-#define MPSC_SDMA_INTR_REG_BLOCK_SIZE  0x0084
-
-struct mpsc_shared_pdata {
-       u32     mrr_val;
-       u32     rcrr_val;
-       u32     tcrr_val;
-       u32     intr_cause_val;
-       u32     intr_mask_val;
-};
-
-/* MPSC Platform Device, Driver Data */
-#define        MPSC_CTLR_NAME                  "mpsc"
-
-#define        MPSC_BASE_ORDER                 0
-#define        MPSC_SDMA_BASE_ORDER            1
-#define        MPSC_BRG_BASE_ORDER             2
-
-#define MPSC_REG_BLOCK_SIZE            0x0038
-#define MPSC_SDMA_REG_BLOCK_SIZE       0x0c18
-#define MPSC_BRG_REG_BLOCK_SIZE                0x0008
-
-struct mpsc_pdata {
-       u8      mirror_regs;
-       u8      cache_mgmt;
-       u8      max_idle;
-       int     default_baud;
-       int     default_bits;
-       int     default_parity;
-       int     default_flow;
-       u32     chr_1_val;
-       u32     chr_2_val;
-       u32     chr_10_val;
-       u32     mpcr_val;
-       u32     bcr_val;
-       u8      brg_can_tune;
-       u8      brg_clk_src;
-       u32     brg_clk_freq;
-};
-
 /* Watchdog Platform Device, Driver Data */
 #define        MV64x60_WDT_NAME                        "mv64x60_wdt"
 
index 5e0b59422a68fdc48b9697a408aa578122e41633..bb2bc99388caeea596ee78f59fd3ab44772fa139 100644 (file)
@@ -110,6 +110,7 @@ struct uart_8250_port {
                                                 *   if no_console_suspend
                                                 */
        unsigned char           probe;
+       struct mctrl_gpios      *gpios;
 #define UART_PROBE_RSA (1 << 0)
 
        /*
index 67c4aaaa2308d3a9ffcfe38eb62b79877b516e71..5642c05e0da04ca37752aaa5e66e207b22f78af7 100644 (file)
 /* Motorola i.MX SoC */
 #define PORT_IMX       62
 
-/* Marvell MPSC */
+/* Marvell MPSC (obsolete unused) */
 #define PORT_MPSC      63
 
 /* TXX9 type number */