diff options
Diffstat (limited to 'drivers/tty/serial/atmel_serial.c')
-rw-r--r-- | drivers/tty/serial/atmel_serial.c | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 1ba9bc667e13..c15c398c88a9 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -51,10 +51,6 @@ #define ATMEL_RTS_HIGH_OFFSET 16 #define ATMEL_RTS_LOW_OFFSET 20 -#if defined(CONFIG_SERIAL_ATMEL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif - #include <linux/serial_core.h> #include "serial_mctrl_gpio.h" @@ -196,10 +192,6 @@ struct atmel_uart_port { static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART]; static DECLARE_BITMAP(atmel_ports_in_use, ATMEL_MAX_UART); -#ifdef SUPPORT_SYSRQ -static struct console atmel_console; -#endif - #if defined(CONFIG_OF) static const struct of_device_id atmel_serial_dt_ids[] = { { .compatible = "atmel,at91rm9200-usart-serial" }, @@ -313,7 +305,11 @@ static int atmel_config_rs485(struct uart_port *port, if (rs485conf->flags & SER_RS485_ENABLED) { dev_dbg(port->dev, "Setting UART to RS485\n"); - atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; + if (port->rs485.flags & SER_RS485_RX_DURING_TX) + atmel_port->tx_done_mask = ATMEL_US_TXRDY; + else + atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; + atmel_uart_writel(port, ATMEL_US_TTGR, rs485conf->delay_rts_after_send); mode |= ATMEL_US_USMODE_RS485; @@ -831,7 +827,7 @@ static void atmel_tx_chars(struct uart_port *port) struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); if (port->x_char && - (atmel_uart_readl(port, ATMEL_US_CSR) & atmel_port->tx_done_mask)) { + (atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY)) { atmel_uart_write_char(port, port->x_char); port->icount.tx++; port->x_char = 0; @@ -839,8 +835,7 @@ static void atmel_tx_chars(struct uart_port *port) if (uart_circ_empty(xmit) || uart_tx_stopped(port)) return; - while (atmel_uart_readl(port, ATMEL_US_CSR) & - atmel_port->tx_done_mask) { + while (atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY) { atmel_uart_write_char(port, xmit->buf[xmit->tail]); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; @@ -851,10 +846,20 @@ static void atmel_tx_chars(struct uart_port *port) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); - if (!uart_circ_empty(xmit)) + if (!uart_circ_empty(xmit)) { + /* we still have characters to transmit, so we should continue + * transmitting them when TX is ready, regardless of + * mode or duplexity + */ + atmel_port->tx_done_mask |= ATMEL_US_TXRDY; + /* Enable interrupts */ atmel_uart_writel(port, ATMEL_US_IER, atmel_port->tx_done_mask); + } else { + if (atmel_uart_is_half_duplex(port)) + atmel_port->tx_done_mask &= ~ATMEL_US_TXRDY; + } } static void atmel_complete_tx_dma(void *arg) @@ -1067,7 +1072,7 @@ static int atmel_prepare_tx_dma(struct uart_port *port) chan_err: dev_err(port->dev, "TX channel not available, switch to pio\n"); - atmel_port->use_dma_tx = 0; + atmel_port->use_dma_tx = false; if (atmel_port->chan_tx) atmel_release_tx_dma(port); return -EINVAL; @@ -1266,7 +1271,7 @@ static int atmel_prepare_rx_dma(struct uart_port *port) chan_err: dev_err(port->dev, "RX channel not available, switch to pio\n"); - atmel_port->use_dma_rx = 0; + atmel_port->use_dma_rx = false; if (atmel_port->chan_rx) atmel_release_rx_dma(port); return -EINVAL; @@ -1693,7 +1698,7 @@ static int atmel_prepare_rx_pdc(struct uart_port *port) DMA_FROM_DEVICE); kfree(atmel_port->pdc_rx[0].buf); } - atmel_port->use_pdc_rx = 0; + atmel_port->use_pdc_rx = false; return -ENOMEM; } pdc->dma_addr = dma_map_single(port->dev, @@ -2526,8 +2531,7 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port, * Use TXEMPTY for interrupt when rs485 or ISO7816 else TXRDY or * ENDTX|TXBUFE */ - if (port->rs485.flags & SER_RS485_ENABLED || - port->iso7816.flags & SER_ISO7816_ENABLED) + if (atmel_uart_is_half_duplex(port)) atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; else if (atmel_use_pdc_tx(port)) { port->fifosize = PDC_BUFFER_SIZE; @@ -2878,6 +2882,7 @@ static int atmel_serial_probe(struct platform_device *pdev) atmel_port = &atmel_ports[ret]; atmel_port->backup_imr = 0; atmel_port->uart.line = ret; + atmel_port->uart.has_sysrq = IS_ENABLED(CONFIG_SERIAL_ATMEL_CONSOLE); atmel_serial_probe_fifos(atmel_port, pdev); atomic_set(&atmel_port->tasklet_shutdown, 0); |