]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
serial: ar933x: Add polling support
authorSven Eckelmann <se@simonwunderlich.de>
Wed, 1 Oct 2025 11:47:26 +0000 (13:47 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 22 Oct 2025 10:04:43 +0000 (12:04 +0200)
KGDB requires at least the polling hooks .poll_get_char and .poll_put_char
to transmit/receive character via the serial driver.

Signed-off-by: Sven Eckelmann <se@simonwunderlich.de>
Link: https://patch.msgid.link/20251001-ar933x-kgdb-support-v1-1-5fffd9e36a01@simonwunderlich.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/ar933x_uart.c

index 8bb33556b31208a1707ca7a48db0aa2ca81452bd..5b491db9d2fc01e051f629f224024ac4dc4d35ff 100644 (file)
@@ -560,6 +560,64 @@ static int ar933x_uart_verify_port(struct uart_port *port,
        return 0;
 }
 
+#ifdef CONFIG_CONSOLE_POLL
+static int ar933x_poll_get_char(struct uart_port *port)
+{
+       struct ar933x_uart_port *up =
+               container_of(port, struct ar933x_uart_port, port);
+       unsigned int rdata;
+       unsigned char ch;
+       u32 imr;
+
+       /* Disable all interrupts */
+       imr = ar933x_uart_read(up, AR933X_UART_INT_EN_REG);
+       ar933x_uart_write(up, AR933X_UART_INT_EN_REG, 0);
+
+       rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG);
+       if ((rdata & AR933X_UART_DATA_RX_CSR) == 0) {
+               /* Enable interrupts */
+               ar933x_uart_write(up, AR933X_UART_INT_EN_REG, imr);
+               return NO_POLL_CHAR;
+       }
+
+       /* remove the character from the FIFO */
+       ar933x_uart_write(up, AR933X_UART_DATA_REG,
+                         AR933X_UART_DATA_RX_CSR);
+
+       ch = rdata & AR933X_UART_DATA_TX_RX_MASK;
+
+       /* Enable interrupts */
+       ar933x_uart_write(up, AR933X_UART_INT_EN_REG, imr);
+
+       return ch;
+}
+
+static void ar933x_poll_put_char(struct uart_port *port, unsigned char c)
+{
+       struct ar933x_uart_port *up =
+               container_of(port, struct ar933x_uart_port, port);
+       u32 imr;
+
+       /* Disable all interrupts */
+       imr = ar933x_uart_read(up, AR933X_UART_INT_EN_REG);
+       ar933x_uart_write(up, AR933X_UART_INT_EN_REG, 0);
+
+       /* Wait until FIFO is empty */
+       while (!(ar933x_uart_read(up, AR933X_UART_DATA_REG) & AR933X_UART_DATA_TX_CSR))
+               cpu_relax();
+
+       /* Write a character */
+       ar933x_uart_putc(up, c);
+
+       /* Wait until FIFO is empty */
+       while (!(ar933x_uart_read(up, AR933X_UART_DATA_REG) & AR933X_UART_DATA_TX_CSR))
+               cpu_relax();
+
+       /* Enable interrupts */
+       ar933x_uart_write(up, AR933X_UART_INT_EN_REG, imr);
+}
+#endif
+
 static const struct uart_ops ar933x_uart_ops = {
        .tx_empty       = ar933x_uart_tx_empty,
        .set_mctrl      = ar933x_uart_set_mctrl,
@@ -576,6 +634,10 @@ static const struct uart_ops ar933x_uart_ops = {
        .request_port   = ar933x_uart_request_port,
        .config_port    = ar933x_uart_config_port,
        .verify_port    = ar933x_uart_verify_port,
+#ifdef CONFIG_CONSOLE_POLL
+       .poll_get_char  = ar933x_poll_get_char,
+       .poll_put_char  = ar933x_poll_put_char,
+#endif
 };
 
 static int ar933x_config_rs485(struct uart_port *port, struct ktermios *termios,