hartmannathan commented on code in PR #15879:
URL: https://github.com/apache/nuttx/pull/15879#discussion_r1963828371


##########
arch/arm/src/mcx-nxxx/nxxx_lpuart.c:
##########
@@ -0,0 +1,2656 @@
+/****************************************************************************
+ * arch/arm/src/mcx-nxxx/nxxx_lpuart.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#ifdef CONFIG_SERIAL_TERMIOS
+#  include <termios.h>
+#endif
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/init.h>
+#include <nuttx/power/pm.h>
+#include <nuttx/fs/ioctl.h>
+#include <nuttx/serial/serial.h>
+
+#include <arch/board/board.h>
+
+#include "arm_internal.h"
+#include "hardware/nxxx_lpuart.h"
+#include "hardware/nxxx_port.h"
+#include "nxxx_lowputc.h"
+#include "nxxx_serial.h"
+
+#if defined(SERIAL_HAVE_TXDMA) || defined(SERIAL_HAVE_RXDMA)
+#  include "chip.h"
+#  include "nxxx_edma.h"
+#  include "hardware/nxxx_dmamux.h"
+#endif
+
+#ifdef USE_SERIALDRIVER
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* DMA should be 32-byte aligned. There is no dcache. */
+
+#define DMA_ALIGNMENT       32
+#define RXDMA_BUFFER_MASK   (DMA_ALIGNMENT - 1)
+#define RXDMA_BUFFER_SIZE   ((CONFIG_NXXX_SERIAL_RXDMA_BUFFER_SIZE \
+                                + RXDMA_BUFFER_MASK) & ~RXDMA_BUFFER_MASK)
+#define TXDMA_BUFFER_MASK   (DMA_ALIGNMENT - 1)
+#define TXDMA_BUFFER_SIZE   ((CONFIG_NXXX_SERIAL_RXDMA_BUFFER_SIZE \
+                              + RXDMA_BUFFER_MASK) & ~RXDMA_BUFFER_MASK)
+
+/* Buffers need to be aligned and multiples of DMA_ALIGNMENT */
+
+#if defined(CONFIG_ARM64_DCACHE_DISABLE)
+#  define TXDMA_BUF_SIZE(b)  (b)
+#  define TXDMA_BUF_ALIGN
+#else
+#  define TXDMA_BUF_SIZE(b) (((b) + TXDMA_BUFFER_MASK) & ~TXDMA_BUFFER_MASK)
+#  define TXDMA_BUF_ALIGN   aligned_data(DMA_ALIGNMENT);
+#endif
+
+#if !defined(CONFIG_LPUART0_TXDMA)
+#  define LPUART0_TXBUFSIZE_ADJUSTED  CONFIG_LPUART0_TXBUFSIZE
+#  define LPUART0_TXBUFSIZE_ALGN
+#else
+#  define LPUART0_TXBUFSIZE_ADJUSTED TXDMA_BUF_SIZE(CONFIG_LPUART0_TXBUFSIZE)
+#  define LPUART0_TXBUFSIZE_ALGN TXDMA_BUF_ALIGN
+#endif
+
+#if !defined(CONFIG_LPUART1_TXDMA)
+#  define LPUART1_TXBUFSIZE_ADJUSTED  CONFIG_LPUART1_TXBUFSIZE
+#  define LPUART1_TXBUFSIZE_ALGN
+#else
+#  define LPUART1_TXBUFSIZE_ADJUSTED TXDMA_BUF_SIZE(CONFIG_LPUART1_TXBUFSIZE)
+#  define LPUART1_TXBUFSIZE_ALGN TXDMA_BUF_ALIGN
+#endif
+
+#if !defined(CONFIG_LPUART2_TXDMA)
+#  define LPUART2_TXBUFSIZE_ADJUSTED  CONFIG_LPUART2_TXBUFSIZE
+#  define LPUART2_TXBUFSIZE_ALGN
+#else
+#  define LPUART2_TXBUFSIZE_ADJUSTED TXDMA_BUF_SIZE(CONFIG_LPUART2_TXBUFSIZE)
+#  define LPUART2_TXBUFSIZE_ALGN TXDMA_BUF_ALIGN
+#endif
+
+#if !defined(CONFIG_LPUART3_TXDMA)
+#  define LPUART3_TXBUFSIZE_ADJUSTED  CONFIG_LPUART3_TXBUFSIZE
+#  define LPUART3_TXBUFSIZE_ALGN
+#else
+#  define LPUART3_TXBUFSIZE_ADJUSTED TXDMA_BUF_SIZE(CONFIG_LPUART3_TXBUFSIZE)
+#  define LPUART3_TXBUFSIZE_ALGN TXDMA_BUF_ALIGN
+#endif
+
+#if !defined(CONFIG_LPUART4_TXDMA)
+#  define LPUART4_TXBUFSIZE_ADJUSTED  CONFIG_LPUART4_TXBUFSIZE
+#  define LPUART4_TXBUFSIZE_ALGN
+#else
+#  define LPUART4_TXBUFSIZE_ADJUSTED TXDMA_BUF_SIZE(CONFIG_LPUART4_TXBUFSIZE)
+#  define LPUART4_TXBUFSIZE_ALGN TXDMA_BUF_ALIGN
+#endif
+
+#if !defined(CONFIG_LPUART5_TXDMA)
+#  define LPUART5_TXBUFSIZE_ADJUSTED  CONFIG_LPUART5_TXBUFSIZE
+#  define LPUART5_TXBUFSIZE_ALGN
+#else
+#  define LPUART5_TXBUFSIZE_ADJUSTED TXDMA_BUF_SIZE(CONFIG_LPUART5_TXBUFSIZE)
+#  define LPUART5_TXBUFSIZE_ALGN TXDMA_BUF_ALIGN
+#endif
+
+#if !defined(CONFIG_LPUART6_TXDMA)
+#  define LPUART6_TXBUFSIZE_ADJUSTED  CONFIG_LPUART6_TXBUFSIZE
+#  define LPUART6_TXBUFSIZE_ALGN
+#else
+#  define LPUART6_TXBUFSIZE_ADJUSTED TXDMA_BUF_SIZE(CONFIG_LPUART6_TXBUFSIZE)
+#  define LPUART6_TXBUFSIZE_ALGN TXDMA_BUF_ALIGN
+#endif
+
+#if !defined(CONFIG_LPUART7_TXDMA)
+#  define LPUART7_TXBUFSIZE_ADJUSTED  CONFIG_LPUART7_TXBUFSIZE
+#  define LPUART7_TXBUFSIZE_ALGN
+#else
+#  define LPUART7_TXBUFSIZE_ADJUSTED TXDMA_BUF_SIZE(CONFIG_LPUART7_TXBUFSIZE)
+#  define LPUART7_TXBUFSIZE_ALGN TXDMA_BUF_ALIGN
+#endif
+
+/* Which LPUART with be console? */
+
+#if defined(CONFIG_LPUART0_SERIAL_CONSOLE)
+#  define CONSOLE_DEV         g_lpuart0priv /* LPUART0 is console */
+#  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_lpuart1priv /* LPUART1 is console */
+#  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_lpuart2priv /* LPUART2 is console */
+#  if defined(CONFIG_LPUART2_RXDMA)
+#    define SERIAL_HAVE_CONSOLE_RXDMA 1
+#  endif
+#  if defined(CONFIG_LPUART2_TXDMA)
+#    define SERIAL_HAVE_CONSOLE_TXDMA 1
+#  endif
+#elif defined(CONFIG_LPUART3_SERIAL_CONSOLE)
+#  define CONSOLE_DEV         g_lpuart3priv /* LPUART3 is console */
+#  if defined(CONFIG_LPUART3_RXDMA)
+#    define SERIAL_HAVE_CONSOLE_RXDMA 1
+#  endif
+#  if defined(CONFIG_LPUART3_TXDMA)
+#    define SERIAL_HAVE_CONSOLE_TXDMA 1
+#  endif
+#elif defined(CONFIG_LPUART4_SERIAL_CONSOLE)
+#  define CONSOLE_DEV         g_lpuart4priv /* LPUART4 is console */
+#  if defined(CONFIG_LPUART4_RXDMA)
+#    define SERIAL_HAVE_CONSOLE_RXDMA 1
+#  endif
+#  if defined(CONFIG_LPUART4_TXDMA)
+#    define SERIAL_HAVE_CONSOLE_TXDMA 1
+#  endif
+#elif defined(CONFIG_LPUART5_SERIAL_CONSOLE)
+#  define CONSOLE_DEV         g_lpuart5priv /* LPUART5 is console */
+#  if defined(CONFIG_LPUART5_RXDMA)
+#    define SERIAL_HAVE_CONSOLE_RXDMA 1
+#  endif
+#  if defined(CONFIG_LPUART5_TXDMA)
+#    define SERIAL_HAVE_CONSOLE_TXDMA 1
+#  endif
+#elif defined(CONFIG_LPUART6_SERIAL_CONSOLE)
+#  define CONSOLE_DEV         g_lpuart6priv /* LPUART6 is console */
+#  if defined(CONFIG_LPUART6_RXDMA)
+#    define SERIAL_HAVE_CONSOLE_RXDMA 1
+#  endif
+#  if defined(CONFIG_LPUART6_TXDMA)
+#    define SERIAL_HAVE_CONSOLE_TXDMA 1
+#  endif
+#elif defined(CONFIG_LPUART7_SERIAL_CONSOLE)
+#  define CONSOLE_DEV         g_lpuart7priv /* LPUART7 is console */
+#  if defined(CONFIG_LPUART7_RXDMA)
+#    define SERIAL_HAVE_CONSOLE_RXDMA 1
+#  endif
+#  if defined(CONFIG_LPUART7_TXDMA)
+#    define SERIAL_HAVE_CONSOLE_TXDMA 1
+#  endif
+#endif
+
+#if defined(SERIAL_HAVE_CONSOLE_RXDMA) || defined(SERIAL_HAVE_CONSOLE_TXDMA)
+#  define SERIAL_HAVE_CONSOLE_DMA
+#endif
+
+#ifdef CONFIG_NXXX_LPUART0
+#define TTYS0_DEV           g_lpuart0priv /* LPUART0 is ttyS0 */
+#endif
+
+#ifdef CONFIG_NXXX_LPUART1
+#define TTYS1_DEV           g_lpuart1priv /* LPUART1 is ttyS1 */
+#endif
+
+#ifdef CONFIG_NXXX_LPUART2
+#define TTYS2_DEV           g_lpuart2priv /* LPUART2 is ttyS2 */
+#endif
+
+#ifdef CONFIG_NXXX_LPUART3
+#define TTYS3_DEV           g_lpuart3priv /* LPUART3 is ttyS3 */
+#endif
+
+#ifdef CONFIG_NXXX_LPUART4
+#define TTYS4_DEV           g_lpuart4priv /* LPUART4 is ttyS4 */
+#endif
+
+#ifdef CONFIG_NXXX_LPUART5
+#define TTYS5_DEV           g_lpuart5priv /* LPUART5 is ttyS5 */
+#endif
+
+#ifdef CONFIG_NXXX_LPUART6
+#define TTYS6_DEV           g_lpuart6priv /* LPUART6 is ttyS6 */
+#endif
+
+#ifdef CONFIG_NXXX_LPUART7
+#define TTYS7_DEV           g_lpuart7priv /* LPUART7 is ttyS7 */
+#endif
+
+/* Power management definitions */
+
+#if defined(CONFIG_PM) && !defined(CONFIG_NXXX_PM_SERIAL_ACTIVITY)
+#  define CONFIG_NXXX_PM_SERIAL_ACTIVITY 10
+#endif
+
+#if defined(CONFIG_PM)
+#  define PM_IDLE_DOMAIN      0 /* Revisit */
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct nxxx_uart_s
+{
+  struct uart_dev_s dev;     /* Generic UART device */
+
+  const uint32_t uartbase;   /* Base address of UART registers */
+  const int      uartnum;    /* LPUART number 1-8 */
+  const bool     usects;     /* output flow control (CTS) available */
+  const bool     userts;     /* input flow control (RTS) available */
+  const bool     rs485mode;  /* We are in RS485 (RTS on TX) mode */
+  const bool     inviflow;   /* Invert RTS sense */
+  spinlock_t     lock;       /* Spinlock */
+  uint32_t       baud;       /* Configured baud */
+  uint32_t       ie;         /* Saved enabled interrupts */
+  uint8_t        irq;        /* IRQ associated with this UART */
+  uint8_t        parity;     /* 0=none, 1=odd, 2=even */
+  uint8_t        bits;       /* Number of bits (7 or 8) */
+  bool           stopbits2;  /* true: Configure with 2 stop bits vs 1 */
+  bool           oflow;      /* output flow control (CTS) enabled */
+  bool           iflow;      /* input flow control (RTS) enabled */
+
+  /* TX DMA state */
+
+#ifdef SERIAL_HAVE_TXDMA
+  const unsigned int txch;   /* DMAMUX source of TX DMA request */
+  DMACH_HANDLE       txdma;  /* currently-open transmit DMA stream */
+#endif
+
+  /* RX DMA state */
+
+#ifdef SERIAL_HAVE_RXDMA
+  const unsigned int rxch;          /* 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 
*/
+#ifndef CONFIG_ARM64_DCACHE_DISABLE
+  uint32_t           rxdmaavail;    /* Number of bytes available without need 
to
+                                     * to invalidate the data cache */
+#endif
+  char *const        rxfifo;        /* Receive DMA buffer */
+#endif
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static inline uint32_t nxxx_serialin(struct nxxx_uart_s *priv,
+                                      uint32_t offset);
+static inline void nxxx_serialout(struct nxxx_uart_s *priv,
+                                   uint32_t offset, uint32_t value);
+static inline void nxxx_disableuartint(struct nxxx_uart_s *priv,
+                                        uint32_t *ie);
+static inline void nxxx_restoreuartint(struct nxxx_uart_s *priv,
+                                        uint32_t ie);
+
+static int  nxxx_setup(struct uart_dev_s *dev);
+static void nxxx_shutdown(struct uart_dev_s *dev);
+static int  nxxx_attach(struct uart_dev_s *dev);
+static void nxxx_detach(struct uart_dev_s *dev);
+static int  nxxx_interrupt(int irq, void *context, void *arg);
+static int  nxxx_ioctl(struct file *filep, int cmd, unsigned long arg);
+#if !defined(SERIAL_HAVE_ONLY_RXDMA)
+static int  nxxx_receive(struct uart_dev_s *dev, unsigned int *status);
+static void nxxx_rxint(struct uart_dev_s *dev, bool enable);
+static bool nxxx_rxavailable(struct uart_dev_s *dev);
+#endif
+#if !defined(SERIAL_HAVE_ONLY_TXDMA)
+static void nxxx_txint(struct uart_dev_s *dev, bool enable);
+#endif
+
+static void nxxx_send(struct uart_dev_s *dev, int ch);
+
+static bool nxxx_txready(struct uart_dev_s *dev);
+
+#ifdef SERIAL_HAVE_TXDMA
+static void nxxx_dma_send(struct uart_dev_s *dev);
+static void nxxx_dma_txint(struct uart_dev_s *dev, bool enable);
+static void nxxx_dma_txavailable(struct uart_dev_s *dev);
+static void nxxx_dma_txcallback(DMACH_HANDLE handle, void *arg, bool done,
+                                   int result);
+#endif
+
+#if defined(SERIAL_HAVE_RXDMA) || defined(SERIAL_HAVE_TXDMA)
+static int  nxxx_dma_setup(struct uart_dev_s *dev);
+static void nxxx_dma_shutdown(struct uart_dev_s *dev);
+#endif
+
+#ifdef SERIAL_HAVE_RXDMA
+static int  nxxx_dma_receive(struct uart_dev_s *dev,
+                                unsigned int *status);
+#ifdef CONFIG_PM
+static void nxxx_dma_reenable(struct nxxx_uart_s *priv);
+#endif
+static void nxxx_dma_rxint(struct uart_dev_s *dev, bool enable);
+static bool nxxx_dma_rxavailable(struct uart_dev_s *dev);
+
+static void nxxx_dma_rxcallback(DMACH_HANDLE handle, void *arg, bool done,
+                                   int result);
+#endif
+
+static bool nxxx_txempty(struct uart_dev_s *dev);
+
+#ifdef CONFIG_PM
+static void up_pm_notify(struct pm_callback_s *cb, int dowmin,
+                         enum pm_state_e pmstate);
+static int  up_pm_prepare(struct pm_callback_s *cb, int domain,
+                          enum pm_state_e pmstate);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Serial driver UART operations */
+
+#if !defined(SERIAL_HAVE_ONLY_TXDMA) && !defined(SERIAL_HAVE_ONLY_RXDMA)
+static const struct uart_ops_s g_lpuart_ops =
+{
+  .setup          = nxxx_setup,
+  .shutdown       = nxxx_shutdown,
+  .attach         = nxxx_attach,
+  .detach         = nxxx_detach,
+  .ioctl          = nxxx_ioctl,
+  .receive        = nxxx_receive,
+  .rxint          = nxxx_rxint,
+  .rxavailable    = nxxx_rxavailable,
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+  .rxflowcontrol  = NULL,
+#endif
+  .send           = nxxx_send,
+  .txint          = nxxx_txint,
+  .txready        = nxxx_txready,
+  .txempty        = nxxx_txempty,
+};
+#endif
+
+#if defined(SERIAL_HAVE_RXDMA) && defined(SERIAL_HAVE_TXDMA)
+static const struct uart_ops_s g_lpuart_rxtxdma_ops =
+{
+  .setup          = nxxx_dma_setup,
+  .shutdown       = nxxx_dma_shutdown,
+  .attach         = nxxx_attach,
+  .detach         = nxxx_detach,
+  .ioctl          = nxxx_ioctl,
+  .receive        = nxxx_dma_receive,
+  .rxint          = nxxx_dma_rxint,
+  .rxavailable    = nxxx_dma_rxavailable,
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+  .rxflowcontrol  = NULL,
+#endif
+  .send           = nxxx_send,
+  .txint          = nxxx_dma_txint,
+  .txready        = nxxx_txready,
+  .txempty        = nxxx_txempty,
+  .dmatxavail     = nxxx_dma_txavailable,
+  .dmasend        = nxxx_dma_send,
+};
+#endif
+
+#if !defined(SERIAL_HAVE_ONLY_DMA) && defined(SERIAL_HAVE_RXDMA)
+static const struct uart_ops_s g_lpuart_rxdma_ops =
+{
+  .setup          = nxxx_dma_setup,
+  .shutdown       = nxxx_dma_shutdown,
+  .attach         = nxxx_attach,
+  .detach         = nxxx_detach,
+  .ioctl          = nxxx_ioctl,
+  .receive        = nxxx_dma_receive,
+  .rxint          = nxxx_dma_rxint,
+  .rxavailable    = nxxx_dma_rxavailable,
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+  .rxflowcontrol  = NULL,
+#endif
+  .send           = nxxx_send,
+  .txint          = nxxx_txint,
+  .txready        = nxxx_txready,
+  .txempty        = nxxx_txempty,
+};
+#endif
+
+#if !defined(SERIAL_HAVE_ONLY_DMA) && defined(SERIAL_HAVE_TXDMA)
+static const struct uart_ops_s g_lpuart_txdma_ops =
+{
+    .setup          = nxxx_dma_setup,
+    .shutdown       = nxxx_dma_shutdown,
+    .attach         = nxxx_attach,
+    .detach         = nxxx_detach,
+    .ioctl          = nxxx_ioctl,
+    .receive        = nxxx_receive,
+    .rxint          = nxxx_rxint,
+    .rxavailable    = nxxx_rxavailable,
+  #ifdef CONFIG_SERIAL_IFLOWCONTROL
+    .rxflowcontrol  = NULL,
+  #endif
+    .send           = nxxx_send,
+    .txint          = nxxx_dma_txint,
+    .txready        = nxxx_txready,
+    .txempty        = nxxx_txempty,
+    .dmatxavail     = nxxx_dma_txavailable,
+    .dmasend        = nxxx_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]
+  aligned_data(DMA_ALIGNMENT);
+#endif
+
+#ifdef CONFIG_LPUART1_RXDMA
+static char g_lpuart1rxfifo[RXDMA_BUFFER_SIZE]
+  aligned_data(DMA_ALIGNMENT);
+#endif
+
+# ifdef CONFIG_LPUART2_RXDMA
+static char g_lpuart2rxfifo[RXDMA_BUFFER_SIZE]
+  aligned_data(DMA_ALIGNMENT);
+#endif
+
+#ifdef CONFIG_LPUART3_RXDMA
+static char g_lpuart3rxfifo[RXDMA_BUFFER_SIZE]
+  aligned_data(DMA_ALIGNMENT);
+#endif
+
+#ifdef CONFIG_LPUART4_RXDMA
+static char g_lpuart4rxfifo[RXDMA_BUFFER_SIZE]
+  aligned_data(DMA_ALIGNMENT);
+#endif
+
+#ifdef CONFIG_LPUART5_RXDMA
+static char g_lpuart5rxfifo[RXDMA_BUFFER_SIZE]
+  aligned_data(DMA_ALIGNMENT);
+#endif
+
+#ifdef CONFIG_LPUART6_RXDMA
+static char g_lpuart6rxfifo[RXDMA_BUFFER_SIZE]
+  aligned_data(DMA_ALIGNMENT);
+#endif
+
+#ifdef CONFIG_LPUART7_RXDMA
+static char g_lpuart7rxfifo[RXDMA_BUFFER_SIZE]
+  aligned_data(DMA_ALIGNMENT);
+#endif
+
+#ifdef CONFIG_NXXX_LPUART0
+static char g_lpuart0rxbuffer[CONFIG_LPUART0_RXBUFSIZE];
+static char g_lpuart0txbuffer[LPUART0_TXBUFSIZE_ADJUSTED] \
+  LPUART0_TXBUFSIZE_ALGN;
+#endif
+
+#ifdef CONFIG_NXXX_LPUART1
+static char g_lpuart1rxbuffer[CONFIG_LPUART1_RXBUFSIZE];
+static char g_lpuart1txbuffer[LPUART1_TXBUFSIZE_ADJUSTED]
+  LPUART1_TXBUFSIZE_ALGN;
+#endif
+
+#ifdef CONFIG_NXXX_LPUART2
+static char g_lpuart2rxbuffer[CONFIG_LPUART2_RXBUFSIZE];
+static char g_lpuart2txbuffer[LPUART2_TXBUFSIZE_ADJUSTED]
+  LPUART2_TXBUFSIZE_ALGN;
+#endif
+
+#ifdef CONFIG_NXXX_LPUART3
+static char g_lpuart3rxbuffer[CONFIG_LPUART3_RXBUFSIZE];
+static char g_lpuart3txbuffer[LPUART3_TXBUFSIZE_ADJUSTED]
+  LPUART3_TXBUFSIZE_ALGN;
+#endif
+
+#ifdef CONFIG_NXXX_LPUART4
+static char g_lpuart4rxbuffer[CONFIG_LPUART4_RXBUFSIZE];
+static char g_lpuart4txbuffer[LPUART4_TXBUFSIZE_ADJUSTED]
+  LPUART4_TXBUFSIZE_ALGN;
+#endif
+
+#ifdef CONFIG_NXXX_LPUART5
+static char g_lpuart5rxbuffer[CONFIG_LPUART5_RXBUFSIZE];
+static char g_lpuart5txbuffer[LPUART5_TXBUFSIZE_ADJUSTED]
+  LPUART5_TXBUFSIZE_ALGN;
+#endif
+
+#ifdef CONFIG_NXXX_LPUART6
+static char g_lpuart6rxbuffer[CONFIG_LPUART6_RXBUFSIZE];
+static char g_lpuart6txbuffer[LPUART6_TXBUFSIZE_ADJUSTED]
+  LPUART6_TXBUFSIZE_ALGN;
+#endif
+
+#ifdef CONFIG_NXXX_LPUART7
+static char g_lpuart7rxbuffer[CONFIG_LPUART7_RXBUFSIZE];
+static char g_lpuart7txbuffer[LPUART7_TXBUFSIZE_ADJUSTED]
+  LPUART7_TXBUFSIZE_ALGN;
+#endif
+
+#ifdef CONFIG_NXXX_LPUART0
+static struct nxxx_uart_s g_lpuart0priv =
+{
+  .dev =
+    {
+      .recv     =
+      {
+        .size   = CONFIG_LPUART0_RXBUFSIZE,
+        .buffer = g_lpuart0rxbuffer,
+      },
+      .xmit     =
+      {
+        .size   = CONFIG_LPUART0_TXBUFSIZE,
+        .buffer = g_lpuart0txbuffer,
+      },
+    #if defined(CONFIG_LPUART0_RXDMA) && defined(CONFIG_LPUART0_TXDMA)
+        .ops    = &g_lpuart_rxtxdma_ops,
+    #elif defined(CONFIG_LPUART0_RXDMA) && !defined(CONFIG_LPUART0_TXDMA)
+        .ops    = &g_lpuart_rxdma_ops,
+    #elif !defined(CONFIG_LPUART0_RXDMA) && defined(CONFIG_LPUART0_TXDMA)
+        .ops    = &g_lpuart_txdma_ops,
+    #else
+        .ops    = &g_lpuart_ops,
+    #endif
+    },
+
+  .uartbase     = NXXX_LPUART0_BASE,
+  .uartnum      = 0,
+  .baud         = CONFIG_LPUART0_BAUD,
+  .irq          = NXXX_IRQ_LP_FLEXCOMM0,
+  .parity       = CONFIG_LPUART0_PARITY,
+  .bits         = CONFIG_LPUART0_BITS,
+  .lock         = SP_UNLOCKED,
+  .stopbits2    = CONFIG_LPUART0_2STOP,
+#  if defined(CONFIG_SERIAL_OFLOWCONTROL) && 
defined(CONFIG_LPUART0_OFLOWCONTROL)
+  .usects       = true,
+#  endif
+#  if defined(CONFIG_SERIAL_IFLOWCONTROL) && 
defined(CONFIG_LPUART0_IFLOWCONTROL)
+  .userts       = true,
+#  endif
+
+#  if (defined(CONFIG_SERIAL_RS485CONTROL) || 
defined(CONFIG_SERIAL_IFLOWCONTROL)) && \
+      defined(CONFIG_LPUART0_INVERTIFLOWCONTROL)
+  .inviflow     = true,
+#  endif
+
+#  if defined(CONFIG_SERIAL_RS485CONTROL) && 
defined(CONFIG_LPUART0_RS485RTSCONTROL)
+  .rs485mode    = true,
+#  endif
+
+#  ifdef CONFIG_LPUART0_TXDMA
+  .txch = DMA_REQUEST_MUXLPUART0TX,
+#  endif
+#  ifdef CONFIG_LPUART0_RXDMA
+  .rxch = DMA_REQUEST_MUXLPUART0RX,
+  .rxfifo       = g_lpuart0rxfifo,
+#  endif
+};
+#endif
+
+#ifdef CONFIG_NXXX_LPUART1
+static struct nxxx_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
+    },
+
+  .uartbase     = NXXX_LPUART1_BASE,
+  .uartnum      = 1,
+  .baud         = CONFIG_LPUART1_BAUD,
+  .irq          = NXXX_IRQ_LP_FLEXCOMM1,
+  .parity       = CONFIG_LPUART1_PARITY,
+  .bits         = CONFIG_LPUART1_BITS,
+  .lock         = SP_UNLOCKED,
+  .stopbits2    = CONFIG_LPUART1_2STOP,
+#  if defined(CONFIG_SERIAL_OFLOWCONTROL) && 
defined(CONFIG_LPUART1_OFLOWCONTROL)
+  .usects       = true,
+#  endif
+#  if defined(CONFIG_SERIAL_IFLOWCONTROL) && 
defined(CONFIG_LPUART1_IFLOWCONTROL)
+  .userts       = true,
+#  endif
+
+#  if (defined(CONFIG_SERIAL_RS485CONTROL) || 
defined(CONFIG_SERIAL_IFLOWCONTROL)) && \
+      defined(CONFIG_LPUART1_INVERTIFLOWCONTROL)
+  .inviflow     = true,
+#  endif
+
+#  if defined(CONFIG_SERIAL_RS485CONTROL) && 
defined(CONFIG_LPUART1_RS485RTSCONTROL)
+  .rs485mode    = true,
+#  endif
+
+#  ifdef CONFIG_LPUART1_TXDMA
+  .txch = DMA_REQUEST_MUXLPUART1TX,
+#  endif
+#  ifdef CONFIG_LPUART1_RXDMA
+  .rxch = DMA_REQUEST_MUXLPUART1RX,
+  .rxfifo       = g_lpuart1rxfifo,
+#  endif
+};
+#endif
+
+#ifdef CONFIG_NXXX_LPUART2
+static struct nxxx_uart_s g_lpuart2priv =
+{
+  .dev =
+    {
+      .recv     =
+      {
+        .size   = CONFIG_LPUART2_RXBUFSIZE,
+        .buffer = g_lpuart2rxbuffer,
+      },
+      .xmit     =
+      {
+        .size   = CONFIG_LPUART2_TXBUFSIZE,
+        .buffer = g_lpuart2txbuffer,
+      },
+#  if defined(CONFIG_LPUART2_RXDMA) && defined(CONFIG_LPUART2_TXDMA)
+        .ops    = &g_lpuart_rxtxdma_ops,
+#  elif defined(CONFIG_LPUART2_RXDMA) && !defined(CONFIG_LPUART2_TXDMA)
+        .ops    = &g_lpuart_rxdma_ops,
+#  elif !defined(CONFIG_LPUART2_RXDMA) && defined(CONFIG_LPUART2_TXDMA)
+        .ops    = &g_lpuart_txdma_ops,
+#  else
+        .ops    = &g_lpuart_ops,
+#  endif
+    },
+
+  .uartbase     = NXXX_LPUART2_BASE,
+  .uartnum      = 2,
+  .baud         = CONFIG_LPUART2_BAUD,
+  .irq          = NXXX_IRQ_LP_FLEXCOMM2,
+  .parity       = CONFIG_LPUART2_PARITY,
+  .bits         = CONFIG_LPUART2_BITS,
+  .lock         = SP_UNLOCKED,
+  .stopbits2    = CONFIG_LPUART2_2STOP,
+#  if defined(CONFIG_SERIAL_OFLOWCONTROL) && 
defined(CONFIG_LPUART2_OFLOWCONTROL)
+  .usects       = true,
+#  endif
+#  if defined(CONFIG_SERIAL_IFLOWCONTROL) && 
defined(CONFIG_LPUART2_IFLOWCONTROL)
+  .userts       = true,
+#  endif
+
+#  if (defined(CONFIG_SERIAL_RS485CONTROL) || 
defined(CONFIG_SERIAL_IFLOWCONTROL)) && \
+      defined(CONFIG_LPUART2_INVERTIFLOWCONTROL)
+  .inviflow     = true,
+#  endif
+
+#  if defined(CONFIG_SERIAL_RS485CONTROL) && 
defined(CONFIG_LPUART2_RS485RTSCONTROL)
+  .rs485mode    = true,
+#  endif
+
+#  ifdef CONFIG_LPUART2_TXDMA
+  .txch = DMA_REQUEST_MUXLPUART2TX,
+#  endif
+#  ifdef CONFIG_LPUART2_RXDMA
+  .rxch = DMA_REQUEST_MUXLPUART2RX,
+  .rxfifo       = g_lpuart2rxfifo,
+#  endif
+};
+#endif
+
+#ifdef CONFIG_NXXX_LPUART3
+static struct nxxx_uart_s g_lpuart3priv =
+{
+  .dev =
+    {
+      .recv     =
+      {
+        .size   = CONFIG_LPUART3_RXBUFSIZE,
+        .buffer = g_lpuart3rxbuffer,
+      },
+      .xmit     =
+      {
+        .size   = CONFIG_LPUART3_TXBUFSIZE,
+        .buffer = g_lpuart3txbuffer,
+      },
+#  if defined(CONFIG_LPUART3_RXDMA) && defined(CONFIG_LPUART3_TXDMA)
+        .ops    = &g_lpuart_rxtxdma_ops,
+#  elif defined(CONFIG_LPUART3_RXDMA) && !defined(CONFIG_LPUART3_TXDMA)
+        .ops    = &g_lpuart_rxdma_ops,
+#  elif !defined(CONFIG_LPUART3_RXDMA) && defined(CONFIG_LPUART3_TXDMA)
+        .ops    = &g_lpuart_txdma_ops,
+#  else
+        .ops    = &g_lpuart_ops,
+#  endif
+    },
+
+  .uartbase     = NXXX_LPUART3_BASE,
+  .uartnum      = 3,
+  .baud         = CONFIG_LPUART3_BAUD,
+  .irq          = NXXX_IRQ_LP_FLEXCOMM3,
+  .parity       = CONFIG_LPUART3_PARITY,
+  .bits         = CONFIG_LPUART3_BITS,
+  .lock         = SP_UNLOCKED,
+  .stopbits2    = CONFIG_LPUART3_2STOP,
+#  if defined(CONFIG_SERIAL_OFLOWCONTROL) && 
defined(CONFIG_LPUART3_OFLOWCONTROL)
+  .usects       = true,
+#  endif
+#  if defined(CONFIG_SERIAL_IFLOWCONTROL) && 
defined(CONFIG_LPUART3_IFLOWCONTROL)
+  .userts       = true,
+#  endif
+
+#  if (defined(CONFIG_SERIAL_RS485CONTROL) || 
defined(CONFIG_SERIAL_IFLOWCONTROL)) && \
+      defined(CONFIG_LPUART3_INVERTIFLOWCONTROL)
+  .inviflow     = true,
+#  endif
+
+#  if defined(CONFIG_SERIAL_RS485CONTROL) && 
defined(CONFIG_LPUART3_RS485RTSCONTROL)
+  .rs485mode    = true,
+#  endif
+
+#  ifdef CONFIG_LPUART3_TXDMA
+  .txch = DMA_REQUEST_MUXLPUART3TX,
+#  endif
+#  ifdef CONFIG_LPUART3_RXDMA
+  .rxch = DMA_REQUEST_MUXLPUART3RX,
+  .rxfifo       = g_lpuart3rxfifo,
+#  endif
+};
+#endif
+
+#ifdef CONFIG_NXXX_LPUART4
+static struct nxxx_uart_s g_lpuart4priv =
+{
+  .dev =
+    {
+      .recv     =
+      {
+        .size   = CONFIG_LPUART4_RXBUFSIZE,
+        .buffer = g_lpuart4rxbuffer,
+      },
+      .xmit     =
+      {
+        .size   = CONFIG_LPUART4_TXBUFSIZE,
+        .buffer = g_lpuart4txbuffer,
+      },
+#  if defined(CONFIG_LPUART4_RXDMA) && defined(CONFIG_LPUART4_TXDMA)
+        .ops    = &g_lpuart_rxtxdma_ops,
+#  elif defined(CONFIG_LPUART4_RXDMA) && !defined(CONFIG_LPUART4_TXDMA)
+        .ops    = &g_lpuart_rxdma_ops,
+#  elif !defined(CONFIG_LPUART4_RXDMA) && defined(CONFIG_LPUART4_TXDMA)
+        .ops    = &g_lpuart_txdma_ops,
+#  else
+        .ops    = &g_lpuart_ops,
+#  endif
+    },
+
+  .uartbase     = NXXX_LPUART4_BASE,
+  .uartnum      = 4,
+  .baud         = CONFIG_LPUART4_BAUD,
+  .irq          = NXXX_IRQ_LP_FLEXCOMM4,
+  .parity       = CONFIG_LPUART4_PARITY,
+  .bits         = CONFIG_LPUART4_BITS,
+  .lock         = SP_UNLOCKED,
+  .stopbits2    = CONFIG_LPUART4_2STOP,
+#  if defined(CONFIG_SERIAL_OFLOWCONTROL) && 
defined(CONFIG_LPUART4_OFLOWCONTROL)
+  .usects       = true,
+#  endif
+#  if defined(CONFIG_SERIAL_IFLOWCONTROL) && 
defined(CONFIG_LPUART4_IFLOWCONTROL)
+  .userts       = true,
+#  endif
+
+#  if (defined(CONFIG_SERIAL_RS485CONTROL) || 
defined(CONFIG_SERIAL_IFLOWCONTROL)) && \
+      defined(CONFIG_LPUART4_INVERTIFLOWCONTROL)
+  .inviflow     = true,
+#  endif
+
+#  if defined(CONFIG_SERIAL_RS485CONTROL) && 
defined(CONFIG_LPUART4_RS485RTSCONTROL)
+  .rs485mode    = true,
+#  endif
+
+#  ifdef CONFIG_LPUART4_TXDMA
+  .txch = DMA_REQUEST_MUXLPUART4TX,
+#  endif
+#  ifdef CONFIG_LPUART4_RXDMA
+  .rxch = DMA_REQUEST_MUXLPUART4RX,
+  .rxfifo       = g_lpuart4rxfifo,
+#  endif
+};
+#endif
+
+#ifdef CONFIG_NXXX_LPUART5
+static struct nxxx_uart_s g_lpuart5priv =
+{
+  .dev =
+    {
+      .recv     =
+      {
+        .size   = CONFIG_LPUART5_RXBUFSIZE,
+        .buffer = g_lpuart5rxbuffer,
+      },
+      .xmit     =
+      {
+        .size   = CONFIG_LPUART5_TXBUFSIZE,
+        .buffer = g_lpuart5txbuffer,
+      },
+#  if defined(CONFIG_LPUART5_RXDMA) && defined(CONFIG_LPUART5_TXDMA)
+        .ops    = &g_lpuart_rxtxdma_ops,
+#  elif defined(CONFIG_LPUART5_RXDMA) && !defined(CONFIG_LPUART5_TXDMA)
+        .ops    = &g_lpuart_rxdma_ops,
+#  elif !defined(CONFIG_LPUART5_RXDMA) && defined(CONFIG_LPUART5_TXDMA)
+        .ops    = &g_lpuart_txdma_ops,
+#  else
+        .ops    = &g_lpuart_ops,
+#  endif
+    },
+
+  .uartbase     = NXXX_LPUART5_BASE,
+  .uartnum      = 5,
+  .baud         = CONFIG_LPUART5_BAUD,
+  .irq          = NXXX_IRQ_LP_FLEXCOMM5,
+  .parity       = CONFIG_LPUART5_PARITY,
+  .bits         = CONFIG_LPUART5_BITS,
+  .lock         = SP_UNLOCKED,
+  .stopbits2    = CONFIG_LPUART5_2STOP,
+#  if defined(CONFIG_SERIAL_OFLOWCONTROL) && 
defined(CONFIG_LPUART5_OFLOWCONTROL)
+  .usects       = true,
+#  endif
+#  if defined(CONFIG_SERIAL_IFLOWCONTROL) && 
defined(CONFIG_LPUART5_IFLOWCONTROL)
+  .userts       = true,
+#  endif
+
+#  if (defined(CONFIG_SERIAL_RS485CONTROL) || 
defined(CONFIG_SERIAL_IFLOWCONTROL)) && \
+      defined(CONFIG_LPUART5_INVERTIFLOWCONTROL)
+  .inviflow     = true,
+#  endif
+
+#  if defined(CONFIG_SERIAL_RS485CONTROL) && 
defined(CONFIG_LPUART5_RS485RTSCONTROL)
+  .rs485mode    = true,
+#  endif
+
+#  ifdef CONFIG_LPUART5_TXDMA
+  .txch = DMA_REQUEST_MUXLPUART5TX,
+#  endif
+#  ifdef CONFIG_LPUART5_RXDMA
+  .rxch = DMA_REQUEST_MUXLPUART5RX,
+  .rxfifo       = g_lpuart5rxfifo,
+#  endif
+};
+#endif
+
+#ifdef CONFIG_NXXX_LPUART6
+static struct nxxx_uart_s g_lpuart6priv =
+{
+  .dev =
+    {
+      .recv     =
+      {
+        .size   = CONFIG_LPUART6_RXBUFSIZE,
+        .buffer = g_lpuart6rxbuffer,
+      },
+      .xmit     =
+      {
+        .size   = CONFIG_LPUART6_TXBUFSIZE,
+        .buffer = g_lpuart6txbuffer,
+      },
+#  if defined(CONFIG_LPUART6_RXDMA) && defined(CONFIG_LPUART6_TXDMA)
+        .ops    = &g_lpuart_rxtxdma_ops,
+#  elif defined(CONFIG_LPUART6_RXDMA) && !defined(CONFIG_LPUART6_TXDMA)
+        .ops    = &g_lpuart_rxdma_ops,
+#  elif !defined(CONFIG_LPUART6_RXDMA) && defined(CONFIG_LPUART6_TXDMA)
+        .ops    = &g_lpuart_txdma_ops,
+#  else
+        .ops    = &g_lpuart_ops,
+#  endif
+    },
+
+  .uartbase     = NXXX_LPUART6_BASE,
+  .uartnum      = 6,
+  .baud         = CONFIG_LPUART6_BAUD,
+  .irq          = NXXX_IRQ_LP_FLEXCOMM6,
+  .parity       = CONFIG_LPUART6_PARITY,
+  .bits         = CONFIG_LPUART6_BITS,
+  .lock         = SP_UNLOCKED,
+  .stopbits2    = CONFIG_LPUART6_2STOP,
+#  if defined(CONFIG_SERIAL_OFLOWCONTROL) && 
defined(CONFIG_LPUART6_OFLOWCONTROL)
+  .usects       = true,
+#  endif
+#  if defined(CONFIG_SERIAL_IFLOWCONTROL) && 
defined(CONFIG_LPUART6_IFLOWCONTROL)
+  .userts       = true,
+#  endif
+
+#  if (defined(CONFIG_SERIAL_RS485CONTROL) || 
defined(CONFIG_SERIAL_IFLOWCONTROL)) && \
+      defined(CONFIG_LPUART6_INVERTIFLOWCONTROL)
+  .inviflow     = true,
+#  endif
+
+#  if defined(CONFIG_SERIAL_RS485CONTROL) && 
defined(CONFIG_LPUART6_RS485RTSCONTROL)
+  .rs485mode    = true,
+#  endif
+
+#  ifdef CONFIG_LPUART6_TXDMA
+  .txch = DMA_REQUEST_MUXLPUART6TX,
+#  endif
+#  ifdef CONFIG_LPUART6_RXDMA
+  .rxch = DMA_REQUEST_MUXLPUART6RX,
+  .rxfifo       = g_lpuart6rxfifo,
+#  endif
+};
+#endif
+
+#ifdef CONFIG_NXXX_LPUART7
+static struct nxxx_uart_s g_lpuart7priv =
+{
+  .dev =
+    {
+      .recv     =
+      {
+        .size   = CONFIG_LPUART7_RXBUFSIZE,
+        .buffer = g_lpuart7rxbuffer,
+      },
+      .xmit     =
+      {
+        .size   = CONFIG_LPUART7_TXBUFSIZE,
+        .buffer = g_lpuart7txbuffer,
+      },
+#  if defined(CONFIG_LPUART7_RXDMA) && defined(CONFIG_LPUART7_TXDMA)
+        .ops    = &g_lpuart_rxtxdma_ops,
+#  elif defined(CONFIG_LPUART7_RXDMA) && !defined(CONFIG_LPUART7_TXDMA)
+        .ops    = &g_lpuart_rxdma_ops,
+#  elif !defined(CONFIG_LPUART7_RXDMA) && defined(CONFIG_LPUART7_TXDMA)
+        .ops    = &g_lpuart_txdma_ops,
+#  else
+        .ops    = &g_lpuart_ops,
+#  endif
+    },
+
+  .uartbase     = NXXX_LPUART7_BASE,
+  .uartnum      = 7,
+  .baud         = CONFIG_LPUART7_BAUD,
+  .irq          = NXXX_IRQ_LP_FLEXCOMM7,
+  .parity       = CONFIG_LPUART7_PARITY,
+  .bits         = CONFIG_LPUART7_BITS,
+  .lock         = SP_UNLOCKED,
+  .stopbits2    = CONFIG_LPUART7_2STOP,
+#  if defined(CONFIG_SERIAL_OFLOWCONTROL) && 
defined(CONFIG_LPUART7_OFLOWCONTROL)
+  .usects       = true,
+#  endif
+#  if defined(CONFIG_SERIAL_IFLOWCONTROL) && 
defined(CONFIG_LPUART7_IFLOWCONTROL)
+  .userts       = true,
+#  endif
+
+#  if (defined(CONFIG_SERIAL_RS485CONTROL) || 
defined(CONFIG_SERIAL_IFLOWCONTROL)) && \
+      defined(CONFIG_LPUART7_INVERTIFLOWCONTROL)
+  .inviflow     = true,
+#  endif
+
+#  if defined(CONFIG_SERIAL_RS485CONTROL) && 
defined(CONFIG_LPUART7_RS485RTSCONTROL)
+  .rs485mode    = true,
+#  endif
+
+#  ifdef CONFIG_LPUART7_TXDMA
+  .txch = DMA_REQUEST_MUXLPUART7TX,
+#  endif
+#  ifdef CONFIG_LPUART7_RXDMA
+  .rxch = DMA_REQUEST_MUXLPUART7RX,
+  .rxfifo       = g_lpuart7rxfifo,
+#  endif
+};
+#endif
+
+#ifdef CONFIG_PM
+static  struct pm_callback_s g_serial_pmcb =
+{
+  .notify       = up_pm_notify,
+  .prepare      = up_pm_prepare,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxxx_serialin
+ ****************************************************************************/
+
+static inline uint32_t nxxx_serialin(struct nxxx_uart_s *priv,
+                                      uint32_t offset)
+{
+  return getreg32(priv->uartbase + offset);
+}
+
+/****************************************************************************
+ * Name: nxxx_serialout
+ ****************************************************************************/
+
+static inline void nxxx_serialout(struct nxxx_uart_s *priv,
+                                     uint32_t offset, uint32_t value)
+{
+  putreg32(value, priv->uartbase + offset);
+}
+
+/****************************************************************************
+ * Name: nxxx_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 nxxx_dma_nextrx(struct nxxx_uart_s *priv)
+{
+  int dmaresidual = nxxx_dmach_getcount(priv->rxdma);
+  DEBUGASSERT(dmaresidual <= RXDMA_BUFFER_SIZE);
+
+  return (RXDMA_BUFFER_SIZE - dmaresidual) % RXDMA_BUFFER_SIZE;
+}
+#endif
+
+/****************************************************************************
+ * Name: nxxx_disableuartint
+ ****************************************************************************/
+
+static inline void nxxx_disableuartint_nolock(struct nxxx_uart_s *priv,
+                                              uint32_t *ie)
+{
+  uint32_t regval;
+
+  regval = nxxx_serialin(priv, NXXX_LPUART_CTRL_OFFSET);
+
+  /* Return the current Rx and Tx interrupt state */
+
+  if (ie != NULL)
+    {
+      *ie = regval & LPUART_ALL_INTS;
+    }
+
+  regval &= ~LPUART_ALL_INTS;
+  nxxx_serialout(priv, NXXX_LPUART_CTRL_OFFSET, regval);
+}
+
+static inline void nxxx_disableuartint(struct nxxx_uart_s *priv,
+                                       uint32_t *ie)
+{
+  irqstate_t flags;
+
+  flags = spin_lock_irqsave(&priv->lock);
+  nxxx_disableuartint_nolock(priv, ie);
+  spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+/****************************************************************************
+ * Name: nxxx_restoreuartint
+ ****************************************************************************/
+
+static inline void nxxx_restoreuartint_nolock(struct nxxx_uart_s *priv,
+                                              uint32_t ie)
+{
+  uint32_t regval;
+
+  regval  = nxxx_serialin(priv, NXXX_LPUART_CTRL_OFFSET);
+  regval &= ~LPUART_ALL_INTS;
+  regval |= ie;
+  nxxx_serialout(priv, NXXX_LPUART_CTRL_OFFSET, regval);
+}
+
+static inline void nxxx_restoreuartint(struct nxxx_uart_s *priv,
+                                       uint32_t ie)
+{
+  irqstate_t flags;
+
+  /* Enable/disable any interrupts that are currently disabled but should be
+   * enabled/disabled.
+   */
+
+  flags = spin_lock_irqsave(&priv->lock);
+  nxxx_restoreuartint_nolock(priv, ie);
+  spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+/****************************************************************************
+ * Name: nxxx_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 nxxx_dma_setup(struct uart_dev_s *dev)
+{
+  struct nxxx_uart_s *priv = (struct nxxx_uart_s *)dev;
+#if defined(SERIAL_HAVE_RXDMA)
+  struct nxxx_edma_xfrconfig_s config;
+#endif
+  int result;
+
+  /* Do the basic UART setup first, unless we are the console */
+
+  if (!dev->isconsole)
+    {
+      result = nxxx_setup(dev);
+      if (result != OK)
+        {
+          return result;
+        }
+    }
+
+#if defined(SERIAL_HAVE_TXDMA)
+  /* Acquire the Tx DMA channel.  This should always succeed. */
+
+  if (priv->txch != 0)
+    {
+      if (priv->txdma == NULL)
+        {
+          priv->txdma = nxxx_dmach_alloc(priv->txch, 0);
+          if (priv->txdma == NULL)
+            {
+              return -EBUSY;
+            }
+        }
+
+      /* Enable Tx DMA for the UART */
+
+      modifyreg32(priv->uartbase + NXXX_LPUART_BAUD_OFFSET,
+                  0, LPUART_BAUD_TDMAE);
+    }
+#endif
+
+#if defined(SERIAL_HAVE_RXDMA)
+  /* Acquire the Rx DMA channel.  This should always succeed. */
+
+  if (priv->rxch != 0)
+    {
+      if (priv->rxdma == NULL)
+        {
+          priv->rxdma = nxxx_dmach_alloc(priv->rxch, 0);
+
+          if (priv->rxdma == NULL)
+            {
+              return -EBUSY;
+            }
+        }
+      else
+        {
+          nxxx_dmach_stop(priv->rxdma);
+        }
+
+      /* Configure for circular DMA reception into the RX FIFO */
+
+      config.saddr  = priv->uartbase + NXXX_LPUART_DATA_OFFSET;
+      config.daddr  = (uintptr_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_NXXX_EDMA_ELINK
+      config.linkch = 0;
+#endif
+
+      nxxx_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;
+
+#ifndef CONFIG_ARM64_DCACHE_DISABLE
+
+      /* Make sure the rx buffer area is all invalid or clean */
+
+      up_invalidate_dcache((uintptr_t)priv->rxfifo,
+                           (uintptr_t)priv->rxfifo + RXDMA_BUFFER_SIZE);
+      priv->rxdmaavail = 0;
+#endif
+
+      /* Enable receive Rx DMA for the UART */
+
+      modifyreg32(priv->uartbase + NXXX_LPUART_BAUD_OFFSET,
+                  0, LPUART_BAUD_RDMAE);
+
+      /* Enable interrupt on idle and erros */

Review Comment:
   ```suggestion
         /* Enable interrupt on idle and errors */
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


Reply via email to