[LEDE-DEV] [PATCH] imx6: kernel: Backport serial port fixes

Petr Štetiar ynezz at true.cz
Fri Jan 13 02:42:08 PST 2017


Signed-off-by: Petr Štetiar <ynezz at true.cz>
---
 ...erial-imx-repair-and-complete-handshaking.patch | 78 ++++++++++++++++++++++
 .../111-serial-imx-fix-polarity-of-RI.patch        | 38 +++++++++++
 ...let-irq-handler-return-IRQ_NONE-if-no-eve.patch | 72 ++++++++++++++++++++
 ...imx-make-sure-unhandled-irqs-are-disabled.patch | 61 +++++++++++++++++
 4 files changed, 249 insertions(+)
 create mode 100644 target/linux/imx6/patches-4.4/110-serial-imx-repair-and-complete-handshaking.patch
 create mode 100644 target/linux/imx6/patches-4.4/111-serial-imx-fix-polarity-of-RI.patch
 create mode 100644 target/linux/imx6/patches-4.4/112-serial-imx-let-irq-handler-return-IRQ_NONE-if-no-eve.patch
 create mode 100644 target/linux/imx6/patches-4.4/113-serial-imx-make-sure-unhandled-irqs-are-disabled.patch

diff --git a/target/linux/imx6/patches-4.4/110-serial-imx-repair-and-complete-handshaking.patch b/target/linux/imx6/patches-4.4/110-serial-imx-repair-and-complete-handshaking.patch
new file mode 100644
index 0000000..0a117f6
--- /dev/null
+++ b/target/linux/imx6/patches-4.4/110-serial-imx-repair-and-complete-handshaking.patch
@@ -0,0 +1,78 @@
+From 90ebc4838666d148eac5bbac6f4044e5b25cd2d6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig at pengutronix.de>
+Date: Sun, 18 Oct 2015 21:34:46 +0200
+Subject: [PATCH] serial: imx: repair and complete handshaking
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The .get_mctrl callback should not report the status of RTS or LOOP, so
+drop this. Instead implement reporting the state of CAR (aka DCD) and
+RI.
+
+For .set_mctrl implement setting the DTR line.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig at pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+Signed-off-by: Petr Štetiar <ynezz at true.cz>
+---
+ drivers/tty/serial/imx.c | 23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
+index 76818f5..086675e 100644
+--- a/drivers/tty/serial/imx.c
++++ b/drivers/tty/serial/imx.c
+@@ -148,8 +148,11 @@
+ #define USR2_TXFE	 (1<<14) /* Transmit buffer FIFO empty */
+ #define USR2_DTRF	 (1<<13) /* DTR edge interrupt flag */
+ #define USR2_IDLE	 (1<<12) /* Idle condition */
++#define USR2_RIDELT	 (1<<10) /* Ring Interrupt Delta */
++#define USR2_RIIN	 (1<<9)	 /* Ring Indicator Input */
+ #define USR2_IRINT	 (1<<8)	 /* Serial infrared interrupt flag */
+ #define USR2_WAKE	 (1<<7)	 /* Wake */
++#define USR2_DCDIN	 (1<<5)	 /* Data Carrier Detect Input */
+ #define USR2_RTSF	 (1<<4)	 /* RTS edge interrupt flag */
+ #define USR2_TXDC	 (1<<3)	 /* Transmitter complete */
+ #define USR2_BRCD	 (1<<2)	 /* Break condition */
+@@ -804,16 +807,19 @@ static unsigned int imx_tx_empty(struct uart_port *port)
+ static unsigned int imx_get_mctrl(struct uart_port *port)
+ {
+ 	struct imx_port *sport = (struct imx_port *)port;
+-	unsigned int tmp = TIOCM_DSR | TIOCM_CAR;
++	unsigned int tmp = TIOCM_DSR;
++	unsigned usr1 = readl(sport->port.membase + USR1);
+ 
+-	if (readl(sport->port.membase + USR1) & USR1_RTSS)
++	if (usr1 & USR1_RTSS)
+ 		tmp |= TIOCM_CTS;
+ 
+-	if (readl(sport->port.membase + UCR2) & UCR2_CTS)
+-		tmp |= TIOCM_RTS;
++	/* in DCE mode DCDIN is always 0 */
++	if (!(usr1 & USR2_DCDIN))
++		tmp |= TIOCM_CAR;
+ 
+-	if (readl(sport->port.membase + uts_reg(sport)) & UTS_LOOP)
+-		tmp |= TIOCM_LOOP;
++	/* in DCE mode RIIN is always 0 */
++	if (readl(sport->port.membase + USR2) & USR2_RIIN)
++		tmp |= TIOCM_RI;
+ 
+ 	return tmp;
+ }
+@@ -831,6 +837,11 @@ static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl)
+ 		writel(temp, sport->port.membase + UCR2);
+ 	}
+ 
++	temp = readl(sport->port.membase + UCR3) & ~UCR3_DSR;
++	if (!(mctrl & TIOCM_DTR))
++		temp |= UCR3_DSR;
++	writel(temp, sport->port.membase + UCR3);
++
+ 	temp = readl(sport->port.membase + uts_reg(sport)) & ~UTS_LOOP;
+ 	if (mctrl & TIOCM_LOOP)
+ 		temp |= UTS_LOOP;
+-- 
+1.9.1
+
diff --git a/target/linux/imx6/patches-4.4/111-serial-imx-fix-polarity-of-RI.patch b/target/linux/imx6/patches-4.4/111-serial-imx-fix-polarity-of-RI.patch
new file mode 100644
index 0000000..a065575
--- /dev/null
+++ b/target/linux/imx6/patches-4.4/111-serial-imx-fix-polarity-of-RI.patch
@@ -0,0 +1,38 @@
+From 9a061cea4477f26a1dfcc0a08dc20575016e91df Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig at pengutronix.de>
+Date: Thu, 24 Mar 2016 14:24:20 +0100
+Subject: [PATCH 1/3] serial: imx: fix polarity of RI
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When in DTE mode, the bit USR2_RIIN is active low. So invert the logic
+accordingly.
+
+Fixes: 90ebc4838666 ("serial: imx: repair and complete handshaking")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig at pengutronix.de>
+Signed-off-by: Petr Štetiar <ynezz at true.cz>
+---
+ drivers/tty/serial/imx.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
+index 231e7d5..bfc4555 100644
+--- a/drivers/tty/serial/imx.c
++++ b/drivers/tty/serial/imx.c
+@@ -797,9 +797,9 @@ static unsigned int imx_get_hwmctrl(struct imx_port *sport)
+ 	if (!(usr1 & USR2_DCDIN))
+ 		tmp |= TIOCM_CAR;
+ 
+-	/* in DCE mode RIIN is always 0 */
+-	if (readl(sport->port.membase + USR2) & USR2_RIIN)
+-		tmp |= TIOCM_RI;
++	if (sport->dte_mode)
++		if (!(readl(sport->port.membase + USR2) & USR2_RIIN))
++			tmp |= TIOCM_RI;
+ 
+ 	return tmp;
+ }
+-- 
+1.9.1
+
diff --git a/target/linux/imx6/patches-4.4/112-serial-imx-let-irq-handler-return-IRQ_NONE-if-no-eve.patch b/target/linux/imx6/patches-4.4/112-serial-imx-let-irq-handler-return-IRQ_NONE-if-no-eve.patch
new file mode 100644
index 0000000..0b803b7
--- /dev/null
+++ b/target/linux/imx6/patches-4.4/112-serial-imx-let-irq-handler-return-IRQ_NONE-if-no-eve.patch
@@ -0,0 +1,72 @@
+From de4356da2cd1a1857513047997d81143cb95a4e1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig at pengutronix.de>
+Date: Thu, 24 Mar 2016 14:24:21 +0100
+Subject: [PATCH 2/3] serial: imx: let irq handler return IRQ_NONE if no event
+ was handled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This gives the irq core a chance to disable the serial interrupt in case
+an event isn't cleared in the handler.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig at pengutronix.de>
+Signed-off-by: Petr Štetiar <ynezz at true.cz>
+---
+ drivers/tty/serial/imx.c | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
+index bfc4555..5ced61e 100644
+--- a/drivers/tty/serial/imx.c
++++ b/drivers/tty/serial/imx.c
+@@ -734,6 +734,7 @@ static irqreturn_t imx_int(int irq, void *dev_id)
+ 	struct imx_port *sport = dev_id;
+ 	unsigned int sts;
+ 	unsigned int sts2;
++	irqreturn_t ret = IRQ_NONE;
+ 
+ 	sts = readl(sport->port.membase + USR1);
+ 	sts2 = readl(sport->port.membase + USR2);
+@@ -743,26 +744,34 @@ static irqreturn_t imx_int(int irq, void *dev_id)
+ 			imx_dma_rxint(sport);
+ 		else
+ 			imx_rxint(irq, dev_id);
++		ret = IRQ_HANDLED;
+ 	}
+ 
+ 	if ((sts & USR1_TRDY &&
+ 	     readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN) ||
+ 	    (sts2 & USR2_TXDC &&
+-	     readl(sport->port.membase + UCR4) & UCR4_TCEN))
++	     readl(sport->port.membase + UCR4) & UCR4_TCEN)) {
+ 		imx_txint(irq, dev_id);
++		ret = IRQ_HANDLED;
++	}
+ 
+-	if (sts & USR1_RTSD)
++	if (sts & USR1_RTSD) {
+ 		imx_rtsint(irq, dev_id);
++		ret = IRQ_HANDLED;
++	}
+ 
+-	if (sts & USR1_AWAKE)
++	if (sts & USR1_AWAKE) {
+ 		writel(USR1_AWAKE, sport->port.membase + USR1);
++		ret = IRQ_HANDLED;
++	}
+ 
+ 	if (sts2 & USR2_ORE) {
+ 		sport->port.icount.overrun++;
+ 		writel(USR2_ORE, sport->port.membase + USR2);
++		ret = IRQ_HANDLED;
+ 	}
+ 
+-	return IRQ_HANDLED;
++	return ret;
+ }
+ 
+ /*
+-- 
+1.9.1
+
diff --git a/target/linux/imx6/patches-4.4/113-serial-imx-make-sure-unhandled-irqs-are-disabled.patch b/target/linux/imx6/patches-4.4/113-serial-imx-make-sure-unhandled-irqs-are-disabled.patch
new file mode 100644
index 0000000..8978d33
--- /dev/null
+++ b/target/linux/imx6/patches-4.4/113-serial-imx-make-sure-unhandled-irqs-are-disabled.patch
@@ -0,0 +1,61 @@
+From a58c6360b9eb3a2374b0b069ba9ce7baec0f26df Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig at pengutronix.de>
+Date: Thu, 24 Mar 2016 14:24:22 +0100
+Subject: [PATCH 3/3] serial: imx: make sure unhandled irqs are disabled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Make sure that events that are not handled in the irq function don't
+trigger an interrupt.
+
+When the serial port is operated in DTE mode, the events for DCD and RI
+events are enabled after a system reset by default.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig at pengutronix.de>
+Signed-off-by: Petr Štetiar <ynezz at true.cz>
+---
+ drivers/tty/serial/imx.c | 23 ++++++++++++++++++++++-
+ 1 file changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
+index 5ced61e..fcd48fd 100644
+--- a/drivers/tty/serial/imx.c
++++ b/drivers/tty/serial/imx.c
+@@ -1221,11 +1221,32 @@ static int imx_startup(struct uart_port *port)
+ 	temp |= (UCR2_RXEN | UCR2_TXEN);
+ 	if (!sport->have_rtscts)
+ 		temp |= UCR2_IRTS;
++	/*
++	 * make sure the edge sensitive RTS-irq is disabled,
++	 * we're using RTSD instead.
++	 */
++	if (!is_imx1_uart(sport))
++		temp &= ~UCR2_RTSEN;
+ 	writel(temp, sport->port.membase + UCR2);
+ 
+ 	if (!is_imx1_uart(sport)) {
+ 		temp = readl(sport->port.membase + UCR3);
+-		temp |= IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP;
++
++		/*
++		 * The effect of RI and DCD differs depending on the UFCR_DCEDTE
++		 * bit. In DCE mode they control the outputs, in DTE mode they
++		 * enable the respective irqs. At least the DCD irq cannot be
++		 * cleared on i.MX25 at least, so it's not usable and must be
++		 * disabled. I don't have test hardware to check if RI has the
++		 * same problem but I consider this likely so it's disabled for
++		 * now, too.
++		 */
++		temp |= IMX21_UCR3_RXDMUXSEL | UCR3_ADNIMP |
++			UCR3_RI | UCR3_DCD;
++
++		if (sport->dte_mode)
++			temp &= ~(UCR3_RI | UCR3_DCD);
++
+ 		writel(temp, sport->port.membase + UCR3);
+ 	}
+ 
+-- 
+1.9.1
+
-- 
1.9.1




More information about the Lede-dev mailing list