This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 9bb1226b04e14524acbb73797f38a9a825a6361c
Author: David Sidrane <david.sidr...@nscdg.com>
AuthorDate: Fri Dec 9 05:15:02 2022 -0800

    s32k1xx:serial Add EDMA
---
 arch/arm/src/s32k1xx/Kconfig          |   16 +
 arch/arm/src/s32k1xx/s32k1xx_serial.c | 1071 ++++++++++++++++++++++++++++-----
 arch/arm/src/s32k1xx/s32k1xx_serial.h |  109 ++++
 3 files changed, 1045 insertions(+), 151 deletions(-)

diff --git a/arch/arm/src/s32k1xx/Kconfig b/arch/arm/src/s32k1xx/Kconfig
index 5da747b11b..1794c90a92 100644
--- a/arch/arm/src/s32k1xx/Kconfig
+++ b/arch/arm/src/s32k1xx/Kconfig
@@ -772,6 +772,22 @@ config LPI2C1_SLAVE_BUS
 endmenu # LPI2C1 Slave Configuration
 endmenu # LPI2C Configuration
 
+menu "LPUART Configuration"
+comment "LP Uart Driver Configuration"
+
+
+config S32K1XX_LPUART_RXDMA_BUFFER_SIZE
+       int "Rx DMA buffer size"
+       default 64
+       depends on LPUART0_RXDMA || LPUART1_RXDMA || LPUART2_RXDMA
+       ---help---
+               The DMA buffer size when using RX DMA to emulate a FIFO.
+
+               When streaming data, the generic serial layer will be called
+               every time the FIFO receives half this number of bytes.
+
+endmenu # LPUART Configuration
+
 menu "Ethernet Configuration"
        depends on S32K1XX_ENET
 
diff --git a/arch/arm/src/s32k1xx/s32k1xx_serial.c 
b/arch/arm/src/s32k1xx/s32k1xx_serial.c
index e113182b28..1a11a984c3 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_serial.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_serial.c
@@ -50,10 +50,13 @@
 #include "chip.h"
 #include "arm_internal.h"
 #include "hardware/s32k1xx_lpuart.h"
+#include "s32k1xx_edma.h"
+#include "hardware/s32k1xx_dmamux.h"
 #include "hardware/s32k1xx_pinmux.h"
 #include "s32k1xx_config.h"
 #include "s32k1xx_pin.h"
 #include "s32k1xx_lowputc.h"
+#include "s32k1xx_serial.h"
 
 #include "s32k1xx_periphclocks.h"
 
@@ -71,27 +74,45 @@
 /* First pick the console and ttys0.  This could be any of LPUART0-2 */
 
 #if defined(CONFIG_LPUART0_SERIAL_CONSOLE)
-#  define CONSOLE_DEV         g_uart0port /* LPUART0 is console */
-#  define TTYS0_DEV           g_uart0port /* LPUART0 is ttyS0 */
+#  define CONSOLE_DEV         g_lpuart0priv /* LPUART0 is console */
+#  define TTYS0_DEV           g_lpuart0priv /* LPUART0 is ttyS0 */
 #  define UART1_ASSIGNED      1
+#  if defined(CONFIG_LPUART0_RXDMA)
+#    define SERIAL_HAVE_CONSOLE_RXDMA 1
+#  endif
+#  if defined(CONFIG_LPUART0_TXDMA)
+#    define SERIAL_HAVE_CONSOLE_TXDMA 1
+#  endif
 #elif defined(CONFIG_LPUART1_SERIAL_CONSOLE)
-#  define CONSOLE_DEV         g_uart1port /* LPUART1 is console */
-#  define TTYS0_DEV           g_uart1port /* LPUART1 is ttyS0 */
+#  define CONSOLE_DEV         g_lpuart1priv /* LPUART1 is console */
+#  define TTYS0_DEV           g_lpuart1priv /* LPUART1 is ttyS0 */
 #  define UART2_ASSIGNED      1
+#  if defined(CONFIG_LPUART1_RXDMA)
+#    define SERIAL_HAVE_CONSOLE_RXDMA 1
+#  endif
+#  if defined(CONFIG_LPUART1_TXDMA)
+#    define SERIAL_HAVE_CONSOLE_TXDMA 1
+#  endif
 #elif defined(CONFIG_LPUART2_SERIAL_CONSOLE)
-#  define CONSOLE_DEV         g_uart2port /* LPUART2 is console */
-#  define TTYS0_DEV           g_uart2port /* LPUART2 is ttyS0 */
-#  define UART3_ASSIGNED      1
+#  define CONSOLE_DEV         g_lpuart2priv /* LPUART2 is console */
+#  define TTYS0_DEV           g_lpuart2priv /* LPUART2 is ttyS0 */
+#  define UART2_ASSIGNED      1
+#  if defined(CONFIG_LPUART2_RXDMA)
+#    define SERIAL_HAVE_CONSOLE_RXDMA 1
+#  endif
+#  if defined(CONFIG_LPUART2_TXDMA)
+#    define SERIAL_HAVE_CONSOLE_TXDMA 1
+#  endif
 #else
 #  undef CONSOLE_DEV                      /* No console */
 #  if defined(CONFIG_S32K1XX_LPUART0)
-#    define TTYS0_DEV         g_uart0port /* LPUART0 is ttyS0 */
+#    define TTYS0_DEV         g_lpuart0priv /* LPUART0 is ttyS0 */
 #    define UART1_ASSIGNED    1
 #  elif defined(CONFIG_S32K1XX_LPUART1)
-#    define TTYS0_DEV         g_uart1port /* LPUART1 is ttyS0 */
+#    define TTYS0_DEV         g_lpuart1priv /* LPUART1 is ttyS0 */
 #    define UART2_ASSIGNED    1
 #  elif defined(CONFIG_S32K1XX_LPUART2)
-#    define TTYS0_DEV         g_uart2port /* LPUART2 is ttyS0 */
+#    define TTYS0_DEV         g_lpuart2priv /* LPUART2 is ttyS0 */
 #    define UART3_ASSIGNED    1
 #  endif
 #endif
@@ -102,26 +123,30 @@
  */
 
 #if defined(CONFIG_S32K1XX_LPUART0) && !defined(UART1_ASSIGNED)
-#  define TTYS1_DEV           g_uart0port /* LPUART0 is ttyS1 */
+#  define TTYS1_DEV           g_lpuart0priv /* LPUART0 is ttyS1 */
 #  define UART1_ASSIGNED      1
 #elif defined(CONFIG_S32K1XX_LPUART1) && !defined(UART2_ASSIGNED)
-#  define TTYS1_DEV           g_uart1port /* LPUART1 is ttyS1 */
+#  define TTYS1_DEV           g_lpuart1priv /* LPUART1 is ttyS1 */
 #  define UART2_ASSIGNED      1
 #elif defined(CONFIG_S32K1XX_LPUART2) && !defined(UART3_ASSIGNED)
-#  define TTYS1_DEV           g_uart2port /* LPUART2 is ttyS1 */
+#  define TTYS1_DEV           g_lpuart2priv /* LPUART2 is ttyS1 */
 #  define UART3_ASSIGNED      1
 #endif
 
+#if defined(SERIAL_HAVE_CONSOLE_RXDMA) || defined(SERIAL_HAVE_CONSOLE_TXDMA)
+#  define SERIAL_HAVE_CONSOLE_DMA
+#endif
+
 /* Pick ttys2.  This could be one of LPUART0-2. It can't be LPUART0 because
  * that was either assigned as ttyS0 or ttys1.  One of LPUART0-2 could be the
  * console.  One of UART1-2 has already been assigned to ttys0 or ttyS1.
  */
 
 #if defined(CONFIG_S32K1XX_LPUART1) && !defined(UART2_ASSIGNED)
-#  define TTYS2_DEV           g_uart1port /* LPUART1 is ttyS2 */
+#  define TTYS2_DEV           g_lpuart1priv /* LPUART1 is ttyS2 */
 #  define UART2_ASSIGNED      1
 #elif defined(CONFIG_S32K1XX_LPUART2) && !defined(UART3_ASSIGNED)
-#  define TTYS2_DEV           g_uart2port /* LPUART2 is ttyS2 */
+#  define TTYS2_DEV           g_lpuart2priv /* LPUART2 is ttyS2 */
 #  define UART3_ASSIGNED      1
 #endif
 
@@ -140,12 +165,20 @@
 #if defined(CONFIG_PM_SERIAL2_STANDBY) || defined(CONFIG_PM_SERIAL2_SLEEP)
 #   define CONFIG_PM_SERIAL2
 #endif
+
+#if !defined(CONFIG_S32K1XX_SERIAL_RXDMA_BUFFER_SIZE)
+#  define CONFIG_S32K1XX_SERIAL_RXDMA_BUFFER_SIZE 32
+#endif
+
+#define RXDMA_BUFFER_SIZE   CONFIG_S32K1XX_SERIAL_RXDMA_BUFFER_SIZE
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
 
 struct s32k1xx_uart_s
 {
+  struct uart_dev_s dev;    /* Generic UART device */
   uint32_t uartbase;        /* Base address of UART registers */
   uint32_t baud;            /* Configured baud */
   uint32_t ie;              /* Saved enabled interrupts */
@@ -169,6 +202,23 @@ struct s32k1xx_uart_s
 #endif
 #ifdef CONFIG_SERIAL_RS485CONTROL
   uint8_t rs485mode:1;      /* We are in RS485 (RTS on TX) mode */
+#endif
+  /* TX DMA state */
+
+#ifdef SERIAL_HAVE_TXDMA
+  const unsigned int dma_txreqsrc;  /* DMAMUX source of TX DMA request */
+  DMACH_HANDLE       txdma;         /* currently-open trasnmit DMA stream */
+  sem_t              txdmasem;      /* Indicate TX DMA completion */
+#endif
+
+  /* RX DMA state */
+
+#ifdef SERIAL_HAVE_RXDMA
+  const unsigned int dma_rxreqsrc;  /* DMAMUX source of RX DMA request */
+  DMACH_HANDLE       rxdma;         /* currently-open receive DMA stream */
+  bool               rxenable;      /* DMA-based reception en/disable */
+  uint32_t           rxdmanext;     /* Next byte in the DMA buffer to be read 
*/
+  char *const        rxfifo;        /* Receive DMA buffer */
 #endif
 };
 
@@ -191,12 +241,44 @@ static int  s32k1xx_attach(struct uart_dev_s *dev);
 static void s32k1xx_detach(struct uart_dev_s *dev);
 static int  s32k1xx_interrupt(int irq, void *context, void *arg);
 static int  s32k1xx_ioctl(struct file *filep, int cmd, unsigned long arg);
+#if !defined(SERIAL_HAVE_ONLY_RXDMA)
 static int  s32k1xx_receive(struct uart_dev_s *dev, unsigned int *status);
 static void s32k1xx_rxint(struct uart_dev_s *dev, bool enable);
 static bool s32k1xx_rxavailable(struct uart_dev_s *dev);
-static void s32k1xx_send(struct uart_dev_s *dev, int ch);
+#endif
+#if !defined(SERIAL_HAVE_ONLY_TXDMA)
 static void s32k1xx_txint(struct uart_dev_s *dev, bool enable);
+#endif
+
+static void s32k1xx_send(struct uart_dev_s *dev, int ch);
+
 static bool s32k1xx_txready(struct uart_dev_s *dev);
+#ifdef SERIAL_HAVE_TXDMA
+static void s32k1xx_dma_send(struct uart_dev_s *dev);
+static void s32k1xx_dma_txint(struct uart_dev_s *dev, bool enable);
+static void s32k1xx_dma_txavailable(struct uart_dev_s *dev);
+static void s32k1xx_dma_txcallback(DMACH_HANDLE handle, void *arg, bool done,
+                                  int result);
+#endif
+
+#if defined(SERIAL_HAVE_RXDMA) || defined(SERIAL_HAVE_TXDMA)
+static int  s32k1xx_dma_setup(struct uart_dev_s *dev);
+static void s32k1xx_dma_shutdown(struct uart_dev_s *dev);
+#endif
+
+#ifdef SERIAL_HAVE_RXDMA
+static int  s32k1xx_dma_receive(struct uart_dev_s *dev,
+                                unsigned int *status);
+#ifdef CONFIG_PM
+static void s32k1xx_dma_reenable(struct s32k1xx_uart_s *priv);
+#endif
+static void s32k1xx_dma_rxint(struct uart_dev_s *dev, bool enable);
+static bool s32k1xx_dma_rxavailable(struct uart_dev_s *dev);
+
+static void s32k1xx_dma_rxcallback(DMACH_HANDLE handle, void *arg, bool done,
+                                  int result);
+#endif
+
 static bool s32k1xx_txempty(struct uart_dev_s *dev);
 
 #ifdef CONFIG_PM
@@ -212,7 +294,8 @@ static int  up_pm_prepare(struct pm_callback_s *cb, int 
domain,
 
 /* Serial driver UART operations */
 
-static const struct uart_ops_s g_uart_ops =
+#if !defined(SERIAL_HAVE_ONLY_TXDMA) && !defined(SERIAL_HAVE_ONLY_RXDMA)
+static const struct uart_ops_s g_lpuart_ops =
 {
   .setup          = s32k1xx_setup,
   .shutdown       = s32k1xx_shutdown,
@@ -230,167 +313,291 @@ static const struct uart_ops_s g_uart_ops =
   .txready        = s32k1xx_txready,
   .txempty        = s32k1xx_txempty,
 };
+#endif
+
+#if defined(SERIAL_HAVE_RXDMA) && defined(SERIAL_HAVE_TXDMA)
+static const struct uart_ops_s g_lpuart_rxtxdma_ops =
+{
+  .setup          = s32k1xx_dma_setup,
+  .shutdown       = s32k1xx_dma_shutdown,
+  .attach         = s32k1xx_attach,
+  .detach         = s32k1xx_detach,
+  .ioctl          = s32k1xx_ioctl,
+  .receive        = s32k1xx_dma_receive,
+  .rxint          = s32k1xx_dma_rxint,
+  .rxavailable    = s32k1xx_dma_rxavailable,
+  .send           = s32k1xx_send,
+  .txint          = s32k1xx_dma_txint,
+  .txready        = s32k1xx_txready,
+  .txempty        = s32k1xx_txempty,
+  .dmatxavail     = s32k1xx_dma_txavailable,
+  .dmasend        = s32k1xx_dma_send,
+};
+#endif
+#if !defined(SERIAL_HAVE_ONLY_DMA) && defined(SERIAL_HAVE_RXDMA)
+static const struct uart_ops_s g_lpuart_rxdma_ops =
+{
+  .setup          = s32k1xx_dma_setup,
+  .shutdown       = s32k1xx_dma_shutdown,
+  .attach         = s32k1xx_attach,
+  .detach         = s32k1xx_detach,
+  .ioctl          = s32k1xx_ioctl,
+  .receive        = s32k1xx_dma_receive,
+  .rxint          = s32k1xx_dma_rxint,
+  .rxavailable    = s32k1xx_dma_rxavailable,
+  .send           = s32k1xx_send,
+  .txint          = s32k1xx_txint,
+  .txready        = s32k1xx_txready,
+  .txempty        = s32k1xx_txempty,
+};
+#endif
+
+#if !defined(SERIAL_HAVE_ONLY_DMA) && defined(SERIAL_HAVE_TXDMA)
+static const struct uart_ops_s g_lpuart_txdma_ops =
+{
+    .setup          = s32k1xx_dma_setup,
+    .shutdown       = s32k1xx_dma_shutdown,
+    .attach         = s32k1xx_attach,
+    .detach         = s32k1xx_detach,
+    .ioctl          = s32k1xx_ioctl,
+    .receive        = s32k1xx_receive,
+    .rxint          = s32k1xx_rxint,
+    .rxavailable    = s32k1xx_rxavailable,
+    .send           = s32k1xx_send,
+    .txint          = s32k1xx_dma_txint,
+    .txready        = s32k1xx_txready,
+    .txempty        = s32k1xx_txempty,
+    .dmatxavail     = s32k1xx_dma_txavailable,
+    .dmasend        = s32k1xx_dma_send,
+};
+#endif
+
+/* Avoid unused warning */
+#if !defined(SERIAL_HAVE_ONLY_DMA) && defined(SERIAL_HAVE_RXDMA)
+const struct uart_ops_s *g_o0 = &g_lpuart_rxdma_ops;
+#endif
+#if !defined(SERIAL_HAVE_ONLY_DMA) && defined(SERIAL_HAVE_TXDMA)
+const struct uart_ops_s *g_o1 = &g_lpuart_txdma_ops;
+#endif
+
+/* I/O buffers */
+
+#ifdef CONFIG_LPUART0_RXDMA
+static char g_lpuart0rxfifo[RXDMA_BUFFER_SIZE];
+#endif
+
+# ifdef CONFIG_LPUART1_RXDMA
+static char g_lpuart1rxfifo[RXDMA_BUFFER_SIZE];
+#endif
+
+#ifdef CONFIG_LPUART2_RXDMA
+static char g_lpuart2rxfifo[RXDMA_BUFFER_SIZE];
+#endif
 
 /* I/O buffers */
 
 #ifdef CONFIG_S32K1XX_LPUART0
-static char g_uart0rxbuffer[CONFIG_LPUART0_RXBUFSIZE];
-static char g_uart0txbuffer[CONFIG_LPUART0_TXBUFSIZE];
+static char g_lpuart0rxbuffer[CONFIG_LPUART0_RXBUFSIZE];
+static char g_lpuart0txbuffer[CONFIG_LPUART0_TXBUFSIZE];
 #endif
 
 #ifdef CONFIG_S32K1XX_LPUART1
-static char g_uart1rxbuffer[CONFIG_LPUART1_RXBUFSIZE];
-static char g_uart1txbuffer[CONFIG_LPUART1_TXBUFSIZE];
+static char g_lpuart1rxbuffer[CONFIG_LPUART1_RXBUFSIZE];
+static char g_lpuart1txbuffer[CONFIG_LPUART1_TXBUFSIZE];
 #endif
 
 #ifdef CONFIG_S32K1XX_LPUART2
-static char g_uart2rxbuffer[CONFIG_LPUART2_RXBUFSIZE];
-static char g_uart2txbuffer[CONFIG_LPUART2_TXBUFSIZE];
+static char g_lpuart2rxbuffer[CONFIG_LPUART2_RXBUFSIZE];
+static char g_lpuart2txbuffer[CONFIG_LPUART2_TXBUFSIZE];
 #endif
 
 /* This describes the state of the S32K1XX lpuart0 port. */
 
 #ifdef CONFIG_S32K1XX_LPUART0
-static struct s32k1xx_uart_s g_uart0priv =
+static struct s32k1xx_uart_s g_lpuart0priv =
 {
+  .dev =
+    {
+      .recv         =
+      {
+        .size       = CONFIG_LPUART0_RXBUFSIZE,
+        .buffer     = g_lpuart0rxbuffer,
+      },
+      .xmit         =
+      {
+        .size       = CONFIG_LPUART0_TXBUFSIZE,
+        .buffer     = g_lpuart0txbuffer,
+      },
+#  if defined(CONFIG_LPUART1_RXDMA) && defined(CONFIG_LPUART1_TXDMA)
+        .ops       = &g_lpuart_rxtxdma_ops,
+#  elif defined(CONFIG_LPUART1_RXDMA) && !defined(CONFIG_LPUART1_TXDMA)
+        .ops       = &g_lpuart_rxdma_ops,
+#  elif !defined(CONFIG_LPUART1_RXDMA) && defined(CONFIG_LPUART1_TXDMA)
+        .ops       = &g_lpuart_txdma_ops,
+#  else
+        .ops       = &g_lpuart_ops,
+#  endif
+        .priv         = &g_lpuart0priv,
+      },
   .uartbase     = S32K1XX_LPUART0_BASE,
   .baud         = CONFIG_LPUART0_BAUD,
   .irq          = S32K1XX_IRQ_LPUART0,
   .parity       = CONFIG_LPUART0_PARITY,
   .bits         = CONFIG_LPUART0_BITS,
   .stopbits2    = CONFIG_LPUART0_2STOP,
-#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART0_OFLOWCONTROL)
+#  if defined(CONFIG_SERIAL_OFLOWCONTROL) && 
defined(CONFIG_LPUART0_OFLOWCONTROL)
   .oflow        = 1,
   .cts_gpio     = GPIO_LPUART0_CTS,
-#endif
-#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART0_IFLOWCONTROL)
+#  endif
+#  if defined(CONFIG_SERIAL_IFLOWCONTROL) && 
defined(CONFIG_LPUART0_IFLOWCONTROL)
   .iflow        = 1,
-#endif
-# if ((defined(CONFIG_SERIAL_RS485CONTROL) && 
defined(CONFIG_LPUART0_RS485RTSCONTROL)) \
+#  endif
+#  if ((defined(CONFIG_SERIAL_RS485CONTROL) && 
defined(CONFIG_LPUART0_RS485RTSCONTROL)) \
    || (defined(CONFIG_SERIAL_IFLOWCONTROL) && 
defined(CONFIG_LPUART0_IFLOWCONTROL)))
   .rts_gpio     = GPIO_LPUART0_RTS,
-#endif
+#  endif
 
-#if (((defined(CONFIG_SERIAL_RS485CONTROL) || 
defined(CONFIG_SERIAL_IFLOWCONTROL))) \
+#  if (((defined(CONFIG_SERIAL_RS485CONTROL) || 
defined(CONFIG_SERIAL_IFLOWCONTROL))) \
     && defined(CONFIG_LPUART0_INVERTIFLOWCONTROL))
   .inviflow     = 1,
-#endif
+#  endif
 
-#if defined(CONFIG_SERIAL_RS485CONTROL) && 
defined(CONFIG_LPUART0_RS485RTSCONTROL)
+#  if defined(CONFIG_SERIAL_RS485CONTROL) && 
defined(CONFIG_LPUART0_RS485RTSCONTROL)
   .rs485mode    = 1,
-#endif
-};
-
-static struct uart_dev_s g_uart0port =
-{
-  .recv         =
-  {
-    .size       = CONFIG_LPUART0_RXBUFSIZE,
-    .buffer     = g_uart0rxbuffer,
-  },
-  .xmit         =
-  {
-    .size       = CONFIG_LPUART0_TXBUFSIZE,
-    .buffer     = g_uart0txbuffer,
-  },
-  .ops          = &g_uart_ops,
-  .priv         = &g_uart0priv,
+#  endif
+#  ifdef CONFIG_LPUART0_TXDMA
+  .dma_txreqsrc = S32K1XX_DMACHAN_LPUART0_TX,
+#  endif
+#  ifdef CONFIG_LPUART0_RXDMA
+  .dma_rxreqsrc = S32K1XX_DMACHAN_LPUART0_RX,
+  .rxfifo        = g_lpuart0rxfifo,
+#  endif
 };
 #endif
 
 /* This describes the state of the S32K1XX lpuart1 port. */
 
 #ifdef CONFIG_S32K1XX_LPUART1
-static struct s32k1xx_uart_s g_uart1priv =
+static struct s32k1xx_uart_s g_lpuart1priv =
 {
+  .dev =
+    {
+      .recv         =
+      {
+        .size       = CONFIG_LPUART1_RXBUFSIZE,
+        .buffer     = g_lpuart1rxbuffer,
+      },
+      .xmit         =
+      {
+        .size       = CONFIG_LPUART1_TXBUFSIZE,
+        .buffer     = g_lpuart1txbuffer,
+      },
+#    if defined(CONFIG_LPUART1_RXDMA) && defined(CONFIG_LPUART1_TXDMA)
+          .ops       = &g_lpuart_rxtxdma_ops,
+#    elif defined(CONFIG_LPUART1_RXDMA) && !defined(CONFIG_LPUART1_TXDMA)
+          .ops       = &g_lpuart_rxdma_ops,
+#    elif !defined(CONFIG_LPUART1_RXDMA) && defined(CONFIG_LPUART1_TXDMA)
+          .ops       = &g_lpuart_txdma_ops,
+#    else
+          .ops       = &g_lpuart_ops,
+#    endif
+          .priv           = &g_lpuart1priv,
+  },
+
   .uartbase     = S32K1XX_LPUART1_BASE,
   .baud         = CONFIG_LPUART1_BAUD,
   .irq          = S32K1XX_IRQ_LPUART1,
   .parity       = CONFIG_LPUART1_PARITY,
   .bits         = CONFIG_LPUART1_BITS,
   .stopbits2    = CONFIG_LPUART1_2STOP,
-#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART1_OFLOWCONTROL)
+#  if defined(CONFIG_SERIAL_OFLOWCONTROL) && 
defined(CONFIG_LPUART1_OFLOWCONTROL)
   .oflow        = 1,
   .cts_gpio     = GPIO_LPUART1_CTS,
-#endif
-#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART1_IFLOWCONTROL)
+#  endif
+#  if defined(CONFIG_SERIAL_IFLOWCONTROL) && 
defined(CONFIG_LPUART1_IFLOWCONTROL)
   .iflow        = 1,
-#endif
-# if ((defined(CONFIG_SERIAL_RS485CONTROL) && 
defined(CONFIG_LPUART1_RS485RTSCONTROL)) \
+#  endif
+#  if ((defined(CONFIG_SERIAL_RS485CONTROL) && 
defined(CONFIG_LPUART1_RS485RTSCONTROL)) \
    || (defined(CONFIG_SERIAL_IFLOWCONTROL) && 
defined(CONFIG_LPUART1_IFLOWCONTROL)))
   .rts_gpio     = GPIO_LPUART1_RTS,
-#endif
-#if (((defined(CONFIG_SERIAL_RS485CONTROL) || 
defined(CONFIG_SERIAL_IFLOWCONTROL))) \
+#  endif
+#  if (((defined(CONFIG_SERIAL_RS485CONTROL) || 
defined(CONFIG_SERIAL_IFLOWCONTROL))) \
     && defined(CONFIG_LPUART1_INVERTIFLOWCONTROL))
   .inviflow     = 1,
-#endif
+#  endif
 
-#if defined(CONFIG_SERIAL_RS485CONTROL) && 
defined(CONFIG_LPUART1_RS485RTSCONTROL)
+#  if defined(CONFIG_SERIAL_RS485CONTROL) && 
defined(CONFIG_LPUART1_RS485RTSCONTROL)
   .rs485mode    = 1,
-#endif
-};
-
-static struct uart_dev_s g_uart1port =
-{
-  .recv           =
-    {
-      .size       = CONFIG_LPUART1_RXBUFSIZE,
-      .buffer     = g_uart1rxbuffer,
-    },
-  .xmit           =
-    {
-      .size       = CONFIG_LPUART1_TXBUFSIZE,
-      .buffer     = g_uart1txbuffer,
-    },
-  .ops            = &g_uart_ops,
-  .priv           = &g_uart1priv,
+#  endif
+#  ifdef CONFIG_LPUART1_TXDMA
+  .dma_txreqsrc = S32K1XX_DMACHAN_LPUART1_TX,
+#  endif
+#  ifdef CONFIG_LPUART1_RXDMA
+  .dma_rxreqsrc = S32K1XX_DMACHAN_LPUART1_RX,
+  .rxfifo        = g_lpuart1rxfifo,
+#  endif
 };
 #endif
 
 #ifdef CONFIG_S32K1XX_LPUART2
-static struct s32k1xx_uart_s g_uart2priv =
+static struct s32k1xx_uart_s g_lpuart2priv =
 {
+  .dev =
+    {
+      .recv         =
+      {
+        .size       = CONFIG_LPUART2_RXBUFSIZE,
+        .buffer     = g_lpuart2rxbuffer,
+      },
+      .xmit         =
+      {
+        .size       = CONFIG_LPUART2_TXBUFSIZE,
+        .buffer     = g_lpuart2txbuffer,
+      },
+#  if defined(CONFIG_LPUART1_RXDMA) && defined(CONFIG_LPUART1_TXDMA)
+        .ops       = &g_lpuart_rxtxdma_ops,
+#  elif defined(CONFIG_LPUART1_RXDMA) && !defined(CONFIG_LPUART1_TXDMA)
+        .ops       = &g_lpuart_rxdma_ops,
+#  elif !defined(CONFIG_LPUART1_RXDMA) && defined(CONFIG_LPUART1_TXDMA)
+        .ops       = &g_lpuart_txdma_ops,
+#  else
+        .ops       = &g_lpuart_ops,
+#  endif
+        .priv           = &g_lpuart2priv,
+  },
+
   .uartbase     = S32K1XX_LPUART2_BASE,
   .baud         = CONFIG_LPUART2_BAUD,
   .irq          = S32K1XX_IRQ_LPUART2,
   .parity       = CONFIG_LPUART2_PARITY,
   .bits         = CONFIG_LPUART2_BITS,
   .stopbits2    = CONFIG_LPUART2_2STOP,
-#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART2_OFLOWCONTROL)
+#  if defined(CONFIG_SERIAL_OFLOWCONTROL) && 
defined(CONFIG_LPUART2_OFLOWCONTROL)
   .oflow        = 1,
   .cts_gpio     = GPIO_LPUART2_CTS,
-#endif
-#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART2_IFLOWCONTROL)
+#  endif
+#  if defined(CONFIG_SERIAL_IFLOWCONTROL) && 
defined(CONFIG_LPUART2_IFLOWCONTROL)
   .iflow        = 1,
-#endif
-# if ((defined(CONFIG_SERIAL_RS485CONTROL) && 
defined(CONFIG_LPUART2_RS485RTSCONTROL)) \
+#  endif
+#  if ((defined(CONFIG_SERIAL_RS485CONTROL) && 
defined(CONFIG_LPUART2_RS485RTSCONTROL)) \
    || (defined(CONFIG_SERIAL_IFLOWCONTROL) && 
defined(CONFIG_LPUART2_IFLOWCONTROL)))
   .rts_gpio     = GPIO_LPUART2_RTS,
-#endif
-#if (((defined(CONFIG_SERIAL_RS485CONTROL) || 
defined(CONFIG_SERIAL_IFLOWCONTROL))) \
+#  endif
+#  if (((defined(CONFIG_SERIAL_RS485CONTROL) || 
defined(CONFIG_SERIAL_IFLOWCONTROL))) \
     && defined(CONFIG_LPUART2_INVERTIFLOWCONTROL))
   .inviflow     = 1,
-#endif
+#  endif
 
-#if defined(CONFIG_SERIAL_RS485CONTROL) && 
defined(CONFIG_LPUART2_RS485RTSCONTROL)
+#  if defined(CONFIG_SERIAL_RS485CONTROL) && 
defined(CONFIG_LPUART2_RS485RTSCONTROL)
   .rs485mode    = 1,
-#endif
-};
-
-static struct uart_dev_s g_uart2port =
-{
-  .recv           =
-    {
-      .size       = CONFIG_LPUART2_RXBUFSIZE,
-      .buffer     = g_uart2rxbuffer,
-    },
-  .xmit           =
-    {
-      .size       = CONFIG_LPUART2_TXBUFSIZE,
-      .buffer     = g_uart2txbuffer,
-    },
-  .ops            = &g_uart_ops,
-  .priv           = &g_uart2priv,
+#  endif
+#  ifdef CONFIG_LPUART2_TXDMA
+  .dma_txreqsrc = S32K1XX_DMACHAN_LPUART2_TX,
+#  endif
+#  ifdef CONFIG_LPUART2_RXDMA
+  .dma_rxreqsrc = S32K1XX_DMACHAN_LPUART2_RX,
+  .rxfifo        = g_lpuart2rxfifo,
+# endif
 };
 #endif
 
@@ -426,6 +633,24 @@ static inline void s32k1xx_serialout(struct s32k1xx_uart_s 
*priv,
   putreg32(value, priv->uartbase + offset);
 }
 
+/****************************************************************************
+ * Name: s32k1xx_dma_nextrx
+ *
+ * Description:
+ *   Returns the index into the RX FIFO where the DMA will place the next
+ *   byte that it receives.
+ *
+ ****************************************************************************/
+
+#ifdef SERIAL_HAVE_RXDMA
+static int s32k1xx_dma_nextrx(struct s32k1xx_uart_s *priv)
+{
+  int dmaresidual = s32k1xx_dmach_getcount(priv->rxdma);
+
+  return RXDMA_BUFFER_SIZE - dmaresidual;
+}
+#endif
+
 /****************************************************************************
  * Name: s32k1xx_disableuartint
  ****************************************************************************/
@@ -473,6 +698,132 @@ static inline void s32k1xx_restoreuartint(struct 
s32k1xx_uart_s *priv,
   spin_unlock_irqrestore(NULL, flags);
 }
 
+/****************************************************************************
+ * Name: s32k1xx_dma_setup
+ *
+ * Description:
+ *   Configure the LPUART baud, bits, parity, etc. This method is called the
+ *   first time that the serial port is opened.
+ *
+ ****************************************************************************/
+
+#if defined(SERIAL_HAVE_RXDMA) || defined(SERIAL_HAVE_TXDMA)
+static int s32k1xx_dma_setup(struct uart_dev_s *dev)
+{
+  struct s32k1xx_uart_s *priv = (struct s32k1xx_uart_s *)dev;
+#if defined(SERIAL_HAVE_RXDMA)
+  struct s32k1xx_edma_xfrconfig_s config;
+#endif
+  int result;
+
+  /* Do the basic UART setup first, unless we are the console */
+
+  if (!dev->isconsole)
+    {
+      result = s32k1xx_setup(dev);
+      if (result != OK)
+        {
+          return result;
+        }
+    }
+
+#if defined(SERIAL_HAVE_TXDMA)
+  /* Acquire the Tx DMA channel.  This should always succeed. */
+
+  if (priv->dma_txreqsrc != 0)
+    {
+      if (priv->txdma == NULL)
+        {
+          priv->txdma = s32k1xx_dmach_alloc(priv->dma_txreqsrc |
+                                          DMAMUX_CHCFG_ENBL, 0);
+          if (priv->txdma == NULL)
+            {
+              return -EBUSY;
+            }
+
+          nxsem_init(&priv->txdmasem, 0, 1);
+          nxsem_set_protocol(&priv->txdmasem, SEM_PRIO_NONE);
+        }
+
+      /* Enable Tx DMA for the UART */
+
+      modifyreg32(priv->uartbase + S32K1XX_LPUART_BAUD_OFFSET,
+                  0, LPUART_BAUD_TDMAE);
+    }
+#endif
+
+#if defined(SERIAL_HAVE_RXDMA)
+  /* Acquire the Rx DMA channel.  This should always succeed. */
+
+  if (priv->dma_rxreqsrc != 0)
+    {
+      if (priv->rxdma == NULL)
+        {
+          priv->rxdma = s32k1xx_dmach_alloc(priv->dma_rxreqsrc |
+                                          DMAMUX_CHCFG_ENBL, 0);
+
+          if (priv->rxdma == NULL)
+            {
+              return -EBUSY;
+            }
+        }
+      else
+        {
+          s32k1xx_dmach_stop(priv->rxdma);
+        }
+
+      /* Configure for circular DMA reception into the RX FIFO */
+
+      config.saddr  = priv->uartbase + S32K1XX_LPUART_DATA_OFFSET;
+      config.daddr  = (uint32_t) priv->rxfifo;
+      config.soff   = 0;
+      config.doff   = 1;
+      config.iter   = RXDMA_BUFFER_SIZE;
+      config.flags  = EDMA_CONFIG_LINKTYPE_LINKNONE |
+                      EDMA_CONFIG_LOOPDEST |
+                      EDMA_CONFIG_INTHALF  |
+                      EDMA_CONFIG_INTMAJOR;
+      config.ssize  = EDMA_8BIT;
+      config.dsize  = EDMA_8BIT;
+      config.nbytes = 1;
+    #ifdef CONFIG_KINETIS_EDMA_ELINK
+      config.linkch = 0;
+    #endif
+
+      s32k1xx_dmach_xfrsetup(priv->rxdma , &config);
+
+      /* Reset our DMA shadow pointer and Rx data availability count to
+       * match the address just programmed above.
+       */
+
+      priv->rxdmanext = 0;
+
+      /* Enable receive Rx DMA for the UART */
+
+      modifyreg32(priv->uartbase + S32K1XX_LPUART_BAUD_OFFSET,
+                  0, LPUART_BAUD_RDMAE);
+
+      /* Enable itnerrupt on Idel and erros */
+
+      modifyreg32(priv->uartbase + S32K1XX_LPUART_CTRL_OFFSET, 0,
+                  LPUART_CTRL_PEIE       |
+                  LPUART_CTRL_FEIE       |
+                  LPUART_CTRL_NEIE       |
+                  LPUART_CTRL_ILIE);
+
+      /* Start the DMA channel, and arrange for callbacks at the half and
+       * full points in the FIFO.  This ensures that we have half a FIFO
+       * worth of time to claim bytes before they are overwritten.
+       */
+
+      s32k1xx_dmach_start(priv->rxdma, s32k1xx_dma_rxcallback, (void *)priv);
+    }
+#endif
+
+  return OK;
+}
+#endif
+
 /****************************************************************************
  * Name: s32k1xx_setup
  *
@@ -556,6 +907,55 @@ static void s32k1xx_shutdown(struct uart_dev_s *dev)
   s32k1xx_serialout(priv, S32K1XX_LPUART_GLOBAL_OFFSET, 0);
 }
 
+/****************************************************************************
+ * Name: s32k1xx_dma_shutdown
+ *
+ * Description:
+ *   Disable the LPUART.  This method is called when the serial
+ *   port is closed
+ *
+ ****************************************************************************/
+
+#if defined(SERIAL_HAVE_RXDMA) || defined(SERIAL_HAVE_TXDMA)
+static void s32k1xx_dma_shutdown(struct uart_dev_s *dev)
+{
+  struct s32k1xx_uart_s *priv = (struct s32k1xx_uart_s *)dev;
+
+  /* Perform the normal UART shutdown */
+
+  s32k1xx_shutdown(dev);
+
+#if defined(SERIAL_HAVE_RXDMA)
+  /* Stop the RX DMA channel */
+
+  if (priv->dma_rxreqsrc != 0)
+    {
+      s32k1xx_dmach_stop(priv->rxdma);
+
+      /* Release the RX DMA channel */
+
+      s32k1xx_dmach_free(priv->rxdma);
+      priv->rxdma = NULL;
+    }
+#endif
+
+#if defined(SERIAL_HAVE_TXDMA)
+  /* Stop the TX DMA channel */
+
+  if (priv->dma_txreqsrc != 0)
+    {
+      s32k1xx_dmach_stop(priv->txdma);
+
+      /* Release the TX DMA channel */
+
+      s32k1xx_dmach_free(priv->txdma);
+      priv->txdma = NULL;
+      nxsem_destroy(&priv->txdmasem);
+    }
+#endif
+}
+#endif
+
 /****************************************************************************
  * Name: s32k1xx_attach
  *
@@ -651,10 +1051,11 @@ static int s32k1xx_interrupt(int irq, void *context, 
void *arg)
        */
 
       usr  = s32k1xx_serialin(priv, S32K1XX_LPUART_STAT_OFFSET);
-      usr &= (LPUART_STAT_RDRF | LPUART_STAT_TC | LPUART_STAT_OR |
-              LPUART_STAT_FE);
+      usr &= (LPUART_STAT_RDRF | LPUART_STAT_TDRE | LPUART_STAT_OR |
+              LPUART_STAT_FE | LPUART_STAT_NF | LPUART_STAT_PF |
+              LPUART_STAT_IDLE);
 
-      /* Clear serial overrun and framing errors */
+      /* Clear serial overrun, parity and framing errors */
 
       if ((usr & LPUART_STAT_OR) != 0)
         {
@@ -662,12 +1063,42 @@ static int s32k1xx_interrupt(int irq, void *context, 
void *arg)
                             LPUART_STAT_OR);
         }
 
+      if ((usr & LPUART_STAT_NF) != 0)
+        {
+          s32k1xx_serialout(priv, S32K1XX_LPUART_STAT_OFFSET,
+                            LPUART_STAT_NF);
+        }
+
+      if ((usr & LPUART_STAT_PF) != 0)
+        {
+          s32k1xx_serialout(priv, S32K1XX_LPUART_STAT_OFFSET,
+                            LPUART_STAT_PF);
+        }
+
       if ((usr & LPUART_STAT_FE) != 0)
         {
           s32k1xx_serialout(priv, S32K1XX_LPUART_STAT_OFFSET,
                             LPUART_STAT_FE);
         }
 
+      if ((usr & (LPUART_STAT_FE | LPUART_STAT_PF | LPUART_STAT_NF)) != 0)
+        {
+          /* Discard data */
+
+          s32k1xx_serialin(priv, S32K1XX_LPUART_DATA_OFFSET);
+        }
+
+#ifdef SERIAL_HAVE_RXDMA
+      /* The line going to idle, deliver any fractions of RX data */
+
+      if ((usr & LPUART_STAT_IDLE) != 0)
+        {
+          s32k1xx_serialout(priv, S32K1XX_LPUART_STAT_OFFSET,
+                            LPUART_STAT_IDLE);
+          s32k1xx_dma_rxcallback(priv->rxdma, priv, false, LPUART_STAT_IDLE);
+        }
+#endif
+
       /* Handle incoming, receive bytes */
 
       if ((usr & LPUART_STAT_RDRF) != 0 &&
@@ -703,6 +1134,7 @@ static int s32k1xx_ioctl(struct file *filep, int cmd, 
unsigned long arg)
 #if defined(CONFIG_SERIAL_TIOCSERGSTRUCT) || defined(CONFIG_SERIAL_TERMIOS)
   struct inode *inode = filep->f_inode;
   struct uart_dev_s *dev   = inode->i_private;
+  irqstate_t flags;
 #endif
   int ret   = OK;
 
@@ -877,6 +1309,7 @@ static int s32k1xx_ioctl(struct file *filep, int cmd, 
unsigned long arg)
              * implement TCSADRAIN / TCSAFLUSH
              */
 
+            flags  = spin_lock_irqsave(NULL);
             s32k1xx_disableuartint(priv, &ie);
             ret = s32k1xx_setup(dev);
 
@@ -884,6 +1317,7 @@ static int s32k1xx_ioctl(struct file *filep, int cmd, 
unsigned long arg)
 
             s32k1xx_restoreuartint(priv, ie);
             priv->ie = ie;
+            spin_unlock_irqrestore(NULL, flags);
           }
       }
       break;
@@ -959,6 +1393,7 @@ static int s32k1xx_ioctl(struct file *filep, int cmd, 
unsigned long arg)
  *
  ****************************************************************************/
 
+#ifndef SERIAL_HAVE_ONLY_RXDMA
 static int s32k1xx_receive(struct uart_dev_s *dev, unsigned int *status)
 {
   struct s32k1xx_uart_s *priv = (struct s32k1xx_uart_s *)dev->priv;
@@ -968,6 +1403,7 @@ static int s32k1xx_receive(struct uart_dev_s *dev, 
unsigned int *status)
   *status = rxd >> LPUART_DATA_STATUS_SHIFT;
   return (rxd & LPUART_DATA_MASK) >> LPUART_DATA_SHIFT;
 }
+#endif
 
 /****************************************************************************
  * Name: s32k1xx_rxint
@@ -977,6 +1413,7 @@ static int s32k1xx_receive(struct uart_dev_s *dev, 
unsigned int *status)
  *
  ****************************************************************************/
 
+#ifndef SERIAL_HAVE_ONLY_RXDMA
 static void s32k1xx_rxint(struct uart_dev_s *dev, bool enable)
 {
   struct s32k1xx_uart_s *priv = (struct s32k1xx_uart_s *)dev->priv;
@@ -1003,6 +1440,7 @@ static void s32k1xx_rxint(struct uart_dev_s *dev, bool 
enable)
   s32k1xx_serialout(priv, S32K1XX_LPUART_CTRL_OFFSET, regval);
   spin_unlock_irqrestore(NULL, flags);
 }
+#endif
 
 /****************************************************************************
  * Name: s32k1xx_rxavailable
@@ -1012,6 +1450,7 @@ static void s32k1xx_rxint(struct uart_dev_s *dev, bool 
enable)
  *
  ****************************************************************************/
 
+#ifndef SERIAL_HAVE_ONLY_RXDMA
 static bool s32k1xx_rxavailable(struct uart_dev_s *dev)
 {
   struct s32k1xx_uart_s *priv = (struct s32k1xx_uart_s *)dev->priv;
@@ -1022,6 +1461,263 @@ static bool s32k1xx_rxavailable(struct uart_dev_s *dev)
   regval = s32k1xx_serialin(priv, S32K1XX_LPUART_STAT_OFFSET);
   return ((regval & LPUART_STAT_RDRF) != 0);
 }
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_dma_receive
+ *
+ * Description:
+ *   Called (usually) from the interrupt level to receive one
+ *   character from the LPUART.  Error bits associated with the
+ *   receipt are provided in the return 'status'.
+ *
+ ****************************************************************************/
+
+#ifdef SERIAL_HAVE_RXDMA
+static int s32k1xx_dma_receive(struct uart_dev_s *dev, unsigned int *status)
+{
+  struct s32k1xx_uart_s *priv = (struct s32k1xx_uart_s *)dev;
+  uint32_t nextrx = s32k1xx_dma_nextrx(priv);
+  int c = 0;
+
+  /* Check if more data is available */
+
+  if (nextrx != priv->rxdmanext)
+    {
+      /* Now read from the DMA buffer */
+
+      c = priv->rxfifo[priv->rxdmanext];
+
+      priv->rxdmanext++;
+
+      if (priv->rxdmanext == RXDMA_BUFFER_SIZE)
+        {
+          priv->rxdmanext = 0;
+        }
+    }
+
+  /* NOTE:  If no data is available, then we would return NULL which is,
+   * of course, valid binary data.  The protocol is that the upper half
+   * driver must call s32k1xx_dma_rxavailable prior to calling this
+   * function to assure that this never happens.
+   */
+
+  return c;
+}
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_dma_reenable
+ *
+ * Description:
+ *   Call to re-enable RX DMA.
+ *
+ ****************************************************************************/
+
+#if defined(SERIAL_HAVE_RXDMA) && defined(CONFIG_PM)
+static void s32k1xx_dma_reenable(struct s32k1xx_uart_s *priv)
+{
+  struct s32k1xx_edma_xfrconfig_s config;
+
+  /* Stop an reset the RX DMA */
+
+  s32k1xx_dmach_stop(priv->rxdma);
+
+  /* Configure for circular DMA reception into the RX FIFO */
+
+  config.saddr  = priv->uartbase + S32K1XX_LPUART_DATA_OFFSET;
+  config.daddr  = (uint32_t) priv->rxfifo;
+  config.soff   = 0;
+  config.doff   = 1;
+  config.iter   = RXDMA_BUFFER_SIZE;
+  config.flags  = EDMA_CONFIG_LINKTYPE_LINKNONE |
+                  EDMA_CONFIG_LOOPDEST |
+                  EDMA_CONFIG_INTHALF |
+                  EDMA_CONFIG_INTMAJOR;
+  config.ssize  = EDMA_8BIT;
+  config.dsize  = EDMA_8BIT;
+  config.nbytes = 1;
+#ifdef CONFIG_KINETIS_EDMA_ELINK
+  config.linkch = 0;
+#endif
+
+  s32k1xx_dmach_xfrsetup(priv->rxdma, &config);
+
+  /* Reset our DMA shadow pointer and Rx data availability count to match
+   * the address just programmed above.
+   */
+
+  priv->rxdmanext = 0;
+
+  /* Start the DMA channel, and arrange for callbacks at the half and
+   * full points in the FIFO.  This ensures that we have half a FIFO
+   * worth of time to claim bytes before they are overwritten.
+   */
+
+  s32k1xx_dmach_start(priv->rxdma, s32k1xx_dma_rxcallback, (void *)priv);
+
+  /* Clear DMA suspended flag. */
+
+  priv->rxdmasusp  = false;
+}
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_dma_rxint
+ *
+ * Description:
+ *   Call to enable or disable RX interrupts
+ *
+ ****************************************************************************/
+
+#ifdef SERIAL_HAVE_RXDMA
+static void s32k1xx_dma_rxint(struct uart_dev_s *dev, bool enable)
+{
+  struct s32k1xx_uart_s *priv = (struct s32k1xx_uart_s *)dev;
+
+  /* Enable/disable DMA reception.
+   *
+   * Note that it is not safe to check for available bytes and immediately
+   * pass them to uart_recvchars as that could potentially recurse back
+   * to us again.  Instead, bytes must wait until the next up_dma_poll or
+   * DMA event.
+   */
+
+  priv->rxenable = enable;
+}
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_dma_rxavailable
+ *
+ * Description:
+ *   Return true if the receive register is not empty
+ *
+ ****************************************************************************/
+
+#ifdef SERIAL_HAVE_RXDMA
+static bool s32k1xx_dma_rxavailable(struct uart_dev_s *dev)
+{
+  struct s32k1xx_uart_s *priv = (struct s32k1xx_uart_s *)dev;
+
+  /* Compare our receive pointer to the current DMA pointer, if they
+   * do not match, then there are bytes to be received.
+   */
+
+  return (s32k1xx_dma_nextrx(priv) != priv->rxdmanext);
+}
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_dma_txcallback
+ *
+ * Description:
+ *   This function clears dma buffer at complete of DMA transfer and wakes up
+ *   threads waiting for space in buffer.
+ *
+ ****************************************************************************/
+
+#ifdef SERIAL_HAVE_TXDMA
+static void s32k1xx_dma_txcallback(DMACH_HANDLE handle, void *arg, bool done,
+                                  int result)
+{
+  struct s32k1xx_uart_s *priv = (struct s32k1xx_uart_s *)arg;
+  /* Update 'nbytes' indicating number of bytes actually transferred by DMA.
+   * This is important to free TX buffer space by 'uart_xmitchars_done'.
+   */
+
+  priv->dev.dmatx.nbytes = priv->dev.dmatx.length + priv->dev.dmatx.nlength;
+
+  /* Adjust the pointers */
+
+  uart_xmitchars_done(&priv->dev);
+
+  /* Release waiter */
+
+  nxsem_post(&priv->txdmasem);
+}
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_dma_txavailable
+ *
+ * Description:
+ *        Informs DMA that Tx data is available and is ready for transfer.
+ *
+ ****************************************************************************/
+
+#ifdef SERIAL_HAVE_TXDMA
+static void s32k1xx_dma_txavailable(struct uart_dev_s *dev)
+{
+  struct s32k1xx_uart_s *priv = (struct s32k1xx_uart_s *)dev;
+
+  /* Only send when the DMA is idle */
+
+  nxsem_wait(&priv->txdmasem);
+
+  uart_xmitchars_dma(dev);
+}
+#endif
+
+/****************************************************************************
+ * Name: s32k1xx_dma_send
+ *
+ * Description:
+ *   Called (usually) from the interrupt level to start DMA transfer.
+ *   (Re-)Configures DMA Stream updating buffer and buffer length.
+ *
+ ****************************************************************************/
+
+#ifdef SERIAL_HAVE_TXDMA
+static void s32k1xx_dma_send(struct uart_dev_s *dev)
+{
+  struct s32k1xx_uart_s *priv = (struct s32k1xx_uart_s *)dev;
+  struct s32k1xx_edma_xfrconfig_s config;
+
+  /* We need to stop DMA before reconfiguration */
+
+  s32k1xx_dmach_stop(priv->txdma);
+
+  /* Reset the number sent */
+
+  dev->dmatx.nbytes = 0;
+
+  /* Make use of setup function to update buffer and its length for next
+   * transfer
+   */
+
+  config.iter   = dev->dmatx.length;
+  config.flags  = EDMA_CONFIG_LINKTYPE_LINKNONE;
+  config.ssize  = EDMA_8BIT;
+  config.dsize  = EDMA_8BIT;
+  config.nbytes = sizeof(dev->dmatx.buffer[0]);
+  config.saddr  = (uint32_t) dev->dmatx.buffer;
+  config.daddr  = priv->uartbase + S32K1XX_LPUART_DATA_OFFSET;
+  config.soff   = sizeof(dev->dmatx.buffer[0]);
+  config.doff   = 0;
+#ifdef CONFIG_S32K1XX_EDMA_ELINK
+  config.linkch  = 0;
+#endif
+
+  /* Setup first half */
+
+  s32k1xx_dmach_xfrsetup(priv->txdma, &config);
+
+  /* Is this a split transfer? */
+
+  if (dev->dmatx.nbuffer)
+    {
+      config.iter   = priv->dev.dmatx.nlength;
+      config.saddr  = (uint32_t) priv->dev.dmatx.nbuffer;
+
+      s32k1xx_dmach_xfrsetup(priv->txdma, &config);
+    }
+
+  /* Start transmission with the callback on DMA completion */
+
+  s32k1xx_dmach_start(priv->txdma, s32k1xx_dma_txcallback, (void *)priv);
+}
+#endif
 
 /****************************************************************************
  * Name: s32k1xx_send
@@ -1037,6 +1733,28 @@ static void s32k1xx_send(struct uart_dev_s *dev, int ch)
   s32k1xx_serialout(priv, S32K1XX_LPUART_DATA_OFFSET, (uint32_t)ch);
 }
 
+/****************************************************************************
+ * Name: s32k1xx_dma_txint
+ *
+ * Description:
+ *   Call to enable or disable TX interrupts from the UART.
+ *
+ ****************************************************************************/
+
+#ifdef SERIAL_HAVE_TXDMA
+static void s32k1xx_dma_txint(struct uart_dev_s *dev, bool enable)
+{
+  /* Nothing to do. */
+
+  /* In case of DMA transfer we do not want to make use of UART interrupts.
+   * Instead, we use DMA interrupts that are activated once during boot
+   * sequence. Furthermore we can use s32k1xx_dma_txcallback() to handle
+   * stuff at half DMA transfer or after transfer completion (depending on
+   * the configuration).
+   */
+}
+#endif
+
 /****************************************************************************
  * Name: s32k1xx_txint
  *
@@ -1045,6 +1763,7 @@ static void s32k1xx_send(struct uart_dev_s *dev, int ch)
  *
  ****************************************************************************/
 
+#if !defined(SERIAL_HAVE_ONLY_TXDMA)
 static void s32k1xx_txint(struct uart_dev_s *dev, bool enable)
 {
   struct s32k1xx_uart_s *priv = (struct s32k1xx_uart_s *)dev->priv;
@@ -1071,6 +1790,7 @@ static void s32k1xx_txint(struct uart_dev_s *dev, bool 
enable)
   s32k1xx_serialout(priv, S32K1XX_LPUART_CTRL_OFFSET, regval);
   spin_unlock_irqrestore(NULL, flags);
 }
+#endif
 
 /****************************************************************************
  * Name: s32k1xx_txready
@@ -1106,6 +1826,48 @@ static bool s32k1xx_txempty(struct uart_dev_s *dev)
   return ((regval & LPUART_STAT_TDRE) != 0);
 }
 
+/****************************************************************************
+ * Name: s32k1xx_dma_rxcallback
+ *
+ * Description:
+ *   This function checks the current DMA state and calls the generic
+ *   serial stack when bytes appear to be available.
+ *
+ ****************************************************************************/
+
+#ifdef SERIAL_HAVE_RXDMA
+static void s32k1xx_dma_rxcallback(DMACH_HANDLE handle, void *arg, bool done,
+                                  int result)
+{
+  struct s32k1xx_uart_s *priv = (struct s32k1xx_uart_s *)arg;
+  uint32_t sr;
+
+  if (priv->rxenable && s32k1xx_dma_rxavailable(&priv->dev))
+    {
+      uart_recvchars(&priv->dev);
+    }
+
+  /* Get the masked LPUART status word to check and clear error flags.
+   *
+   * When wake-up from low power mode was not fast enough, UART is resumed
+   * too late and sometimes exactly when character was coming over UART,
+   * resulting to frame error.
+   * If error flag is not cleared, Rx DMA will be stuck. Clearing errors
+   * will release Rx DMA.
+   */
+
+  sr = s32k1xx_serialin(priv, S32K1XX_LPUART_STAT_OFFSET);
+
+  if ((sr & (LPUART_STAT_OR | LPUART_STAT_NF | LPUART_STAT_FE)) != 0)
+    {
+      s32k1xx_serialout(priv, S32K1XX_LPUART_STAT_OFFSET,
+                      sr & (LPUART_STAT_OR |
+                            LPUART_STAT_NF |
+                            LPUART_STAT_FE));
+    }
+}
+#endif
+
 /****************************************************************************
  * Name: up_pm_notify
  *
@@ -1136,13 +1898,13 @@ static void up_pm_notify(struct pm_callback_s *cb, int 
domain,
   peripheral_clock_source_t clock_source;
 
   #ifdef CONFIG_PM_SERIAL0
-    struct s32k1xx_uart_s *priv0 = g_uart0port.priv;
+    struct s32k1xx_uart_s *priv0 = g_lpuart0priv.priv;
   #endif
   #ifdef CONFIG_PM_SERIAL1
-    struct s32k1xx_uart_s *priv1 = g_uart1port.priv;
+    struct s32k1xx_uart_s *priv1 = g_lpuart1priv.priv;
   #endif
   #ifdef CONFIG_PM_SERIAL2
-    struct s32k1xx_uart_s *priv2 = g_uart2port.priv;
+    struct s32k1xx_uart_s *priv2 = g_lpuart2priv.priv;
   #endif
 
   uint32_t ret_reg = 0;
@@ -1215,7 +1977,7 @@ static void up_pm_notify(struct pm_callback_s *cb, int 
domain,
 
       /* shutdown the LPUART1 (soft reset) */
 
-      s32k1xx_shutdown(&g_uart0port);
+      s32k1xx_shutdown(&g_lpuart0priv);
 
       /* change the clock config for the new mode */
 
@@ -1223,16 +1985,16 @@ static void up_pm_notify(struct pm_callback_s *cb, int 
domain,
 
       /* shutdown the LPUART1 (soft reset) */
 
-      s32k1xx_shutdown(&g_uart0port);
+      s32k1xx_shutdown(&g_lpuart0priv);
 
       /* set up the LPUART1 again for the new mode */
 
-      s32k1xx_setup(&g_uart0port);
+      s32k1xx_setup(&g_lpuart0priv);
 
       /* enable the interrupts */
 
-      s32k1xx_rxint(&g_uart0port, true);
-      s32k1xx_txint(&g_uart0port, true);
+      s32k1xx_rxint(&g_lpuart0priv, true);
+      s32k1xx_txint(&g_lpuart0priv, true);
 
     #endif
     #ifdef CONFIG_PM_SERIAL1
@@ -1262,7 +2024,7 @@ static void up_pm_notify(struct pm_callback_s *cb, int 
domain,
 
       /* shutdown the LPUART1 (soft reset) */
 
-      s32k1xx_shutdown(&g_uart1port);
+      s32k1xx_shutdown(&g_lpuart1priv);
 
       /* change the clock config for the new mode */
 
@@ -1270,16 +2032,16 @@ static void up_pm_notify(struct pm_callback_s *cb, int 
domain,
 
       /* shutdown the LPUART1 (soft reset) */
 
-      s32k1xx_shutdown(&g_uart1port);
+      s32k1xx_shutdown(&g_lpuart1priv);
 
       /* set up the LPUART1 again for the new mode */
 
-      s32k1xx_setup(&g_uart1port);
+      s32k1xx_setup(&g_lpuart1priv);
 
       /* enable the interrupts */
 
-      s32k1xx_rxint(&g_uart1port, true);
-      s32k1xx_txint(&g_uart1port, true);
+      s32k1xx_rxint(&g_lpuart1priv, true);
+      s32k1xx_txint(&g_lpuart1priv, true);
 
     #endif
     #ifdef CONFIG_PM_SERIAL2
@@ -1309,7 +2071,7 @@ static void up_pm_notify(struct pm_callback_s *cb, int 
domain,
 
       /* shutdown the LPUART1 (soft reset) */
 
-      s32k1xx_shutdown(&g_uart2port);
+      s32k1xx_shutdown(&g_lpuart2priv);
 
       /* change the clock config for the new mode */
 
@@ -1317,16 +2079,16 @@ static void up_pm_notify(struct pm_callback_s *cb, int 
domain,
 
       /* shutdown the LPUART1 (soft reset) */
 
-      s32k1xx_shutdown(&g_uart2port);
+      s32k1xx_shutdown(&g_lpuart2priv);
 
       /* set up the LPUART1 again for the new mode */
 
-      s32k1xx_setup(&g_uart2port);
+      s32k1xx_setup(&g_lpuart2priv);
 
       /* enable the interrupts */
 
-      s32k1xx_rxint(&g_uart2port, true);
-      s32k1xx_txint(&g_uart2port, true);
+      s32k1xx_rxint(&g_lpuart2priv, true);
+      s32k1xx_txint(&g_lpuart2priv, true);
 
     #endif
   }
@@ -1378,13 +2140,16 @@ static int up_pm_prepare(struct pm_callback_s *cb, int 
domain,
   peripheral_clock_source_t clock_source;
 
   #ifdef CONFIG_PM_SERIAL0
-    struct s32k1xx_uart_s *priv0 = (struct s32k1xx_uart_s *)g_uart0port.priv;
+    struct s32k1xx_uart_s *priv0 =
+        (struct s32k1xx_uart_s *)g_lpuart0priv.priv;
   #endif
   #ifdef CONFIG_PM_SERIAL1
-    struct s32k1xx_uart_s *priv1 = (struct s32k1xx_uart_s *)g_uart1port.priv;
+    struct s32k1xx_uart_s *priv1 =
+        (struct s32k1xx_uart_s *)g_lpuart1priv.priv;
   #endif
   #ifdef CONFIG_PM_SERIAL2
-    struct s32k1xx_uart_s *priv2 = (struct s32k1xx_uart_s *)g_uart2port.priv;
+    struct s32k1xx_uart_s *priv2 =
+        (struct s32k1xx_uart_s *)g_lpuart2priv.priv;
   #endif
 
   uint32_t ret_reg = 0;
@@ -1461,7 +2226,7 @@ static int up_pm_prepare(struct pm_callback_s *cb, int 
domain,
 
     /* shutdown the LPUART1 (soft reset) */
 
-    s32k1xx_shutdown(&g_uart0port);
+    s32k1xx_shutdown(&g_lpuart0priv);
 
     /* change the clock config for the new mode */
 
@@ -1469,16 +2234,16 @@ static int up_pm_prepare(struct pm_callback_s *cb, int 
domain,
 
     /* shutdown the LPUART1 (soft reset) */
 
-    s32k1xx_shutdown(&g_uart0port);
+    s32k1xx_shutdown(&g_lpuart0priv);
 
     /* set up the LPUART1 again for the new mode */
 
-    s32k1xx_setup(&g_uart0port);
+    s32k1xx_setup(&g_lpuart0priv);
 
     /* enable the interrupts */
 
-    s32k1xx_rxint(&g_uart0port, true);
-    s32k1xx_txint(&g_uart0port, true);
+    s32k1xx_rxint(&g_lpuart0priv, true);
+    s32k1xx_txint(&g_lpuart0priv, true);
 
   #endif
   #ifdef CONFIG_PM_SERIAL1
@@ -1508,7 +2273,7 @@ static int up_pm_prepare(struct pm_callback_s *cb, int 
domain,
 
     /* shutdown the LPUART1 (soft reset) */
 
-    s32k1xx_shutdown(&g_uart1port);
+    s32k1xx_shutdown(&g_lpuart1priv);
 
     /* change the clock config for the new mode */
 
@@ -1516,16 +2281,16 @@ static int up_pm_prepare(struct pm_callback_s *cb, int 
domain,
 
     /* shutdown the LPUART1 (soft reset) */
 
-    s32k1xx_shutdown(&g_uart1port);
+    s32k1xx_shutdown(&g_lpuart1priv);
 
     /* set up the LPUART1 again for the new mode */
 
-    s32k1xx_setup(&g_uart1port);
+    s32k1xx_setup(&g_lpuart1priv);
 
     /* enable the interrupts */
 
-    s32k1xx_rxint(&g_uart1port, true);
-    s32k1xx_txint(&g_uart1port, true);
+    s32k1xx_rxint(&g_lpuart1priv, true);
+    s32k1xx_txint(&g_lpuart1priv, true);
 
   #endif
   #ifdef CONFIG_PM_SERIAL2
@@ -1555,7 +2320,7 @@ static int up_pm_prepare(struct pm_callback_s *cb, int 
domain,
 
     /* shutdown the LPUART1 (soft reset) */
 
-    s32k1xx_shutdown(&g_uart2port);
+    s32k1xx_shutdown(&g_lpuart2priv);
 
     /* change the clock config for the new mode */
 
@@ -1563,16 +2328,16 @@ static int up_pm_prepare(struct pm_callback_s *cb, int 
domain,
 
     /* shutdown the LPUART1 (soft reset) */
 
-    s32k1xx_shutdown(&g_uart2port);
+    s32k1xx_shutdown(&g_lpuart2priv);
 
     /* set up the LPUART1 again for the new mode */
 
-    s32k1xx_setup(&g_uart2port);
+    s32k1xx_setup(&g_lpuart2priv);
 
     /* enable the interrupts */
 
-    s32k1xx_rxint(&g_uart2port, true);
-    s32k1xx_txint(&g_uart2port, true);
+    s32k1xx_rxint(&g_lpuart2priv, true);
+    s32k1xx_txint(&g_lpuart2priv, true);
 
   #endif
 
@@ -1606,8 +2371,8 @@ void s32k1xx_earlyserialinit(void)
    */
 
 #ifdef CONSOLE_DEV
-  CONSOLE_DEV.isconsole = true;
-  s32k1xx_setup(&CONSOLE_DEV);
+  CONSOLE_DEV.dev.isconsole = true;
+  s32k1xx_setup(&CONSOLE_DEV.dev);
 #endif
 }
 
@@ -1623,7 +2388,7 @@ void s32k1xx_earlyserialinit(void)
 void arm_serialinit(void)
 {
 #ifdef CONFIG_PM
-  #if defined(CONFIG_PM_SERIAL_STANDBY) || defined(CONFIG_PM_SERIAL_SLEEP) 
+  #if defined(CONFIG_PM_SERIAL_STANDBY) || defined(CONFIG_PM_SERIAL_SLEEP)
 
   int ret;
 
@@ -1636,17 +2401,20 @@ void arm_serialinit(void)
 #endif
 
 #ifdef CONSOLE_DEV
-  uart_register("/dev/console", &CONSOLE_DEV);
+  uart_register("/dev/console", &CONSOLE_DEV.dev);
+#  if defined(SERIAL_HAVE_CONSOLE_DMA)
+  s32k1xx_dma_setup(&CONSOLE_DEV.dev);
+#  endif
 #endif
 
   /* Register all UARTs */
 
-  uart_register("/dev/ttyS0", &TTYS0_DEV);
+  uart_register("/dev/ttyS0", &TTYS0_DEV.dev);
 #ifdef TTYS1_DEV
-  uart_register("/dev/ttyS1", &TTYS1_DEV);
+  uart_register("/dev/ttyS1", &TTYS1_DEV.dev);
 #endif
 #ifdef TTYS2_DEV
-  uart_register("/dev/ttyS2", &TTYS2_DEV);
+  uart_register("/dev/ttyS2", &TTYS2_DEV.dev);
 #endif
 }
 
@@ -1661,7 +2429,8 @@ void arm_serialinit(void)
 int up_putc(int ch)
 {
 #ifdef CONSOLE_DEV
-  struct s32k1xx_uart_s *priv = (struct s32k1xx_uart_s *)CONSOLE_DEV.priv;
+  struct s32k1xx_uart_s *priv =
+      (struct s32k1xx_uart_s *)CONSOLE_DEV.dev.priv;
   uint32_t ie;
 
   s32k1xx_disableuartint(priv, &ie);
diff --git a/arch/arm/src/s32k1xx/s32k1xx_serial.h 
b/arch/arm/src/s32k1xx/s32k1xx_serial.h
index e0c26f2a83..9e33a0a367 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_serial.h
+++ b/arch/arm/src/s32k1xx/s32k1xx_serial.h
@@ -34,6 +34,115 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
+#if defined(CONFIG_S32K1XX_LPUART0) || defined(CONFIG_S32K1XX_LPUART1) || \
+    defined(CONFIG_S32K1XX_LPUART2)
+#  define HAVE_UART 1
+#endif
+
+/* Assume DMA is not used on the console UART */
+
+#undef SERIAL_HAVE_CONSOLE_RXDMA
+#undef SERIAL_HAVE_CONSOLE_TXDMA
+
+#if !defined(HAVE_UART) || !defined(CONFIG_ARCH_DMA)
+#  undef CONFIG_LPUART0_RXDMA
+#  undef CONFIG_LPUART0_TXDMA
+#  undef CONFIG_LPUART1_RXDMA
+#  undef CONFIG_LPUART1_TXDMA
+#  undef CONFIG_LPUART2_RXDMA
+#  undef CONFIG_LPUART2_TXDMA
+#endif
+
+/* Disable the DMA configuration on all unused LPUARTs */
+
+#ifndef CONFIG_S32K1XX_LPUART0
+#  undef CONFIG_LPUART0_RXDMA
+#  undef CONFIG_LPUART0_TXDMA
+#endif
+
+#ifndef CONFIG_S32K1XX_LPUART1
+#  undef CONFIG_LPUART1_RXDMA
+#  undef CONFIG_LPUART1_TXDMA
+#endif
+
+#ifndef CONFIG_S32K1XX_LPUART2
+#  undef CONFIG_LPUART2_RXDMA
+#  undef CONFIG_LPUART2_TXDMA
+#endif
+
+/* Is RX DMA available on any (enabled) LPUART? */
+
+#undef SERIAL_HAVE_RXDMA
+#if defined(CONFIG_LPUART0_RXDMA) || defined(CONFIG_LPUART1_RXDMA) || \
+    defined(CONFIG_LPUART2_RXDMA)
+#  define SERIAL_HAVE_RXDMA 1
+#endif
+
+/* Is TX DMA available on any (enabled) LPUART? */
+#undef SERIAL_HAVE_TXDMA
+#if defined(CONFIG_LPUART0_TXDMA) || defined(CONFIG_LPUART1_TXDMA) || \
+    defined(CONFIG_LPUART2_TXDMA)
+#    define SERIAL_HAVE_TXDMA 1
+#endif
+
+/* Is RX DMA used on all (enabled) LPUARTs */
+
+#define SERIAL_HAVE_ONLY_RXDMA 1
+#if defined(CONFIG_S32K1XX_LPUART0) && !defined(CONFIG_LPUART0_RXDMA)
+#  undef SERIAL_HAVE_ONLY_RXDMA
+#elif defined(CONFIG_S32K1XX_LPUART1) && !defined(CONFIG_LPUART1_RXDMA)
+#  undef SERIAL_HAVE_ONLY_RXDMA
+#elif defined(CONFIG_S32K1XX_LPUART2) && !defined(CONFIG_LPUART2_RXDMA)
+#  undef SERIAL_HAVE_ONLY_RXDMA
+#endif
+
+/* Is TX DMA used on all (enabled) LPUARTs */
+
+#define SERIAL_HAVE_ONLY_TXDMA 1
+#if defined(CONFIG_S32K1XX_LPUART0) && !defined(CONFIG_LPUART0_TXDMA)
+#  undef SERIAL_HAVE_ONLY_TXDMA
+#elif defined(CONFIG_S32K1XX_LPUART1) && !defined(CONFIG_LPUART1_TXDMA)
+#  undef SERIAL_HAVE_ONLY_TXDMA
+#elif defined(CONFIG_S32K1XX_LPUART2) && !defined(CONFIG_LPUART2_TXDMA)
+#  undef SERIAL_HAVE_ONLY_TXDMA
+#endif
+
+#undef SERIAL_HAVE_ONLY_DMA
+#if defined(SERIAL_HAVE_ONLY_RXDMA) && defined(SERIAL_HAVE_ONLY_TXDMA)
+#define SERIAL_HAVE_ONLY_DMA
+#endif
+
+/* Verify that DMA has been enabled and the DMA channel has been defined.
+ */
+
+#  if defined(SERIAL_HAVE_TXDMA) || defined(SERIAL_HAVE_RXDMA)
+#    ifndef CONFIG_S32K1XX_EDMA
+#      error S32K1XX LPUART receive or transmit DMA requires 
CONFIG_S32K1XX_EDMA
+#    endif
+#  endif
+
+#if defined(SERIAL_HAVE_RXDMA)
+/* Currently RS-485 support cannot be enabled when RXDMA is in use due to
+ * lack of testing.
+ */
+
+#  if (defined(CONFIG_LPUART0_RXDMA) && defined(CONFIG_LPUART0_RS485)) || \
+      (defined(CONFIG_LPUART1_RXDMA) && defined(CONFIG_LPUART1_RS485)) || \
+      (defined(CONFIG_LPUART2_RXDMA) && defined(CONFIG_LPUART2_RS485))
+#    error "RXDMA and RS-485 cannot be enabled at the same time for the same 
LPUART"
+#  endif
+#endif /* SERIAL_HAVE_RXDMA */
+
+/* Currently RS-485 support cannot be enabled when TXDMA is in use due to
+ * lack of testing.
+ */
+
+#if (defined(CONFIG_LPUART0_TXDMA) && defined(CONFIG_LPUART0_RS485)) || \
+    (defined(CONFIG_LPUART1_TXDMA) && defined(CONFIG_LPUART1_RS485)) || \
+    (defined(CONFIG_LPUART2_TXDMA) && defined(CONFIG_LPUART2_RS485))
+#  error "TXDMA and RS-485 cannot be enabled at the same time for the same 
LPUART"
+#endif
+
 /****************************************************************************
  * Public Types
  ****************************************************************************/

Reply via email to