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

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

commit 8c035a2414402f147ed623e29fde28a2dcf5f462
Author: yinshengkai <[email protected]>
AuthorDate: Thu Feb 26 16:31:50 2026 +0800

    drivers/serial/xlnxps: add polling mode support for serial drivers
    
    Adds CONFIG_UART_XLNXPS_POLLING options to enable polling mode for
    transmission. This avoids TX interrupts and reduces interrupt latency
    at the cost of blocking during TX.
    
    Implements sendbuf() method for efficient buffer transmission
    in polling mode.
    
    Signed-off-by: yinshengkai <[email protected]>
    Signed-off-by: chao an <[email protected]>
---
 drivers/serial/Kconfig-xlnxps |  8 ++++++++
 drivers/serial/uart_xlnx_ps.c | 39 +++++++++++++++++++++++++++++++++++----
 2 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/drivers/serial/Kconfig-xlnxps b/drivers/serial/Kconfig-xlnxps
index 3de1f212ce6..7bb991370d5 100644
--- a/drivers/serial/Kconfig-xlnxps
+++ b/drivers/serial/Kconfig-xlnxps
@@ -5,6 +5,14 @@
 
 if UART_XLNXPS
 
+config UART_XLNXPS_POLLING
+       bool "Force polling mode for TX"
+       default n
+       ---help---
+               Force using polling mode for transmission. This avoids using TX 
interrupts
+               and potentially reduces interrupt latency, at the cost of 
blocking execution
+               during transmission.
+
 config XLNXPS_SERIAL_DISABLE_REORDERING
        bool "Disable reordering of ttySx devices."
        default n
diff --git a/drivers/serial/uart_xlnx_ps.c b/drivers/serial/uart_xlnx_ps.c
index 6257d36ba4f..1fc8f92b095 100644
--- a/drivers/serial/uart_xlnx_ps.c
+++ b/drivers/serial/uart_xlnx_ps.c
@@ -413,6 +413,8 @@ struct xlnxps_port_s
 
 static void xlnxps_rxint(struct uart_dev_s *dev, bool enable);
 static void xlnxps_txint(struct uart_dev_s *dev, bool enable);
+static bool xlnxps_txready(struct uart_dev_s *dev);
+static void xlnxps_wait_send(struct uart_dev_s *dev, int ch);
 
 /***************************************************************************
  * Private Functions
@@ -982,6 +984,26 @@ static void xlnxps_send(struct uart_dev_s *dev, int ch)
   putreg8(ch, config->uart + XUARTPS_FIFO_OFFSET);
 }
 
+/***************************************************************************
+ * Name: xlnxps_sendbuf
+ *
+ * Description:
+ *   This method will send a buffer of bytes on the UART
+ *
+ ***************************************************************************/
+
+static ssize_t xlnxps_sendbuf(struct uart_dev_s *dev,
+                              const void *buffer, size_t size)
+{
+  for (size_t i = 0; i < size; i++)
+    {
+      while (!xlnxps_txready(dev));
+      xlnxps_send(dev, ((const unsigned char *)buffer)[i]);
+    }
+
+  return (ssize_t)size;
+}
+
 /***************************************************************************
  * Name: xlnxps_txint
  *
@@ -1003,33 +1025,41 @@ static void xlnxps_txint(struct uart_dev_s *dev, bool 
enable)
   struct xlnxps_config *config = &port->config;
   irqstate_t flags;
 
-  flags = enter_critical_section();
-
   /* Write to Interrupt Enable Register (UART_IER) */
 
   if (enable)
     {
+#ifdef CONFIG_UART_XLNXPS_POLLING
+      /* In polling mode, we loop until the buffer is empty */
+
+      uart_xmitchars(dev);
+#else
+      flags = enter_critical_section();
+
       /* Set XUARTPS_IXR_TXEMPTY bit (Enable Tx Fifo Empty Interrupt) */
 
       modreg32(XUARTPS_IXR_TXEMPTY, XUARTPS_IXR_TXEMPTY,
                config->uart + XUARTPS_IER_OFFSET);
 
       modreg32(0, XUARTPS_IXR_TXEMPTY, config->uart + XUARTPS_IDR_OFFSET);
+      leave_critical_section(flags);
 
       /* Fake a TX interrupt */
 
       uart_xmitchars(dev);
+#endif
     }
   else
     {
+      flags = enter_critical_section();
+
       /* Clear XUARTPS_IXR_TXEMPTY bit (Disable Tx Fifo Empty Interrupt) */
 
       modreg32(0, XUARTPS_IXR_TXEMPTY, config->uart + XUARTPS_IER_OFFSET);
       modreg32(XUARTPS_IXR_TXEMPTY, XUARTPS_IXR_TXEMPTY,
                config->uart + XUARTPS_IDR_OFFSET);
+      leave_critical_section(flags);
     }
-
-  leave_critical_section(flags);
 }
 
 /***************************************************************************
@@ -1124,6 +1154,7 @@ static const struct uart_ops_s g_uart_ops =
   .txint    = xlnxps_txint,
   .txready  = xlnxps_txready,
   .txempty  = xlnxps_txempty,
+  .sendbuf  = xlnxps_sendbuf,
 };
 
 #ifdef CONFIG_UART_XLNXPS0

Reply via email to