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

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

commit 1dd9f6428753def6a665ee109befd26b7817c364
Author: chao an <anc...@lixiang.com>
AuthorDate: Thu Jan 11 14:15:45 2024 +0800

    drivers/serial/pl011: add support of uart0/2/3 port
    
    Signed-off-by: chao an <anc...@lixiang.com>
---
 drivers/serial/Kconfig-pl011 |  58 +++---
 drivers/serial/uart_pl011.c  | 425 +++++++++++++++++++++++++++++++------------
 2 files changed, 341 insertions(+), 142 deletions(-)

diff --git a/drivers/serial/Kconfig-pl011 b/drivers/serial/Kconfig-pl011
index 9d562761bc..c4c94ba221 100644
--- a/drivers/serial/Kconfig-pl011
+++ b/drivers/serial/Kconfig-pl011
@@ -10,51 +10,59 @@ config UART0_PL011
        select UART0_SERIALDRIVER
        default n
 
+if UART0_PL011
+
+config UART0_BASE
+       hex "UART0 base address"
+
+config UART0_IRQ
+       int "PL011 UART0 IRQ number"
+
+endif # UART0_PL011
+
 config UART1_PL011
        bool "UART1 PL011"
        select UART1_SERIALDRIVER
        default n
 
+if UART1_PL011
+
+config UART1_BASE
+       hex "UART1 base address"
+
+config UART1_IRQ
+       int "PL011 UART1 IRQ number"
+
+endif # UART1_PL011
+
 config UART2_PL011
        bool "UART2 PL011"
        select UART2_SERIALDRIVER
        default n
 
+if UART2_PL011
+
+config UART2_BASE
+       hex "UART2 base address"
+
+config UART2_IRQ
+       int "PL011 UART2 IRQ number"
+
+endif # UART2_PL011
+
 config UART3_PL011
        bool "UART3 PL011"
        select UART3_SERIALDRIVER
        default n
 
-config UART0_BASE
-       hex "UART0 base address"
-       depends on UART0_PL011
-
-config UART1_BASE
-       hex "UART1 base address"
-       depends on UART1_PL011
-
-config UART2_BASE
-       hex "UART2 base address"
-       depends on UART2_PL011
+if UART3_PL011
 
 config UART3_BASE
        hex "UART3 base address"
-       depends on UART3_PL011
-
-config UART0_IRQ
-       int "PL011 UART0 IRQ number"
-       depends on UART0_PL011
-
-config UART1_IRQ
-       int "PL011 UART1 IRQ number"
-       depends on UART1_PL011
-
-config UART2_IRQ
-       int "PL011 UART2 IRQ number"
-       depends on UART2_PL011
 
 config UART3_IRQ
        int "PL011 UART3 IRQ number"
-       depends on UART3_PL011
+
+endif # UART3_PL011
 
 endif # UART_PL011
diff --git a/drivers/serial/uart_pl011.c b/drivers/serial/uart_pl011.c
index 222579a21f..da2aa2f684 100644
--- a/drivers/serial/uart_pl011.c
+++ b/drivers/serial/uart_pl011.c
@@ -59,10 +59,16 @@
 
 /* First pick the console and ttys0.  This could be any of UART1-5 */
 
-#if defined(CONFIG_UART1_SERIAL_CONSOLE)
-#  define CONSOLE_DEV     g_uart1port         /* UART1 is console */
-#  define TTYS0_DEV       g_uart1port         /* UART1 is ttyS0 */
-#  define UART1_ASSIGNED  1
+#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_UART0_PL011)
+#  define HAVE_PL011_CONSOLE 1
+#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_UART1_PL011)
+#  define HAVE_PL011_CONSOLE 1
+#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_UART2_PL011)
+#  define HAVE_PL011_CONSOLE 1
+#elif defined(CONFIG_UART3_SERIAL_CONSOLE) && defined(CONFIG_UART3_PL011)
+#  define HAVE_PL011_CONSOLE 1
+#else
+#  undef HAVE_PL011_CONSOLE 1
 #endif
 
 #define PL011_BIT_MASK(x, y)  (((2 << (x)) - 1) << (y))
@@ -220,9 +226,263 @@ struct pl011_uart_port_s
   struct pl011_data data;
   struct pl011_config config;
   unsigned int irq_num;
-  bool is_console;
 };
 
+static int pl011_setup(struct uart_dev_s *dev);
+static void pl011_shutdown(struct uart_dev_s *dev);
+static int pl011_attach(struct uart_dev_s *dev);
+static void pl011_detach(struct uart_dev_s *dev);
+static int pl011_ioctl(struct file *filep, int cmd, unsigned long arg);
+static int pl011_receive(struct uart_dev_s *dev, unsigned int *status);
+static void pl011_rxint(struct uart_dev_s *dev, bool enable);
+static bool pl011_rxavailable(struct uart_dev_s *dev);
+static void pl011_send(struct uart_dev_s *dev, int ch);
+static void pl011_txint(struct uart_dev_s *dev, bool enable);
+static bool pl011_txready(struct uart_dev_s *dev);
+static bool pl011_txempty(struct uart_dev_s *dev);
+
+/***************************************************************************
+ * Private Data
+ ***************************************************************************/
+
+/* Serial driver UART operations */
+
+static const struct uart_ops_s g_uart_ops =
+{
+  .setup    = pl011_setup,
+  .shutdown = pl011_shutdown,
+  .attach   = pl011_attach,
+  .detach   = pl011_detach,
+  .ioctl    = pl011_ioctl,
+  .receive  = pl011_receive,
+  .rxint    = pl011_rxint,
+  .rxavailable = pl011_rxavailable,
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+  .rxflowcontrol    = NULL,
+#endif
+  .send     = pl011_send,
+  .txint    = pl011_txint,
+  .txready  = pl011_txready,
+  .txempty  = pl011_txempty,
+};
+
+/* I/O buffers */
+
+#ifdef CONFIG_UART0_PL011
+static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE];
+static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE];
+#endif
+#ifdef CONFIG_UART1_PL011
+static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE];
+static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE];
+#endif
+#ifdef CONFIG_UART2_PL011
+static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE];
+static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE];
+#endif
+#ifdef CONFIG_UART3_PL011
+static char g_uart3rxbuffer[CONFIG_UART3_RXBUFSIZE];
+static char g_uart3txbuffer[CONFIG_UART3_TXBUFSIZE];
+#endif
+
+/* This describes the state of the uart0 port. */
+
+#ifdef CONFIG_UART0_PL011
+
+static struct pl011_uart_port_s g_uart0priv =
+{
+  .data =
+    {
+      .baud_rate = CONFIG_UART0_BAUD,
+      .sbsa      = false,
+    },
+
+  .config =
+    {
+      .uart         = (volatile struct pl011_regs *)CONFIG_UART0_BASE,
+      .sys_clk_freq = 24000000,
+    },
+
+    .irq_num    = CONFIG_UART0_IRQ,
+};
+
+/* I/O buffers */
+
+static struct uart_dev_s g_uart0port =
+{
+  .recv =
+    {
+      .size   = CONFIG_UART0_RXBUFSIZE,
+      .buffer = g_uart0rxbuffer,
+    },
+
+  .xmit =
+    {
+      .size   = CONFIG_UART0_TXBUFSIZE,
+      .buffer = g_uart0txbuffer,
+    },
+
+  .ops  = &g_uart_ops,
+  .priv = &g_uart0priv,
+};
+
+#endif /* CONFIG_UART0_PL011 */
+
+/* This describes the state of the uart1 port. */
+
+#ifdef CONFIG_UART1_PL011
+
+static struct pl011_uart_port_s g_uart1priv =
+{
+  .data =
+    {
+      .baud_rate = CONFIG_UART1_BAUD,
+      .sbsa      = false,
+    },
+
+  .config =
+    {
+      .uart         = (volatile struct pl011_regs *)CONFIG_UART1_BASE,
+      .sys_clk_freq = 24000000,
+    },
+
+    .irq_num    = CONFIG_UART1_IRQ,
+};
+
+/* I/O buffers */
+
+static struct uart_dev_s g_uart1port =
+{
+  .recv =
+    {
+      .size   = CONFIG_UART1_RXBUFSIZE,
+      .buffer = g_uart1rxbuffer,
+    },
+
+  .xmit =
+    {
+      .size   = CONFIG_UART1_TXBUFSIZE,
+      .buffer = g_uart1txbuffer,
+    },
+
+  .ops  = &g_uart_ops,
+  .priv = &g_uart1priv,
+};
+
+#endif /* CONFIG_UART1_PL011 */
+
+/* This describes the state of the uart2 port. */
+
+#ifdef CONFIG_UART2_PL011
+
+static struct pl011_uart_port_s g_uart2priv =
+{
+  .data =
+    {
+      .baud_rate = CONFIG_UART2_BAUD,
+      .sbsa      = false,
+    },
+
+  .config =
+    {
+      .uart         = (volatile struct pl011_regs *)CONFIG_UART2_BASE,
+      .sys_clk_freq = 24000000,
+    },
+
+    .irq_num    = CONFIG_UART2_IRQ,
+};
+
+/* I/O buffers */
+
+static struct uart_dev_s g_uart2port =
+{
+  .recv =
+    {
+      .size   = CONFIG_UART2_RXBUFSIZE,
+      .buffer = g_uart2rxbuffer,
+    },
+
+  .xmit =
+    {
+      .size   = CONFIG_UART2_TXBUFSIZE,
+      .buffer = g_uart2txbuffer,
+    },
+
+  .ops  = &g_uart_ops,
+  .priv = &g_uart2priv,
+};
+
+#endif /* CONFIG_UART2_PL011 */
+
+/* This describes the state of the uart3 port. */
+
+#ifdef CONFIG_UART3_PL011
+
+static struct pl011_uart_port_s g_uart3priv =
+{
+  .data =
+    {
+      .baud_rate = CONFIG_UART3_BAUD,
+      .sbsa      = false,
+    },
+
+  .config =
+    {
+      .uart         = (volatile struct pl011_regs *)CONFIG_UART3_BASE,
+      .sys_clk_freq = 24000000,
+    },
+
+    .irq_num    = CONFIG_UART3_IRQ,
+};
+
+/* I/O buffers */
+
+static struct uart_dev_s g_uart3port =
+{
+  .recv =
+    {
+      .size   = CONFIG_UART3_RXBUFSIZE,
+      .buffer = g_uart3rxbuffer,
+    },
+
+  .xmit =
+    {
+      .size   = CONFIG_UART3_TXBUFSIZE,
+      .buffer = g_uart3txbuffer,
+    },
+
+  .ops  = &g_uart_ops,
+  .priv = &g_uart3priv,
+};
+
+#endif /* CONFIG_UART3_PL011 */
+
+#if defined(CONFIG_UART0_SERIAL_CONSOLE)
+#  define CONSOLE_DEV     g_uart0port         /* UART0 is console */
+#elif defined(CONFIG_UART1_SERIAL_CONSOLE)
+#  define CONSOLE_DEV     g_uart1port         /* UART1 is console */
+#elif defined(CONFIG_UART2_SERIAL_CONSOLE)
+#  define CONSOLE_DEV     g_uart2port         /* UART2 is console */
+#elif defined(CONFIG_UART3_SERIAL_CONSOLE)
+#  define CONSOLE_DEV     g_uart3port         /* UART3 is console */
+#endif
+
+#ifdef CONFIG_UART0_PL011
+#  define TTYS0_DEV       g_uart0port
+#endif
+
+#ifdef CONFIG_UART1_PL011
+#  define TTYS1_DEV       g_uart1port
+#endif
+
+#ifdef CONFIG_UART2_PL011
+#  define TTYS2_DEV       g_uart2port
+#endif
+
+#ifdef CONFIG_UART3_PL011
+#  define TTYS3_DEV       g_uart3port
+#endif
+
 /***************************************************************************
  * Private Functions
  ***************************************************************************/
@@ -350,7 +610,7 @@ static int pl011_irq_rx_ready(const struct 
pl011_uart_port_s *sport)
 
 static bool pl011_txready(struct uart_dev_s *dev)
 {
-  struct pl011_uart_port_s  *sport  = (struct pl011_uart_port_s *)dev->priv;
+  struct pl011_uart_port_s  *sport  = dev->priv;
   const struct pl011_config *config = &sport->config;
   struct pl011_data         *data   = &sport->data;
 
@@ -373,7 +633,7 @@ static bool pl011_txready(struct uart_dev_s *dev)
 
 static bool pl011_txempty(struct uart_dev_s *dev)
 {
-  struct pl011_uart_port_s *sport = (struct pl011_uart_port_s *)dev->priv;
+  struct pl011_uart_port_s *sport = dev->priv;
 
   return pl011_irq_tx_complete(sport);
 }
@@ -388,7 +648,7 @@ static bool pl011_txempty(struct uart_dev_s *dev)
 
 static void pl011_send(struct uart_dev_s *dev, int ch)
 {
-  struct pl011_uart_port_s  *sport  = (struct pl011_uart_port_s *)dev->priv;
+  struct pl011_uart_port_s  *sport  = dev->priv;
   const struct pl011_config *config = &sport->config;
 
   config->uart->dr = ch;
@@ -404,7 +664,7 @@ static void pl011_send(struct uart_dev_s *dev, int ch)
 
 static bool pl011_rxavailable(struct uart_dev_s *dev)
 {
-  struct pl011_uart_port_s  *sport  = (struct pl011_uart_port_s *)dev->priv;
+  struct pl011_uart_port_s  *sport  = dev->priv;
   const struct pl011_config *config = &sport->config;
   struct pl011_data         *data   = &sport->data;
 
@@ -428,7 +688,7 @@ static bool pl011_rxavailable(struct uart_dev_s *dev)
 
 static void pl011_rxint(struct uart_dev_s *dev, bool enable)
 {
-  struct pl011_uart_port_s *sport = (struct pl011_uart_port_s *)dev->priv;
+  struct pl011_uart_port_s *sport = dev->priv;
 
   if (enable)
     {
@@ -450,7 +710,7 @@ static void pl011_rxint(struct uart_dev_s *dev, bool enable)
 
 static void pl011_txint(struct uart_dev_s *dev, bool enable)
 {
-  struct pl011_uart_port_s *sport = (struct pl011_uart_port_s *)dev->priv;
+  struct pl011_uart_port_s *sport = dev->priv;
   irqstate_t flags;
 
   flags = enter_critical_section();
@@ -485,7 +745,7 @@ static void pl011_txint(struct uart_dev_s *dev, bool enable)
 
 static int pl011_receive(struct uart_dev_s *dev, unsigned int *status)
 {
-  struct pl011_uart_port_s  *sport  = (struct pl011_uart_port_s *)dev->priv;
+  struct pl011_uart_port_s  *sport  = dev->priv;
   const struct pl011_config *config = &sport->config;
   unsigned int              rx;
 
@@ -537,13 +797,13 @@ static int pl011_ioctl(struct file *filep, int cmd, 
unsigned long arg)
 
 static int pl011_irq_handler(int irq, void *context, void *arg)
 {
-  struct uart_dev_s         *dev = (struct uart_dev_s *)arg;
+  struct uart_dev_s         *dev = arg;
   struct pl011_uart_port_s  *sport;
   UNUSED(irq);
   UNUSED(context);
 
   DEBUGASSERT(dev != NULL && dev->priv != NULL);
-  sport = (struct pl011_uart_port_s *)dev->priv;
+  sport = dev->priv;
 
   if (pl011_irq_rx_ready(sport))
     {
@@ -570,7 +830,7 @@ static int pl011_irq_handler(int irq, void *context, void 
*arg)
 
 static void pl011_detach(struct uart_dev_s *dev)
 {
-  struct pl011_uart_port_s *sport = (struct pl011_uart_port_s *)dev->priv;
+  struct pl011_uart_port_s *sport = dev->priv;
 
   up_disable_irq(sport->irq_num);
   irq_detach(sport->irq_num);
@@ -599,7 +859,7 @@ static int pl011_attach(struct uart_dev_s *dev)
   struct pl011_data         *data;
   int                       ret;
 
-  sport = (struct pl011_uart_port_s *)dev->priv;
+  sport = dev->priv;
   data  = &sport->data;
 
   ret = irq_attach(sport->irq_num, pl011_irq_handler, dev);
@@ -638,7 +898,7 @@ static void pl011_shutdown(struct uart_dev_s *dev)
 
 static int pl011_setup(struct uart_dev_s *dev)
 {
-  struct pl011_uart_port_s  *sport  = (struct pl011_uart_port_s *)dev->priv;
+  struct pl011_uart_port_s  *sport  = dev->priv;
   const struct pl011_config *config = &sport->config;
   struct pl011_data         *data   = &sport->data;
   int                       ret;
@@ -698,74 +958,6 @@ static int pl011_setup(struct uart_dev_s *dev)
   return 0;
 }
 
-/***************************************************************************
- * Private Data
- ***************************************************************************/
-
-/* Serial driver UART operations */
-
-static const struct uart_ops_s g_uart_ops =
-{
-  .setup    = pl011_setup,
-  .shutdown = pl011_shutdown,
-  .attach   = pl011_attach,
-  .detach   = pl011_detach,
-  .ioctl    = pl011_ioctl,
-  .receive  = pl011_receive,
-  .rxint    = pl011_rxint,
-  .rxavailable = pl011_rxavailable,
-#ifdef CONFIG_SERIAL_IFLOWCONTROL
-  .rxflowcontrol    = NULL,
-#endif
-  .send     = pl011_send,
-  .txint    = pl011_txint,
-  .txready  = pl011_txready,
-  .txempty  = pl011_txempty,
-};
-
-/* This describes the state of the uart1 port. */
-
-static struct pl011_uart_port_s g_uart1priv =
-{
-  .data   =
-    {
-      .baud_rate  = CONFIG_UART1_BAUD,
-      .sbsa       = false,
-    },
-
-  .config =
-    {
-      .uart           = (volatile struct pl011_regs *)CONFIG_UART1_BASE,
-      .sys_clk_freq   = 24000000,
-    },
-
-    .irq_num      = CONFIG_UART1_IRQ,
-    .is_console   = 1,
-};
-
-/* I/O buffers */
-
-static char                 g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE];
-static char                 g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE];
-
-static struct uart_dev_s    g_uart1port =
-{
-  .recv  =
-    {
-      .size   = CONFIG_UART1_RXBUFSIZE,
-      .buffer = g_uart1rxbuffer,
-    },
-
-  .xmit  =
-    {
-      .size   = CONFIG_UART1_TXBUFSIZE,
-      .buffer = g_uart1txbuffer,
-    },
-
-  .ops   = &g_uart_ops,
-  .priv  = &g_uart1priv,
-};
-
 /***************************************************************************
  * Public Functions
  ***************************************************************************/
@@ -789,18 +981,45 @@ void pl011_earlyserialinit(void)
 #endif
 }
 
+/***************************************************************************
+ * Name: pl011_serialinit
+ *
+ * Description:
+ *   Register serial console and serial ports.  This assumes that
+ *   pl011_earlyserialinit was called previously.
+ *
+ ***************************************************************************/
+
+void pl011_serialinit(void)
+{
+#ifdef CONSOLE_DEV
+  uart_register("/dev/console", &CONSOLE_DEV);
+#endif
+#ifdef TTYS0_DEV
+  uart_register("/dev/ttyS0", &TTYS0_DEV);
+#endif
+#ifdef TTYS1_DEV
+  uart_register("/dev/ttyS1", &TTYS1_DEV);
+#endif
+#ifdef TTYS2_DEV
+  uart_register("/dev/ttyS2", &TTYS2_DEV);
+#endif
+#ifdef TTYS3_DEV
+  uart_register("/dev/ttyS3", &TTYS3_DEV);
+#endif
+}
+
 /***************************************************************************
  * Name: up_putc
  *
  * Description:
- *   Provide priority, low-level access to support OS debug
- *   writes
+ *   Provide priority, low-level access to support OS debug writes
  *
  ***************************************************************************/
 
+#ifdef HAVE_PL011_CONSOLE
 int up_putc(int ch)
 {
-#ifdef CONSOLE_DEV
   struct uart_dev_s *dev = &CONSOLE_DEV;
 
   /* Check for LF */
@@ -813,37 +1032,9 @@ int up_putc(int ch)
     }
 
   pl011_send(dev, ch);
-#endif
 
   return ch;
 }
-
-/***************************************************************************
- * Name: pl011_serialinit
- *
- * Description:
- *   see nuttx/serial/uart_pl011.h
- *
- ***************************************************************************/
-
-void pl011_serialinit(void)
-{
-#ifdef CONSOLE_DEV
-  int ret;
-
-  ret = uart_register("/dev/console", &CONSOLE_DEV);
-  if (ret < 0)
-    {
-      sinfo("error at register dev/console, ret =%d\n", ret);
-    }
-
-  ret = uart_register("/dev/ttyS0", &TTYS0_DEV);
-
-  if (ret < 0)
-    {
-      sinfo("error at register dev/ttyS0, ret =%d\n", ret);
-    }
 #endif
-}
 
-#endif /* USE_SERIALDRIVER */
+#endif /* CONFIG_UART_PL011 */

Reply via email to