[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