static void imx_uart_stop_rx(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
- u32 ucr1, ucr2, ucr4;
+ u32 ucr1, ucr2, ucr4, uts;
ucr1 = imx_uart_readl(sport, UCR1);
ucr2 = imx_uart_readl(sport, UCR2);
imx_uart_writel(sport, ucr1, UCR1);
imx_uart_writel(sport, ucr4, UCR4);
- ucr2 &= ~UCR2_RXEN;
+ /* See SER_RS485_ENABLED/UTS_LOOP comment in imx_uart_probe() */
+ if (port->rs485.flags & SER_RS485_ENABLED &&
+ port->rs485.flags & SER_RS485_RTS_ON_SEND &&
+ sport->have_rtscts && !sport->have_rtsgpio) {
+ uts = imx_uart_readl(sport, imx_uart_uts_reg(sport));
+ uts |= UTS_LOOP;
+ imx_uart_writel(sport, uts, imx_uart_uts_reg(sport));
+ ucr2 |= UCR2_RXEN;
+ } else {
+ ucr2 &= ~UCR2_RXEN;
+ }
+
imx_uart_writel(sport, ucr2, UCR2);
}
int retval, i;
unsigned long flags;
int dma_is_inited = 0;
- u32 ucr1, ucr2, ucr3, ucr4;
+ u32 ucr1, ucr2, ucr3, ucr4, uts;
retval = clk_prepare_enable(sport->clk_per);
if (retval)
imx_uart_writel(sport, ucr2, UCR2);
}
+ /* See SER_RS485_ENABLED/UTS_LOOP comment in imx_uart_probe() */
+ uts = imx_uart_readl(sport, imx_uart_uts_reg(sport));
+ uts &= ~UTS_LOOP;
+ imx_uart_writel(sport, uts, imx_uart_uts_reg(sport));
+
spin_unlock_irqrestore(&sport->port.lock, flags);
return 0;
{
struct imx_port *sport = (struct imx_port *)port;
unsigned long flags;
- u32 ucr1, ucr2, ucr4;
+ u32 ucr1, ucr2, ucr4, uts;
if (sport->dma_is_enabled) {
dmaengine_terminate_sync(sport->dma_chan_tx);
spin_lock_irqsave(&sport->port.lock, flags);
ucr1 = imx_uart_readl(sport, UCR1);
- ucr1 &= ~(UCR1_TRDYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN | UCR1_RXDMAEN | UCR1_ATDMAEN);
+ ucr1 &= ~(UCR1_TRDYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_RXDMAEN | UCR1_ATDMAEN);
+ /* See SER_RS485_ENABLED/UTS_LOOP comment in imx_uart_probe() */
+ if (port->rs485.flags & SER_RS485_ENABLED &&
+ port->rs485.flags & SER_RS485_RTS_ON_SEND &&
+ sport->have_rtscts && !sport->have_rtsgpio) {
+ uts = imx_uart_readl(sport, imx_uart_uts_reg(sport));
+ uts |= UTS_LOOP;
+ imx_uart_writel(sport, uts, imx_uart_uts_reg(sport));
+ ucr1 |= UCR1_UARTEN;
+ } else {
+ ucr1 &= ~UCR1_UARTEN;
+ }
imx_uart_writel(sport, ucr1, UCR1);
ucr4 = imx_uart_readl(sport, UCR4);
void __iomem *base;
u32 dma_buf_conf[2];
int ret = 0;
- u32 ucr1;
+ u32 ucr1, ucr2, uts;
struct resource *res;
int txirq, rxirq, rtsirq;
ucr1 &= ~(UCR1_ADEN | UCR1_TRDYEN | UCR1_IDEN | UCR1_RRDYEN | UCR1_RTSDEN);
imx_uart_writel(sport, ucr1, UCR1);
+ /*
+ * In case RS485 is enabled without GPIO RTS control, the UART IP
+ * is used to control CTS signal. Keep both the UART and Receiver
+ * enabled, otherwise the UART IP pulls CTS signal always HIGH no
+ * matter how the UCR2 CTSC and CTS bits are set. To prevent any
+ * data from being fed into the RX FIFO, enable loopback mode in
+ * UTS register, which disconnects the RX path from external RXD
+ * pin and connects it to the Transceiver, which is disabled, so
+ * no data can be fed to the RX FIFO that way.
+ */
+ if (sport->port.rs485.flags & SER_RS485_ENABLED &&
+ sport->have_rtscts && !sport->have_rtsgpio) {
+ uts = imx_uart_readl(sport, imx_uart_uts_reg(sport));
+ uts |= UTS_LOOP;
+ imx_uart_writel(sport, uts, imx_uart_uts_reg(sport));
+
+ ucr1 = imx_uart_readl(sport, UCR1);
+ ucr1 |= UCR1_UARTEN;
+ imx_uart_writel(sport, ucr1, UCR1);
+
+ ucr2 = imx_uart_readl(sport, UCR2);
+ ucr2 |= UCR2_RXEN;
+ imx_uart_writel(sport, ucr2, UCR2);
+ }
+
if (!imx_uart_is_imx1(sport) && sport->dte_mode) {
/*
* The DCEDTE bit changes the direction of DSR, DCD, DTR and RI