Update Linux to v5.4.2
Change-Id: Idf6911045d9d382da2cfe01b1edff026404ac8fd
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 0f67197..5e08f26 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -24,6 +24,7 @@
#include <linux/serial.h>
#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/pinctrl/consumer.h>
#include <linux/rational.h>
#include <linux/slab.h>
#include <linux/of.h>
@@ -382,6 +383,7 @@
}
#endif
+/* called with port.lock taken and irqs caller dependent */
static void imx_uart_rts_active(struct imx_port *sport, u32 *ucr2)
{
*ucr2 &= ~(UCR2_CTSC | UCR2_CTS);
@@ -390,6 +392,7 @@
mctrl_gpio_set(sport->gpios, sport->port.mctrl);
}
+/* called with port.lock taken and irqs caller dependent */
static void imx_uart_rts_inactive(struct imx_port *sport, u32 *ucr2)
{
*ucr2 &= ~UCR2_CTSC;
@@ -399,11 +402,6 @@
mctrl_gpio_set(sport->gpios, sport->port.mctrl);
}
-static void imx_uart_rts_auto(struct imx_port *sport, u32 *ucr2)
-{
- *ucr2 |= UCR2_CTSC;
-}
-
/* called with port.lock taken and irqs off */
static void imx_uart_start_rx(struct uart_port *port)
{
@@ -441,7 +439,7 @@
return;
ucr1 = imx_uart_readl(sport, UCR1);
- imx_uart_writel(sport, ucr1 & ~UCR1_TXMPTYEN, UCR1);
+ imx_uart_writel(sport, ucr1 & ~UCR1_TRDYEN, UCR1);
/* in rs485 mode disable transmitter if shifter is empty */
if (port->rs485.flags & SER_RS485_ENABLED &&
@@ -519,7 +517,7 @@
* and the TX IRQ is disabled.
**/
ucr1 = imx_uart_readl(sport, UCR1);
- ucr1 &= ~UCR1_TXMPTYEN;
+ ucr1 &= ~UCR1_TRDYEN;
if (sport->dma_is_txing) {
ucr1 |= UCR1_TXDMAEN;
imx_uart_writel(sport, ucr1, UCR1);
@@ -681,7 +679,7 @@
if (!sport->dma_is_enabled) {
ucr1 = imx_uart_readl(sport, UCR1);
- imx_uart_writel(sport, ucr1 | UCR1_TXMPTYEN, UCR1);
+ imx_uart_writel(sport, ucr1 | UCR1_TRDYEN, UCR1);
}
if (sport->dma_is_enabled) {
@@ -690,7 +688,7 @@
* disable TX DMA to let TX interrupt to send X-char */
ucr1 = imx_uart_readl(sport, UCR1);
ucr1 &= ~UCR1_TXDMAEN;
- ucr1 |= UCR1_TXMPTYEN;
+ ucr1 |= UCR1_TRDYEN;
imx_uart_writel(sport, ucr1, UCR1);
return;
}
@@ -706,27 +704,25 @@
{
struct imx_port *sport = dev_id;
u32 usr1;
- unsigned long flags;
- spin_lock_irqsave(&sport->port.lock, flags);
+ spin_lock(&sport->port.lock);
imx_uart_writel(sport, USR1_RTSD, USR1);
usr1 = imx_uart_readl(sport, USR1) & USR1_RTSS;
uart_handle_cts_change(&sport->port, !!usr1);
wake_up_interruptible(&sport->port.state->port.delta_msr_wait);
- spin_unlock_irqrestore(&sport->port.lock, flags);
+ spin_unlock(&sport->port.lock);
return IRQ_HANDLED;
}
static irqreturn_t imx_uart_txint(int irq, void *dev_id)
{
struct imx_port *sport = dev_id;
- unsigned long flags;
- spin_lock_irqsave(&sport->port.lock, flags);
+ spin_lock(&sport->port.lock);
imx_uart_transmit_buffer(sport);
- spin_unlock_irqrestore(&sport->port.lock, flags);
+ spin_unlock(&sport->port.lock);
return IRQ_HANDLED;
}
@@ -735,9 +731,8 @@
struct imx_port *sport = dev_id;
unsigned int rx, flg, ignored = 0;
struct tty_port *port = &sport->port.state->port;
- unsigned long flags;
- spin_lock_irqsave(&sport->port.lock, flags);
+ spin_lock(&sport->port.lock);
while (imx_uart_readl(sport, USR2) & USR2_RDR) {
u32 usr2;
@@ -797,7 +792,7 @@
}
out:
- spin_unlock_irqrestore(&sport->port.lock, flags);
+ spin_unlock(&sport->port.lock);
tty_flip_buffer_push(port);
return IRQ_HANDLED;
}
@@ -879,7 +874,7 @@
usr1 &= ~USR1_RRDY;
if ((ucr2 & UCR2_ATEN) == 0)
usr1 &= ~USR1_AGTIM;
- if ((ucr1 & UCR1_TXMPTYEN) == 0)
+ if ((ucr1 & UCR1_TRDYEN) == 0)
usr1 &= ~USR1_TRDY;
if ((ucr4 & UCR4_TCEN) == 0)
usr2 &= ~USR2_TXDC;
@@ -903,13 +898,11 @@
}
if (usr1 & USR1_DTRD) {
- unsigned long flags;
-
imx_uart_writel(sport, USR1_DTRD, USR1);
- spin_lock_irqsave(&sport->port.lock, flags);
+ spin_lock(&sport->port.lock);
imx_uart_mctrl_check(sport);
- spin_unlock_irqrestore(&sport->port.lock, flags);
+ spin_unlock(&sport->port.lock);
ret = IRQ_HANDLED;
}
@@ -970,10 +963,22 @@
if (!(port->rs485.flags & SER_RS485_ENABLED)) {
u32 ucr2;
+ /*
+ * Turn off autoRTS if RTS is lowered and restore autoRTS
+ * setting if RTS is raised.
+ */
ucr2 = imx_uart_readl(sport, UCR2);
ucr2 &= ~(UCR2_CTS | UCR2_CTSC);
- if (mctrl & TIOCM_RTS)
- ucr2 |= UCR2_CTS | UCR2_CTSC;
+ if (mctrl & TIOCM_RTS) {
+ ucr2 |= UCR2_CTS;
+ /*
+ * UCR2_IRTS is unset if and only if the port is
+ * configured for CRTSCTS, so we use inverted UCR2_IRTS
+ * to get the state to restore to.
+ */
+ if (!(ucr2 & UCR2_IRTS))
+ ucr2 |= UCR2_CTSC;
+ }
imx_uart_writel(sport, ucr2, UCR2);
}
@@ -1169,7 +1174,6 @@
sport->port.icount.buf_overrun++;
tty_flip_buffer_push(port);
} else {
- dev_err(sport->port.dev, "DMA transaction error.\n");
if (usr1 & USR1_FRAMERR) {
sport->port.icount.frame++;
imx_uart_writel(sport, USR1_FRAMERR, USR1);
@@ -1470,7 +1474,7 @@
spin_lock_irqsave(&sport->port.lock, flags);
ucr1 = imx_uart_readl(sport, UCR1);
- ucr1 &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN | UCR1_RXDMAEN | UCR1_ATDMAEN);
+ ucr1 &= ~(UCR1_TRDYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN | UCR1_RXDMAEN | UCR1_ATDMAEN);
imx_uart_writel(sport, ucr1, UCR1);
spin_unlock_irqrestore(&sport->port.lock, flags);
@@ -1537,11 +1541,11 @@
{
struct imx_port *sport = (struct imx_port *)port;
unsigned long flags;
- u32 ucr2, old_ucr1, old_ucr2, ufcr;
+ u32 ucr2, old_ucr2, ufcr;
unsigned int baud, quot;
unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
unsigned long div;
- unsigned long num, denom;
+ unsigned long num, denom, old_ubir, old_ubmr;
uint64_t tdiv64;
/*
@@ -1554,49 +1558,6 @@
old_csize = CS8;
}
- if ((termios->c_cflag & CSIZE) == CS8)
- ucr2 = UCR2_WS | UCR2_SRST | UCR2_IRTS;
- else
- ucr2 = UCR2_SRST | UCR2_IRTS;
-
- if (termios->c_cflag & CRTSCTS) {
- if (sport->have_rtscts) {
- ucr2 &= ~UCR2_IRTS;
-
- if (port->rs485.flags & SER_RS485_ENABLED) {
- /*
- * RTS is mandatory for rs485 operation, so keep
- * it under manual control and keep transmitter
- * disabled.
- */
- if (port->rs485.flags &
- SER_RS485_RTS_AFTER_SEND)
- imx_uart_rts_active(sport, &ucr2);
- else
- imx_uart_rts_inactive(sport, &ucr2);
- } else {
- imx_uart_rts_auto(sport, &ucr2);
- }
- } else {
- termios->c_cflag &= ~CRTSCTS;
- }
- } else if (port->rs485.flags & SER_RS485_ENABLED) {
- /* disable transmitter */
- if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
- imx_uart_rts_active(sport, &ucr2);
- else
- imx_uart_rts_inactive(sport, &ucr2);
- }
-
-
- if (termios->c_cflag & CSTOPB)
- ucr2 |= UCR2_STPB;
- if (termios->c_cflag & PARENB) {
- ucr2 |= UCR2_PREN;
- if (termios->c_cflag & PARODD)
- ucr2 |= UCR2_PROE;
- }
-
del_timer_sync(&sport->timer);
/*
@@ -1607,6 +1568,51 @@
spin_lock_irqsave(&sport->port.lock, flags);
+ /*
+ * Read current UCR2 and save it for future use, then clear all the bits
+ * except those we will or may need to preserve.
+ */
+ old_ucr2 = imx_uart_readl(sport, UCR2);
+ ucr2 = old_ucr2 & (UCR2_TXEN | UCR2_RXEN | UCR2_ATEN | UCR2_CTS);
+
+ ucr2 |= UCR2_SRST | UCR2_IRTS;
+ if ((termios->c_cflag & CSIZE) == CS8)
+ ucr2 |= UCR2_WS;
+
+ if (!sport->have_rtscts)
+ termios->c_cflag &= ~CRTSCTS;
+
+ if (port->rs485.flags & SER_RS485_ENABLED) {
+ /*
+ * RTS is mandatory for rs485 operation, so keep
+ * it under manual control and keep transmitter
+ * disabled.
+ */
+ if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
+ imx_uart_rts_active(sport, &ucr2);
+ else
+ imx_uart_rts_inactive(sport, &ucr2);
+
+ } else if (termios->c_cflag & CRTSCTS) {
+ /*
+ * Only let receiver control RTS output if we were not requested
+ * to have RTS inactive (which then should take precedence).
+ */
+ if (ucr2 & UCR2_CTS)
+ ucr2 |= UCR2_CTSC;
+ }
+
+ if (termios->c_cflag & CRTSCTS)
+ ucr2 &= ~UCR2_IRTS;
+
+ if (termios->c_cflag & CSTOPB)
+ ucr2 |= UCR2_STPB;
+ if (termios->c_cflag & PARENB) {
+ ucr2 |= UCR2_PREN;
+ if (termios->c_cflag & PARODD)
+ ucr2 |= UCR2_PROE;
+ }
+
sport->port.read_status_mask = 0;
if (termios->c_iflag & INPCK)
sport->port.read_status_mask |= (URXD_FRMERR | URXD_PRERR);
@@ -1637,23 +1643,6 @@
*/
uart_update_timeout(port, termios->c_cflag, baud);
- /*
- * disable interrupts and drain transmitter
- */
- old_ucr1 = imx_uart_readl(sport, UCR1);
- imx_uart_writel(sport,
- old_ucr1 & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN),
- UCR1);
- old_ucr2 = imx_uart_readl(sport, UCR2);
- imx_uart_writel(sport, old_ucr2 & ~UCR2_ATEN, UCR2);
-
- while (!(imx_uart_readl(sport, USR2) & USR2_TXDC))
- barrier();
-
- /* then, disable everything */
- imx_uart_writel(sport, old_ucr2 & ~(UCR2_TXEN | UCR2_RXEN | UCR2_ATEN), UCR2);
- old_ucr2 &= (UCR2_TXEN | UCR2_RXEN | UCR2_ATEN);
-
/* custom-baudrate handling */
div = sport->port.uartclk / (baud * 16);
if (baud == 38400 && quot != div)
@@ -1681,17 +1670,27 @@
ufcr = (ufcr & (~UFCR_RFDIV)) | UFCR_RFDIV_REG(div);
imx_uart_writel(sport, ufcr, UFCR);
- imx_uart_writel(sport, num, UBIR);
- imx_uart_writel(sport, denom, UBMR);
+ /*
+ * Two registers below should always be written both and in this
+ * particular order. One consequence is that we need to check if any of
+ * them changes and then update both. We do need the check for change
+ * as even writing the same values seem to "restart"
+ * transmission/receiving logic in the hardware, that leads to data
+ * breakage even when rate doesn't in fact change. E.g., user switches
+ * RTS/CTS handshake and suddenly gets broken bytes.
+ */
+ old_ubir = imx_uart_readl(sport, UBIR);
+ old_ubmr = imx_uart_readl(sport, UBMR);
+ if (old_ubir != num || old_ubmr != denom) {
+ imx_uart_writel(sport, num, UBIR);
+ imx_uart_writel(sport, denom, UBMR);
+ }
if (!imx_uart_is_imx1(sport))
imx_uart_writel(sport, sport->port.uartclk / div / 1000,
IMX21_ONEMS);
- imx_uart_writel(sport, old_ucr1, UCR1);
-
- /* set the parity, stop bits and data size */
- imx_uart_writel(sport, ucr2 | old_ucr2, UCR2);
+ imx_uart_writel(sport, ucr2, UCR2);
if (UART_ENABLE_MS(&sport->port, termios->c_cflag))
imx_uart_enable_ms(&sport->port);
@@ -1779,7 +1778,7 @@
ucr1 |= IMX1_UCR1_UARTCLKEN;
ucr1 |= UCR1_UARTEN;
- ucr1 &= ~(UCR1_TXMPTYEN | UCR1_RTSDEN | UCR1_RRDYEN);
+ ucr1 &= ~(UCR1_TRDYEN | UCR1_RTSDEN | UCR1_RRDYEN);
ucr2 |= UCR2_RXEN;
ucr2 &= ~UCR2_ATEN;
@@ -1939,7 +1938,7 @@
if (imx_uart_is_imx1(sport))
ucr1 |= IMX1_UCR1_UARTCLKEN;
ucr1 |= UCR1_UARTEN;
- ucr1 &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
+ ucr1 &= ~(UCR1_TRDYEN | UCR1_RRDYEN | UCR1_RTSDEN);
imx_uart_writel(sport, ucr1, UCR1);
@@ -2020,7 +2019,7 @@
}
if (*baud != baud_raw)
- pr_info("Console IMX rounded baud rate from %d to %d\n",
+ dev_info(sport->port.dev, "Console IMX rounded baud rate from %d to %d\n",
baud_raw, *baud);
}
}
@@ -2068,7 +2067,7 @@
retval = clk_prepare(sport->clk_per);
if (retval)
- clk_disable_unprepare(sport->clk_ipg);
+ clk_unprepare(sport->clk_ipg);
error_console:
return retval;
@@ -2223,8 +2222,8 @@
return PTR_ERR(base);
rxirq = platform_get_irq(pdev, 0);
- txirq = platform_get_irq(pdev, 1);
- rtsirq = platform_get_irq(pdev, 2);
+ txirq = platform_get_irq_optional(pdev, 1);
+ rtsirq = platform_get_irq_optional(pdev, 2);
sport->port.dev = &pdev->dev;
sport->port.mapbase = res->start;
@@ -2295,7 +2294,7 @@
/* Disable interrupts before requesting them */
ucr1 = imx_uart_readl(sport, UCR1);
ucr1 &= ~(UCR1_ADEN | UCR1_TRDYEN | UCR1_IDEN | UCR1_RRDYEN |
- UCR1_TXMPTYEN | UCR1_RTSDEN);
+ UCR1_TRDYEN | UCR1_RTSDEN);
imx_uart_writel(sport, ucr1, UCR1);
if (!imx_uart_is_imx1(sport) && sport->dte_mode) {
@@ -2384,8 +2383,13 @@
static void imx_uart_restore_context(struct imx_port *sport)
{
- if (!sport->context_saved)
+ unsigned long flags;
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+ if (!sport->context_saved) {
+ spin_unlock_irqrestore(&sport->port.lock, flags);
return;
+ }
imx_uart_writel(sport, sport->saved_reg[4], UFCR);
imx_uart_writel(sport, sport->saved_reg[5], UESC);
@@ -2398,11 +2402,15 @@
imx_uart_writel(sport, sport->saved_reg[2], UCR3);
imx_uart_writel(sport, sport->saved_reg[3], UCR4);
sport->context_saved = false;
+ spin_unlock_irqrestore(&sport->port.lock, flags);
}
static void imx_uart_save_context(struct imx_port *sport)
{
+ unsigned long flags;
+
/* Save necessary regs */
+ spin_lock_irqsave(&sport->port.lock, flags);
sport->saved_reg[0] = imx_uart_readl(sport, UCR1);
sport->saved_reg[1] = imx_uart_readl(sport, UCR2);
sport->saved_reg[2] = imx_uart_readl(sport, UCR3);
@@ -2414,6 +2422,7 @@
sport->saved_reg[8] = imx_uart_readl(sport, UBMR);
sport->saved_reg[9] = imx_uart_readl(sport, IMX21_UTS);
sport->context_saved = true;
+ spin_unlock_irqrestore(&sport->port.lock, flags);
}
static void imx_uart_enable_wakeup(struct imx_port *sport, bool on)
@@ -2447,6 +2456,8 @@
clk_disable(sport->clk_ipg);
+ pinctrl_pm_select_sleep_state(dev);
+
return 0;
}
@@ -2455,6 +2466,8 @@
struct imx_port *sport = dev_get_drvdata(dev);
int ret;
+ pinctrl_pm_select_default_state(dev);
+
ret = clk_enable(sport->clk_ipg);
if (ret)
return ret;