diff options
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/owl-uart.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/tty/serial/owl-uart.c b/drivers/tty/serial/owl-uart.c index c149f8c30007..abc6042f0378 100644 --- a/drivers/tty/serial/owl-uart.c +++ b/drivers/tty/serial/owl-uart.c @@ -12,6 +12,7 @@ #include <linux/console.h> #include <linux/delay.h> #include <linux/io.h> +#include <linux/iopoll.h> #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> @@ -62,6 +63,9 @@ #define OWL_UART_STAT_TRFL_MASK GENMASK(16, 11) #define OWL_UART_STAT_UTBB BIT(17) +#define OWL_UART_POLL_USEC 5 +#define OWL_UART_TIMEOUT_USEC 10000 + static struct uart_driver owl_uart_driver; struct owl_uart_info { @@ -461,6 +465,36 @@ static void owl_uart_config_port(struct uart_port *port, int flags) } } +#ifdef CONFIG_CONSOLE_POLL + +static int owl_uart_poll_get_char(struct uart_port *port) +{ + if (owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_RFEM) + return NO_POLL_CHAR; + + return owl_uart_read(port, OWL_UART_RXDAT); +} + +static void owl_uart_poll_put_char(struct uart_port *port, unsigned char ch) +{ + u32 reg; + int ret; + + /* Wait while FIFO is full or timeout */ + ret = readl_poll_timeout_atomic(port->membase + OWL_UART_STAT, reg, + !(reg & OWL_UART_STAT_TFFU), + OWL_UART_POLL_USEC, + OWL_UART_TIMEOUT_USEC); + if (ret == -ETIMEDOUT) { + dev_err(port->dev, "Timeout waiting while UART TX FULL\n"); + return; + } + + owl_uart_write(port, ch, OWL_UART_TXDAT); +} + +#endif /* CONFIG_CONSOLE_POLL */ + static const struct uart_ops owl_uart_ops = { .set_mctrl = owl_uart_set_mctrl, .get_mctrl = owl_uart_get_mctrl, @@ -476,6 +510,10 @@ static const struct uart_ops owl_uart_ops = { .request_port = owl_uart_request_port, .release_port = owl_uart_release_port, .verify_port = owl_uart_verify_port, +#ifdef CONFIG_CONSOLE_POLL + .poll_get_char = owl_uart_poll_get_char, + .poll_put_char = owl_uart_poll_put_char, +#endif }; #ifdef CONFIG_SERIAL_OWL_CONSOLE |