linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/7] serial: imx: drop members from driver data that are only used during probe
@ 2015-02-18 20:41 Uwe Kleine-König
  2015-02-18 20:41 ` [PATCH 2/7] serial: imx: reformat and cleanup copyright header Uwe Kleine-König
                   ` (6 more replies)
  0 siblings, 7 replies; 16+ messages in thread
From: Uwe Kleine-König @ 2015-02-18 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

There is no benefit in keeping this information in RAM when it's not
used any more, so better use function local variables instead.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
 drivers/tty/serial/imx.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 4c5e9092e2d7..d6da02210919 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -205,7 +205,6 @@ struct imx_port {
 	struct uart_port	port;
 	struct timer_list	timer;
 	unsigned int		old_status;
-	int			txirq, rxirq, rtsirq;
 	unsigned int		have_rtscts:1;
 	unsigned int		dte_mode:1;
 	unsigned int		use_irda:1;
@@ -1851,6 +1850,7 @@ static int serial_imx_probe(struct platform_device *pdev)
 	void __iomem *base;
 	int ret = 0;
 	struct resource *res;
+	int txirq, rxirq, rtsirq;
 
 	sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL);
 	if (!sport)
@@ -1867,15 +1867,16 @@ static int serial_imx_probe(struct platform_device *pdev)
 	if (IS_ERR(base))
 		return PTR_ERR(base);
 
+	rxirq = platform_get_irq(pdev, 0);
+	txirq = platform_get_irq(pdev, 1);
+	rtsirq = platform_get_irq(pdev, 2);
+
 	sport->port.dev = &pdev->dev;
 	sport->port.mapbase = res->start;
 	sport->port.membase = base;
 	sport->port.type = PORT_IMX,
 	sport->port.iotype = UPIO_MEM;
-	sport->port.irq = platform_get_irq(pdev, 0);
-	sport->rxirq = platform_get_irq(pdev, 0);
-	sport->txirq = platform_get_irq(pdev, 1);
-	sport->rtsirq = platform_get_irq(pdev, 2);
+	sport->port.irq = rxirq;
 	sport->port.fifosize = 32;
 	sport->port.ops = &imx_pops;
 	sport->port.flags = UPF_BOOT_AUTOCONF;
@@ -1903,27 +1904,27 @@ static int serial_imx_probe(struct platform_device *pdev)
 	 * Allocate the IRQ(s) i.MX1 has three interrupts whereas later
 	 * chips only have one interrupt.
 	 */
-	if (sport->txirq > 0) {
-		ret = devm_request_irq(&pdev->dev, sport->rxirq, imx_rxint, 0,
+	if (txirq > 0) {
+		ret = devm_request_irq(&pdev->dev, rxirq, imx_rxint, 0,
 				       dev_name(&pdev->dev), sport);
 		if (ret)
 			return ret;
 
-		ret = devm_request_irq(&pdev->dev, sport->txirq, imx_txint, 0,
+		ret = devm_request_irq(&pdev->dev, txirq, imx_txint, 0,
 				       dev_name(&pdev->dev), sport);
 		if (ret)
 			return ret;
 
 		/* do not use RTS IRQ on IrDA */
 		if (!USE_IRDA(sport)) {
-			ret = devm_request_irq(&pdev->dev, sport->rtsirq,
+			ret = devm_request_irq(&pdev->dev, rtsirq,
 					       imx_rtsint, 0,
 					       dev_name(&pdev->dev), sport);
 			if (ret)
 				return ret;
 		}
 	} else {
-		ret = devm_request_irq(&pdev->dev, sport->port.irq, imx_int, 0,
+		ret = devm_request_irq(&pdev->dev, rxirq, imx_int, 0,
 				       dev_name(&pdev->dev), sport);
 		if (ret)
 			return ret;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/7] serial: imx: reformat and cleanup copyright header
  2015-02-18 20:41 [PATCH 1/7] serial: imx: drop members from driver data that are only used during probe Uwe Kleine-König
@ 2015-02-18 20:41 ` Uwe Kleine-König
  2015-02-18 20:41 ` [PATCH 3/7] serial: imx: fix comment about which machines use the i.MX21 type Uwe Kleine-König
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Uwe Kleine-König @ 2015-02-18 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

Fix indention, remove old address of the FSF, remove in-file changelog,
mention Freescale.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
 drivers/tty/serial/imx.c | 19 ++++++-------------
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index d6da02210919..8ab52ed15917 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1,13 +1,13 @@
 /*
- *  Driver for Motorola IMX serial ports
+ * Driver for Motorola/Freescale IMX serial ports
  *
- *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
  *
- *  Author: Sascha Hauer <sascha@saschahauer.de>
- *  Copyright (C) 2004 Pengutronix
+ * Author: Sascha Hauer <sascha@saschahauer.de>
+ * Copyright (C) 2004 Pengutronix
  *
- *  Copyright (C) 2009 emlix GmbH
- *  Author: Fabian Godehardt (added IrDA support for iMX)
+ * Author: Fabian Godehardt (added IrDA support for iMX)
+ * Copyright (C) 2009 emlix GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -18,13 +18,6 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * [29-Mar-2005] Mike Lee
- * Added hardware handshake
  */
 
 #if defined(CONFIG_SERIAL_IMX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 3/7] serial: imx: fix comment about which machines use the i.MX21 type
  2015-02-18 20:41 [PATCH 1/7] serial: imx: drop members from driver data that are only used during probe Uwe Kleine-König
  2015-02-18 20:41 ` [PATCH 2/7] serial: imx: reformat and cleanup copyright header Uwe Kleine-König
@ 2015-02-18 20:41 ` Uwe Kleine-König
  2015-02-18 20:41 ` [PATCH 4/7] serial: imx: drop support for IRDA Uwe Kleine-König
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Uwe Kleine-König @ 2015-02-18 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
 drivers/tty/serial/imx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 8ab52ed15917..cf1a612435cc 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -181,7 +181,7 @@
 
 #define UART_NR 8
 
-/* i.mx21 type uart runs on all i.mx except i.mx1 */
+/* i.MX21 type uart runs on all i.mx except i.MX1 and i.MX6q */
 enum imx_uart_type {
 	IMX1_UART,
 	IMX21_UART,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 4/7] serial: imx: drop support for IRDA
  2015-02-18 20:41 [PATCH 1/7] serial: imx: drop members from driver data that are only used during probe Uwe Kleine-König
  2015-02-18 20:41 ` [PATCH 2/7] serial: imx: reformat and cleanup copyright header Uwe Kleine-König
  2015-02-18 20:41 ` [PATCH 3/7] serial: imx: fix comment about which machines use the i.MX21 type Uwe Kleine-König
@ 2015-02-18 20:41 ` Uwe Kleine-König
  2015-02-18 21:16   ` Fabio Estevam
  2015-02-18 20:41 ` [PATCH 5/7] serial: imx: Fix handling of receiver overrun Uwe Kleine-König
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Uwe Kleine-König @ 2015-02-18 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

Support for IRDA was added in 2009 in commit v2.6.31-rc1~399^2~2. There
are no in-tree users.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
Cc: Oskar Schirmer <os@emlix.com>
---
 drivers/tty/serial/imx.c | 156 +++--------------------------------------------
 1 file changed, 9 insertions(+), 147 deletions(-)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index cf1a612435cc..587f7b3075e4 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -6,9 +6,6 @@
  * Author: Sascha Hauer <sascha@saschahauer.de>
  * Copyright (C) 2004 Pengutronix
  *
- * Author: Fabian Godehardt (added IrDA support for iMX)
- * Copyright (C) 2009 emlix GmbH
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -200,7 +197,6 @@ struct imx_port {
 	unsigned int		old_status;
 	unsigned int		have_rtscts:1;
 	unsigned int		dte_mode:1;
-	unsigned int		use_irda:1;
 	unsigned int		irda_inv_rx:1;
 	unsigned int		irda_inv_tx:1;
 	unsigned short		trcv_delay; /* transceiver delay */
@@ -227,12 +223,6 @@ struct imx_port_ucrs {
 	unsigned int	ucr3;
 };
 
-#ifdef CONFIG_IRDA
-#define USE_IRDA(sport)	((sport)->use_irda)
-#else
-#define USE_IRDA(sport)	(0)
-#endif
-
 static struct imx_uart_data imx_uart_devdata[] = {
 	[IMX1_UART] = {
 		.uts_reg = IMX1_UTS,
@@ -367,48 +357,6 @@ static void imx_stop_tx(struct uart_port *port)
 	struct imx_port *sport = (struct imx_port *)port;
 	unsigned long temp;
 
-	if (USE_IRDA(sport)) {
-		/* half duplex - wait for end of transmission */
-		int n = 256;
-		while ((--n > 0) &&
-		      !(readl(sport->port.membase + USR2) & USR2_TXDC)) {
-			udelay(5);
-			barrier();
-		}
-		/*
-		 * irda transceiver - wait a bit more to avoid
-		 * cutoff, hardware dependent
-		 */
-		udelay(sport->trcv_delay);
-
-		/*
-		 * half duplex - reactivate receive mode,
-		 * flush receive pipe echo crap
-		 */
-		if (readl(sport->port.membase + USR2) & USR2_TXDC) {
-			temp = readl(sport->port.membase + UCR1);
-			temp &= ~(UCR1_TXMPTYEN | UCR1_TRDYEN);
-			writel(temp, sport->port.membase + UCR1);
-
-			temp = readl(sport->port.membase + UCR4);
-			temp &= ~(UCR4_TCEN);
-			writel(temp, sport->port.membase + UCR4);
-
-			while (readl(sport->port.membase + URXD0) &
-			       URXD_CHARRDY)
-				barrier();
-
-			temp = readl(sport->port.membase + UCR1);
-			temp |= UCR1_RRDYEN;
-			writel(temp, sport->port.membase + UCR1);
-
-			temp = readl(sport->port.membase + UCR4);
-			temp |= UCR4_DREN;
-			writel(temp, sport->port.membase + UCR4);
-		}
-		return;
-	}
-
 	/*
 	 * We are maybe in the SMP context, so if the DMA TX thread is running
 	 * on other cpu, we have to wait for it to finish.
@@ -572,16 +520,6 @@ static void imx_start_tx(struct uart_port *port)
 	struct imx_port *sport = (struct imx_port *)port;
 	unsigned long temp;
 
-	if (USE_IRDA(sport)) {
-		/* half duplex in IrDA mode; have to disable receive mode */
-		temp = readl(sport->port.membase + UCR4);
-		temp &= ~(UCR4_DREN);
-		writel(temp, sport->port.membase + UCR4);
-
-		temp = readl(sport->port.membase + UCR1);
-		temp &= ~(UCR1_RRDYEN);
-		writel(temp, sport->port.membase + UCR1);
-	}
 	/* Clear any pending ORE flag before enabling interrupt */
 	temp = readl(sport->port.membase + USR2);
 	writel(temp | USR2_ORE, sport->port.membase + USR2);
@@ -595,16 +533,6 @@ static void imx_start_tx(struct uart_port *port)
 		writel(temp | UCR1_TXMPTYEN, sport->port.membase + UCR1);
 	}
 
-	if (USE_IRDA(sport)) {
-		temp = readl(sport->port.membase + UCR1);
-		temp |= UCR1_TRDYEN;
-		writel(temp, sport->port.membase + UCR1);
-
-		temp = readl(sport->port.membase + UCR4);
-		temp |= UCR4_TCEN;
-		writel(temp, sport->port.membase + UCR4);
-	}
-
 	if (sport->dma_is_enabled) {
 		/* FIXME: port->x_char must be transmitted if != 0 */
 		if (!uart_circ_empty(&port->state->xmit) &&
@@ -1081,9 +1009,6 @@ static int imx_startup(struct uart_port *port)
 	 */
 	temp = readl(sport->port.membase + UCR4);
 
-	if (USE_IRDA(sport))
-		temp |= UCR4_IRSC;
-
 	/* set the trigger level for CTS */
 	temp &= ~(UCR4_CTSTL_MASK << UCR4_CTSTL_SHF);
 	temp |= CTSTL << UCR4_CTSTL_SHF;
@@ -1109,11 +1034,6 @@ static int imx_startup(struct uart_port *port)
 	temp = readl(sport->port.membase + UCR1);
 	temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN;
 
-	if (USE_IRDA(sport)) {
-		temp |= UCR1_IREN;
-		temp &= ~(UCR1_RTSDEN);
-	}
-
 	writel(temp, sport->port.membase + UCR1);
 
 	temp = readl(sport->port.membase + UCR2);
@@ -1128,38 +1048,12 @@ static int imx_startup(struct uart_port *port)
 		writel(temp, sport->port.membase + UCR3);
 	}
 
-	if (USE_IRDA(sport)) {
-		temp = readl(sport->port.membase + UCR4);
-		if (sport->irda_inv_rx)
-			temp |= UCR4_INVR;
-		else
-			temp &= ~(UCR4_INVR);
-		writel(temp | UCR4_DREN, sport->port.membase + UCR4);
-
-		temp = readl(sport->port.membase + UCR3);
-		if (sport->irda_inv_tx)
-			temp |= UCR3_INVT;
-		else
-			temp &= ~(UCR3_INVT);
-		writel(temp, sport->port.membase + UCR3);
-	}
-
 	/*
 	 * Enable modem status interrupts
 	 */
 	imx_enable_ms(&sport->port);
 	spin_unlock_irqrestore(&sport->port.lock, flags);
 
-	if (USE_IRDA(sport)) {
-		struct imxuart_platform_data *pdata;
-		pdata = dev_get_platdata(sport->port.dev);
-		sport->irda_inv_rx = pdata->irda_inv_rx;
-		sport->irda_inv_tx = pdata->irda_inv_tx;
-		sport->trcv_delay = pdata->transceiver_delay;
-		if (pdata->irda_enable)
-			pdata->irda_enable(1);
-	}
-
 	return 0;
 }
 
@@ -1193,13 +1087,6 @@ static void imx_shutdown(struct uart_port *port)
 	writel(temp, sport->port.membase + UCR2);
 	spin_unlock_irqrestore(&sport->port.lock, flags);
 
-	if (USE_IRDA(sport)) {
-		struct imxuart_platform_data *pdata;
-		pdata = dev_get_platdata(sport->port.dev);
-		if (pdata->irda_enable)
-			pdata->irda_enable(0);
-	}
-
 	/*
 	 * Stop our timer.
 	 */
@@ -1212,8 +1099,6 @@ static void imx_shutdown(struct uart_port *port)
 	spin_lock_irqsave(&sport->port.lock, flags);
 	temp = readl(sport->port.membase + UCR1);
 	temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
-	if (USE_IRDA(sport))
-		temp &= ~(UCR1_IREN);
 
 	writel(temp, sport->port.membase + UCR1);
 	spin_unlock_irqrestore(&sport->port.lock, flags);
@@ -1343,24 +1228,16 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
 			sport->port.membase + UCR2);
 	old_txrxen &= (UCR2_TXEN | UCR2_RXEN);
 
-	if (USE_IRDA(sport)) {
-		/*
-		 * use maximum available submodule frequency to
-		 * avoid missing short pulses due to low sampling rate
-		 */
+	/* custom-baudrate handling */
+	div = sport->port.uartclk / (baud * 16);
+	if (baud == 38400 && quot != div)
+		baud = sport->port.uartclk / (quot * 16);
+
+	div = sport->port.uartclk / (baud * 16);
+	if (div > 7)
+		div = 7;
+	if (!div)
 		div = 1;
-	} else {
-		/* custom-baudrate handling */
-		div = sport->port.uartclk / (baud * 16);
-		if (baud == 38400 && quot != div)
-			baud = sport->port.uartclk / (quot * 16);
-
-		div = sport->port.uartclk / (baud * 16);
-		if (div > 7)
-			div = 7;
-		if (!div)
-			div = 1;
-	}
 
 	rational_best_approximation(16 * div * baud, sport->port.uartclk,
 		1 << 16, 1 << 16, &num, &denom);
@@ -1801,9 +1678,6 @@ static int serial_imx_probe_dt(struct imx_port *sport,
 	if (of_get_property(np, "fsl,uart-has-rtscts", NULL))
 		sport->have_rtscts = 1;
 
-	if (of_get_property(np, "fsl,irda-mode", NULL))
-		sport->use_irda = 1;
-
 	if (of_get_property(np, "fsl,dte-mode", NULL))
 		sport->dte_mode = 1;
 
@@ -1832,9 +1706,6 @@ static void serial_imx_probe_pdata(struct imx_port *sport,
 
 	if (pdata->flags & IMXUART_HAVE_RTSCTS)
 		sport->have_rtscts = 1;
-
-	if (pdata->flags & IMXUART_IRDA)
-		sport->use_irda = 1;
 }
 
 static int serial_imx_probe(struct platform_device *pdev)
@@ -1907,15 +1778,6 @@ static int serial_imx_probe(struct platform_device *pdev)
 				       dev_name(&pdev->dev), sport);
 		if (ret)
 			return ret;
-
-		/* do not use RTS IRQ on IrDA */
-		if (!USE_IRDA(sport)) {
-			ret = devm_request_irq(&pdev->dev, rtsirq,
-					       imx_rtsint, 0,
-					       dev_name(&pdev->dev), sport);
-			if (ret)
-				return ret;
-		}
 	} else {
 		ret = devm_request_irq(&pdev->dev, rxirq, imx_int, 0,
 				       dev_name(&pdev->dev), sport);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 5/7] serial: imx: Fix handling of receiver overrun
  2015-02-18 20:41 [PATCH 1/7] serial: imx: drop members from driver data that are only used during probe Uwe Kleine-König
                   ` (2 preceding siblings ...)
  2015-02-18 20:41 ` [PATCH 4/7] serial: imx: drop support for IRDA Uwe Kleine-König
@ 2015-02-18 20:41 ` Uwe Kleine-König
  2015-02-18 20:41 ` [PATCH 6/7] serial: imx: remove long dead code Uwe Kleine-König
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Uwe Kleine-König @ 2015-02-18 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

The ORE bit only signals overflow of the receiver fifo, so the
respective interrupt should be enabled in the startup callback instead
of the start_tx callback.

Moreover the writeable bits in the USR2 register are all "write 1 to
clear", so only write the bits that actually should be cleared.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
Hello,

a colleague asked me to split this patch into two. i.e. move ORE handling to
.startup + fixing acknowledge. But line 526

	writel(temp | USR2_ORE, sport->port.membase + USR2);

suffers from both problems, and so would need to be touched twice. So I kept
both changes in a single patch.

Best regards
Uwe

 drivers/tty/serial/imx.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 587f7b3075e4..985a1178911c 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -520,14 +520,6 @@ static void imx_start_tx(struct uart_port *port)
 	struct imx_port *sport = (struct imx_port *)port;
 	unsigned long temp;
 
-	/* Clear any pending ORE flag before enabling interrupt */
-	temp = readl(sport->port.membase + USR2);
-	writel(temp | USR2_ORE, sport->port.membase + USR2);
-
-	temp = readl(sport->port.membase + UCR4);
-	temp |= UCR4_OREN;
-	writel(temp, sport->port.membase + UCR4);
-
 	if (!sport->dma_is_enabled) {
 		temp = readl(sport->port.membase + UCR1);
 		writel(temp | UCR1_TXMPTYEN, sport->port.membase + UCR1);
@@ -691,7 +683,7 @@ static irqreturn_t imx_int(int irq, void *dev_id)
 	if (sts2 & USR2_ORE) {
 		dev_err(sport->port.dev, "Rx FIFO overrun\n");
 		sport->port.icount.overrun++;
-		writel(sts2 | USR2_ORE, sport->port.membase + USR2);
+		writel(USR2_ORE, sport->port.membase + USR2);
 	}
 
 	return IRQ_HANDLED;
@@ -1026,16 +1018,21 @@ static int imx_startup(struct uart_port *port)
 		udelay(1);
 
 	spin_lock_irqsave(&sport->port.lock, flags);
+
 	/*
 	 * Finally, clear and enable interrupts
 	 */
 	writel(USR1_RTSD, sport->port.membase + USR1);
+	writel(USR2_ORE, sport->port.membase + USR2);
 
 	temp = readl(sport->port.membase + UCR1);
 	temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN;
-
 	writel(temp, sport->port.membase + UCR1);
 
+	temp = read(sport->port.membase + UCR4);
+	temp |= UCR4_OREN;
+	writel(temp, sport->port.membase + UCR4);
+
 	temp = readl(sport->port.membase + UCR2);
 	temp |= (UCR2_RXEN | UCR2_TXEN);
 	if (!sport->have_rtscts)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 6/7] serial: imx: remove long dead code
  2015-02-18 20:41 [PATCH 1/7] serial: imx: drop members from driver data that are only used during probe Uwe Kleine-König
                   ` (3 preceding siblings ...)
  2015-02-18 20:41 ` [PATCH 5/7] serial: imx: Fix handling of receiver overrun Uwe Kleine-König
@ 2015-02-18 20:41 ` Uwe Kleine-König
  2015-02-18 20:41 ` [PATCH 7/7] serial: imx: add support for half duplex rs485 Uwe Kleine-König
  2015-02-21  8:58 ` [PATCH 1/7] serial: imx: drop members from driver data that are only used during probe Uwe Kleine-König
  6 siblings, 0 replies; 16+ messages in thread
From: Uwe Kleine-König @ 2015-02-18 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

This if (0) exists since the driver was introduced in commit
c49bde83eb6a ([ARM PATCH] 1956/2: Re: Motorola i.MX serial driver)
back in 2004.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
 drivers/tty/serial/imx.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 985a1178911c..806b3cfb7f55 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1127,15 +1127,6 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
 	uint64_t tdiv64;
 
 	/*
-	 * If we don't support modem control lines, don't allow
-	 * these to be set.
-	 */
-	if (0) {
-		termios->c_cflag &= ~(HUPCL | CRTSCTS | CMSPAR);
-		termios->c_cflag |= CLOCAL;
-	}
-
-	/*
 	 * We only support CS7 and CS8.
 	 */
 	while ((termios->c_cflag & CSIZE) != CS7 &&
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 7/7] serial: imx: add support for half duplex rs485
  2015-02-18 20:41 [PATCH 1/7] serial: imx: drop members from driver data that are only used during probe Uwe Kleine-König
                   ` (4 preceding siblings ...)
  2015-02-18 20:41 ` [PATCH 6/7] serial: imx: remove long dead code Uwe Kleine-König
@ 2015-02-18 20:41 ` Uwe Kleine-König
  2015-02-18 22:09   ` [PATCH 7'/7] fixup! " Uwe Kleine-König
  2015-02-19  9:15   ` [PATCH 7/7] " aurélien bouin
  2015-02-21  8:58 ` [PATCH 1/7] serial: imx: drop members from driver data that are only used during probe Uwe Kleine-König
  6 siblings, 2 replies; 16+ messages in thread
From: Uwe Kleine-König @ 2015-02-18 20:41 UTC (permalink / raw)
  To: linux-arm-kernel

The transmitter is expected to be controlled by the UART's RTS pin.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
 drivers/tty/serial/imx.c | 94 +++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 81 insertions(+), 13 deletions(-)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 806b3cfb7f55..ad43019a4880 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -364,8 +364,20 @@ static void imx_stop_tx(struct uart_port *port)
 	if (sport->dma_is_enabled && sport->dma_is_txing)
 		return;
 
-	temp = readl(sport->port.membase + UCR1);
-	writel(temp & ~UCR1_TXMPTYEN, sport->port.membase + UCR1);
+	temp = readl(port->membase + UCR1);
+	writel(temp & ~UCR1_TXMPTYEN, port->membase + UCR1);
+
+	/* in rs485 mode disable transmitter if shifter is empty */
+	if (port->rs485.flags & SER_RS485_ENABLED &&
+	    readl(port->membase + USR2) & USR2_TXDC) {
+		temp = readl(port->membase + UCR2);
+		temp |= UCR2_CTS;
+		writel(temp, port->membase + UCR2);
+
+		temp = readl(port->membase + UCR4);
+		temp &= ~UCR4_TCEN;
+		writel(temp, port->membase + UCR4);
+	}
 }
 
 /*
@@ -520,6 +532,17 @@ static void imx_start_tx(struct uart_port *port)
 	struct imx_port *sport = (struct imx_port *)port;
 	unsigned long temp;
 
+	if (port->rs485.flags & SER_RS485_ENABLED) {
+		/* enable transmitter and shifter empty irq */
+		temp = readl(port->membase + UCR2);
+		temp &= ~UCR2_CTS;
+		writel(temp, port->membase + UCR2);
+
+		temp = readl(port->membase + UCR4);
+		temp |= UCR4_TCEN;
+		writel(temp, port->membase + UCR4);
+	}
+
 	if (!sport->dma_is_enabled) {
 		temp = readl(sport->port.membase + UCR1);
 		writel(temp | UCR1_TXMPTYEN, sport->port.membase + UCR1);
@@ -661,6 +684,7 @@ static irqreturn_t imx_int(int irq, void *dev_id)
 	unsigned int sts2;
 
 	sts = readl(sport->port.membase + USR1);
+	sts2 = readl(sport->port.membase + USR2);
 
 	if (sts & USR1_RRDY) {
 		if (sport->dma_is_enabled)
@@ -669,8 +693,10 @@ static irqreturn_t imx_int(int irq, void *dev_id)
 			imx_rxint(irq, dev_id);
 	}
 
-	if (sts & USR1_TRDY &&
-			readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN)
+	if ((sts & USR1_TRDY &&
+	     readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN) ||
+	    (sts2 & USR2_TXDC &&
+	     readl(sport->port.membase + UCR4) & UCR4_TCEN))
 		imx_txint(irq, dev_id);
 
 	if (sts & USR1_RTSD)
@@ -679,7 +705,6 @@ static irqreturn_t imx_int(int irq, void *dev_id)
 	if (sts & USR1_AWAKE)
 		writel(USR1_AWAKE, sport->port.membase + USR1);
 
-	sts2 = readl(sport->port.membase + USR2);
 	if (sts2 & USR2_ORE) {
 		dev_err(sport->port.dev, "Rx FIFO overrun\n");
 		sport->port.icount.overrun++;
@@ -731,11 +756,13 @@ static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl)
 	struct imx_port *sport = (struct imx_port *)port;
 	unsigned long temp;
 
-	temp = readl(sport->port.membase + UCR2) & ~(UCR2_CTS | UCR2_CTSC);
-	if (mctrl & TIOCM_RTS)
-		temp |= UCR2_CTS | UCR2_CTSC;
-
-	writel(temp, sport->port.membase + UCR2);
+	if (!(port->rs485.flags & SER_RS485_ENABLED)) {
+		temp = readl(sport->port.membase + UCR2);
+		temp &= ~(UCR2_CTS | UCR2_CTSC);
+		if (mctrl & TIOCM_RTS)
+			temp |= UCR2_CTS | UCR2_CTSC;
+		writel(temp, sport->port.membase + UCR2);
+	}
 
 	temp = readl(sport->port.membase + uts_reg(sport)) & ~UTS_LOOP;
 	if (mctrl & TIOCM_LOOP)
@@ -1029,7 +1056,7 @@ static int imx_startup(struct uart_port *port)
 	temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN;
 	writel(temp, sport->port.membase + UCR1);
 
-	temp = read(sport->port.membase + UCR4);
+	temp = readl(sport->port.membase + UCR4);
 	temp |= UCR4_OREN;
 	writel(temp, sport->port.membase + UCR4);
 
@@ -1144,7 +1171,17 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
 	if (termios->c_cflag & CRTSCTS) {
 		if (sport->have_rtscts) {
 			ucr2 &= ~UCR2_IRTS;
-			ucr2 |= UCR2_CTSC;
+
+			if (port->rs485.flags & SER_RS485_ENABLED)
+				/*
+				 * RTS is mandatory for rs485 operation, so keep
+				 * it under manual control and keep transmitter
+				 * disabled.
+				 */
+				ucr2 |= UCR2_CTS;
+			else
+				ucr2 |= UCR2_CTSC;
+
 
 			/* Can we enable the DMA support? */
 			if (is_imx6q_uart(sport) && !uart_console(port)
@@ -1153,7 +1190,9 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
 		} else {
 			termios->c_cflag &= ~CRTSCTS;
 		}
-	}
+	} else if (port->rs485.flags & SER_RS485_ENABLED)
+		/* disable transmitter */
+		ucr2 |= UCR2_CTS;
 
 	if (termios->c_cflag & CSTOPB)
 		ucr2 |= UCR2_STPB;
@@ -1374,6 +1413,34 @@ static void imx_poll_put_char(struct uart_port *port, unsigned char c)
 }
 #endif
 
+static int imx_rs485_config(struct uart_port *port,
+			    struct serial_rs485 *rs485conf)
+{
+	struct imx_port *sport = (struct imx_port *)port;
+
+	/* unimplemented */
+	rs485conf->delay_rts_before_send = 0;
+	rs485conf->delay_rts_after_send = 0;
+
+	/* RTS is required to control the transmitter */
+	if (!sport->have_rtscts)
+		rs485conf->flags &= ~SER_RS485_ENABLED;
+
+	if (rs485conf->flags & SER_RS485_ENABLED) {
+		unsigned long temp;
+
+		/* disable transmitter */
+		temp = readl(sport->port.membase + UCR2);
+		temp &= ~UCR2_CTSC;
+		temp |= UCR2_CTS;
+		writel(temp, sport->port.membase + UCR2);
+	}
+
+	port->rs485 = *rs485conf;
+
+	return 0;
+}
+
 static struct uart_ops imx_pops = {
 	.tx_empty	= imx_tx_empty,
 	.set_mctrl	= imx_set_mctrl,
@@ -1731,6 +1798,7 @@ static int serial_imx_probe(struct platform_device *pdev)
 	sport->port.irq = rxirq;
 	sport->port.fifosize = 32;
 	sport->port.ops = &imx_pops;
+	sport->port.rs485_config = imx_rs485_config;
 	sport->port.flags = UPF_BOOT_AUTOCONF;
 	init_timer(&sport->timer);
 	sport->timer.function = imx_timeout;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 4/7] serial: imx: drop support for IRDA
  2015-02-18 20:41 ` [PATCH 4/7] serial: imx: drop support for IRDA Uwe Kleine-König
@ 2015-02-18 21:16   ` Fabio Estevam
  2015-02-18 22:06     ` Uwe Kleine-König
  0 siblings, 1 reply; 16+ messages in thread
From: Fabio Estevam @ 2015-02-18 21:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

On Wed, Feb 18, 2015 at 6:41 PM, Uwe Kleine-K?nig
<u.kleine-koenig@pengutronix.de> wrote:
> Support for IRDA was added in 2009 in commit v2.6.31-rc1~399^2~2. There
> are no in-tree users.

'fsl,irda-mode' is still documented at
Documentation/devicetree/bindings/serial/fsl-imx-uart.txt .

Is the irda support broken?

Maybe there are people using it in out-of-tree dts files?

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 4/7] serial: imx: drop support for IRDA
  2015-02-18 21:16   ` Fabio Estevam
@ 2015-02-18 22:06     ` Uwe Kleine-König
  0 siblings, 0 replies; 16+ messages in thread
From: Uwe Kleine-König @ 2015-02-18 22:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hey Fabio,

On Wed, Feb 18, 2015 at 07:16:39PM -0200, Fabio Estevam wrote:
> On Wed, Feb 18, 2015 at 6:41 PM, Uwe Kleine-K?nig
> <u.kleine-koenig@pengutronix.de> wrote:
> > Support for IRDA was added in 2009 in commit v2.6.31-rc1~399^2~2. There
> > are no in-tree users.
> 
> 'fsl,irda-mode' is still documented at
> Documentation/devicetree/bindings/serial/fsl-imx-uart.txt .
I wondered if I should remove it but decided to not do that for
compatibility reasons. The driver not supporting it any more is a
different thing.

> Is the irda support broken?
It is (was) inconsitent and did some things in strange ways. For example
instead of disabling RC it only disabled the corresponding irqs and
flushed the fifo before reenabling. I couldn't test it because I don't
have such hardware though.

> Maybe there are people using it in out-of-tree dts files?
I expect them to cry at some point if they exist. In this case I'm
willing to help them to reinstanciate support for it.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 7'/7] fixup! serial: imx: add support for half duplex rs485
  2015-02-18 20:41 ` [PATCH 7/7] serial: imx: add support for half duplex rs485 Uwe Kleine-König
@ 2015-02-18 22:09   ` Uwe Kleine-König
  2015-02-19  9:15   ` [PATCH 7/7] " aurélien bouin
  1 sibling, 0 replies; 16+ messages in thread
From: Uwe Kleine-König @ 2015-02-18 22:09 UTC (permalink / raw)
  To: linux-arm-kernel

---
Hello,

can you please squash this patch into patch 7/7? It adds support for handling
the rs485 flags that I found in my notes after sending out the series.

If you prefer me to send the whole patch 7 instead please tell me.

Best regards
Uwe

 drivers/tty/serial/imx.c | 25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index ad43019a4880..44a7b5d570e4 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -371,7 +371,10 @@ static void imx_stop_tx(struct uart_port *port)
 	if (port->rs485.flags & SER_RS485_ENABLED &&
 	    readl(port->membase + USR2) & USR2_TXDC) {
 		temp = readl(port->membase + UCR2);
-		temp |= UCR2_CTS;
+		if (port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
+			temp &= ~UCR2_CTS;
+		else
+			temp |= UCR2_CTS;
 		writel(temp, port->membase + UCR2);
 
 		temp = readl(port->membase + UCR4);
@@ -535,7 +538,10 @@ static void imx_start_tx(struct uart_port *port)
 	if (port->rs485.flags & SER_RS485_ENABLED) {
 		/* enable transmitter and shifter empty irq */
 		temp = readl(port->membase + UCR2);
-		temp &= ~UCR2_CTS;
+		if (port->rs485.flags & SER_RS485_RTS_ON_SEND)
+			temp &= ~UCR2_CTS;
+		else
+			temp |= UCR2_CTS;
 		writel(temp, port->membase + UCR2);
 
 		temp = readl(port->membase + UCR4);
@@ -1178,7 +1184,9 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
 				 * it under manual control and keep transmitter
 				 * disabled.
 				 */
-				ucr2 |= UCR2_CTS;
+				if (!(port->rs485.flags &
+				      SER_RS485_RTS_AFTER_SEND))
+					ucr2 |= UCR2_CTS;
 			else
 				ucr2 |= UCR2_CTSC;
 
@@ -1192,7 +1200,8 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
 		}
 	} else if (port->rs485.flags & SER_RS485_ENABLED)
 		/* disable transmitter */
-		ucr2 |= UCR2_CTS;
+		if (!(port->rs485.flags & SER_RS485_RTS_AFTER_SEND))
+			ucr2 |= UCR2_CTS;
 
 	if (termios->c_cflag & CSTOPB)
 		ucr2 |= UCR2_STPB;
@@ -1421,6 +1430,7 @@ static int imx_rs485_config(struct uart_port *port,
 	/* unimplemented */
 	rs485conf->delay_rts_before_send = 0;
 	rs485conf->delay_rts_after_send = 0;
+	rs485conf->flags |= SER_RS485_RX_DURING_TX;
 
 	/* RTS is required to control the transmitter */
 	if (!sport->have_rtscts)
@@ -1432,7 +1442,10 @@ static int imx_rs485_config(struct uart_port *port,
 		/* disable transmitter */
 		temp = readl(sport->port.membase + UCR2);
 		temp &= ~UCR2_CTSC;
-		temp |= UCR2_CTS;
+		if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND)
+			temp &= ~UCR2_CTS;
+		else
+			temp |= UCR2_CTS;
 		writel(temp, sport->port.membase + UCR2);
 	}
 
@@ -1799,6 +1812,8 @@ static int serial_imx_probe(struct platform_device *pdev)
 	sport->port.fifosize = 32;
 	sport->port.ops = &imx_pops;
 	sport->port.rs485_config = imx_rs485_config;
+	sport->port.rs485.flags =
+		SER_RS485_RTS_ON_SEND | SER_RS485_RX_DURING_TX;
 	sport->port.flags = UPF_BOOT_AUTOCONF;
 	init_timer(&sport->timer);
 	sport->timer.function = imx_timeout;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 7/7] serial: imx: add support for half duplex rs485
  2015-02-18 20:41 ` [PATCH 7/7] serial: imx: add support for half duplex rs485 Uwe Kleine-König
  2015-02-18 22:09   ` [PATCH 7'/7] fixup! " Uwe Kleine-König
@ 2015-02-19  9:15   ` aurélien bouin
  2015-02-19  9:37     ` Uwe Kleine-König
  1 sibling, 1 reply; 16+ messages in thread
From: aurélien bouin @ 2015-02-19  9:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

2015-02-18 21:41 GMT+01:00 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> The transmitter is expected to be controlled by the UART's RTS pin.

You definately can be more open in using the last patch I have sent
the 11th of februrary using rs485.padding[0] that give in parameter
the GPIO to use for transmit pin

> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
> ---
>  drivers/tty/serial/imx.c | 94 +++++++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 81 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index 806b3cfb7f55..ad43019a4880 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -364,8 +364,20 @@ static void imx_stop_tx(struct uart_port *port)
>         if (sport->dma_is_enabled && sport->dma_is_txing)
>                 return;
>
> -       temp = readl(sport->port.membase + UCR1);
> -       writel(temp & ~UCR1_TXMPTYEN, sport->port.membase + UCR1);
> +       temp = readl(port->membase + UCR1);
> +       writel(temp & ~UCR1_TXMPTYEN, port->membase + UCR1);
> +
> +       /* in rs485 mode disable transmitter if shifter is empty */
> +       if (port->rs485.flags & SER_RS485_ENABLED &&
> +           readl(port->membase + USR2) & USR2_TXDC) {
> +               temp = readl(port->membase + UCR2);
> +               temp |= UCR2_CTS;
> +               writel(temp, port->membase + UCR2);
> +
> +               temp = readl(port->membase + UCR4);
> +               temp &= ~UCR4_TCEN;
> +               writel(temp, port->membase + UCR4);
> +       }
>  }
>
>  /*
> @@ -520,6 +532,17 @@ static void imx_start_tx(struct uart_port *port)
>         struct imx_port *sport = (struct imx_port *)port;
>         unsigned long temp;
>
> +       if (port->rs485.flags & SER_RS485_ENABLED) {
> +               /* enable transmitter and shifter empty irq */
> +               temp = readl(port->membase + UCR2);
> +               temp &= ~UCR2_CTS;
> +               writel(temp, port->membase + UCR2);
> +
> +               temp = readl(port->membase + UCR4);
> +               temp |= UCR4_TCEN;
> +               writel(temp, port->membase + UCR4);
> +       }
> +
>         if (!sport->dma_is_enabled) {
>                 temp = readl(sport->port.membase + UCR1);
>                 writel(temp | UCR1_TXMPTYEN, sport->port.membase + UCR1);
> @@ -661,6 +684,7 @@ static irqreturn_t imx_int(int irq, void *dev_id)
>         unsigned int sts2;
>
>         sts = readl(sport->port.membase + USR1);
> +       sts2 = readl(sport->port.membase + USR2);
>
>         if (sts & USR1_RRDY) {
>                 if (sport->dma_is_enabled)
> @@ -669,8 +693,10 @@ static irqreturn_t imx_int(int irq, void *dev_id)
>                         imx_rxint(irq, dev_id);
>         }
>
> -       if (sts & USR1_TRDY &&
> -                       readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN)
> +       if ((sts & USR1_TRDY &&
> +            readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN) ||
> +           (sts2 & USR2_TXDC &&
> +            readl(sport->port.membase + UCR4) & UCR4_TCEN))
>                 imx_txint(irq, dev_id);
>
>         if (sts & USR1_RTSD)
> @@ -679,7 +705,6 @@ static irqreturn_t imx_int(int irq, void *dev_id)
>         if (sts & USR1_AWAKE)
>                 writel(USR1_AWAKE, sport->port.membase + USR1);
>
> -       sts2 = readl(sport->port.membase + USR2);
>         if (sts2 & USR2_ORE) {
>                 dev_err(sport->port.dev, "Rx FIFO overrun\n");
>                 sport->port.icount.overrun++;
> @@ -731,11 +756,13 @@ static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl)
>         struct imx_port *sport = (struct imx_port *)port;
>         unsigned long temp;
>
> -       temp = readl(sport->port.membase + UCR2) & ~(UCR2_CTS | UCR2_CTSC);
> -       if (mctrl & TIOCM_RTS)
> -               temp |= UCR2_CTS | UCR2_CTSC;
> -
> -       writel(temp, sport->port.membase + UCR2);
> +       if (!(port->rs485.flags & SER_RS485_ENABLED)) {
> +               temp = readl(sport->port.membase + UCR2);
> +               temp &= ~(UCR2_CTS | UCR2_CTSC);
> +               if (mctrl & TIOCM_RTS)
> +                       temp |= UCR2_CTS | UCR2_CTSC;
> +               writel(temp, sport->port.membase + UCR2);
> +       }
>
>         temp = readl(sport->port.membase + uts_reg(sport)) & ~UTS_LOOP;
>         if (mctrl & TIOCM_LOOP)
> @@ -1029,7 +1056,7 @@ static int imx_startup(struct uart_port *port)
>         temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN;
>         writel(temp, sport->port.membase + UCR1);
>
> -       temp = read(sport->port.membase + UCR4);
> +       temp = readl(sport->port.membase + UCR4);
>         temp |= UCR4_OREN;
>         writel(temp, sport->port.membase + UCR4);
>
> @@ -1144,7 +1171,17 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
>         if (termios->c_cflag & CRTSCTS) {
>                 if (sport->have_rtscts) {
>                         ucr2 &= ~UCR2_IRTS;
> -                       ucr2 |= UCR2_CTSC;
> +
> +                       if (port->rs485.flags & SER_RS485_ENABLED)
> +                               /*
> +                                * RTS is mandatory for rs485 operation, so keep
> +                                * it under manual control and keep transmitter
> +                                * disabled.
> +                                */
> +                               ucr2 |= UCR2_CTS;
> +                       else
> +                               ucr2 |= UCR2_CTSC;
> +
>
>                         /* Can we enable the DMA support? */
>                         if (is_imx6q_uart(sport) && !uart_console(port)
> @@ -1153,7 +1190,9 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
>                 } else {
>                         termios->c_cflag &= ~CRTSCTS;
>                 }
> -       }
> +       } else if (port->rs485.flags & SER_RS485_ENABLED)
> +               /* disable transmitter */
> +               ucr2 |= UCR2_CTS;
>
>         if (termios->c_cflag & CSTOPB)
>                 ucr2 |= UCR2_STPB;
> @@ -1374,6 +1413,34 @@ static void imx_poll_put_char(struct uart_port *port, unsigned char c)
>  }
>  #endif
>
> +static int imx_rs485_config(struct uart_port *port,
> +                           struct serial_rs485 *rs485conf)
> +{
> +       struct imx_port *sport = (struct imx_port *)port;
> +
> +       /* unimplemented */
> +       rs485conf->delay_rts_before_send = 0;
> +       rs485conf->delay_rts_after_send = 0;
> +
> +       /* RTS is required to control the transmitter */
> +       if (!sport->have_rtscts)
> +               rs485conf->flags &= ~SER_RS485_ENABLED;
> +
> +       if (rs485conf->flags & SER_RS485_ENABLED) {
> +               unsigned long temp;
> +
> +               /* disable transmitter */
> +               temp = readl(sport->port.membase + UCR2);
> +               temp &= ~UCR2_CTSC;
> +               temp |= UCR2_CTS;
> +               writel(temp, sport->port.membase + UCR2);
> +       }
> +
> +       port->rs485 = *rs485conf;
> +
> +       return 0;
> +}
> +
>  static struct uart_ops imx_pops = {
>         .tx_empty       = imx_tx_empty,
>         .set_mctrl      = imx_set_mctrl,
> @@ -1731,6 +1798,7 @@ static int serial_imx_probe(struct platform_device *pdev)
>         sport->port.irq = rxirq;
>         sport->port.fifosize = 32;
>         sport->port.ops = &imx_pops;
> +       sport->port.rs485_config = imx_rs485_config;
>         sport->port.flags = UPF_BOOT_AUTOCONF;
>         init_timer(&sport->timer);
>         sport->timer.function = imx_timeout;
> --
> 2.1.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-serial" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 7/7] serial: imx: add support for half duplex rs485
  2015-02-19  9:15   ` [PATCH 7/7] " aurélien bouin
@ 2015-02-19  9:37     ` Uwe Kleine-König
  2015-02-19  9:45       ` aurélien bouin
  0 siblings, 1 reply; 16+ messages in thread
From: Uwe Kleine-König @ 2015-02-19  9:37 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Aur?lien,

On Thu, Feb 19, 2015 at 10:15:10AM +0100, aur?lien bouin wrote:
> 2015-02-18 21:41 GMT+01:00 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > The transmitter is expected to be controlled by the UART's RTS pin.
> 
> You definately can be more open in using the last patch I have sent
> the 11th of februrary using rs485.padding[0] that give in parameter
> the GPIO to use for transmit pin
you have a link? Without having seen that patch this can well be a
separate patch. And (also without having seen the patch) I wonder why
the information which gpio to use doesn't come from the device tree but
is supplied by userspace. I thought about expanding mctrl-gpio for that,
but as there are a few conflicting patches to mctrl-gpio out I wanted to
wait until the dust settles.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 7/7] serial: imx: add support for half duplex rs485
  2015-02-19  9:37     ` Uwe Kleine-König
@ 2015-02-19  9:45       ` aurélien bouin
  2015-02-20 15:34         ` Uwe Kleine-König
  0 siblings, 1 reply; 16+ messages in thread
From: aurélien bouin @ 2015-02-19  9:45 UTC (permalink / raw)
  To: linux-arm-kernel

I hope this link will be ok :
http://marc.info/?l=linux-kernel&m=142366865609389&q=raw
Best regards,



2015-02-19 10:37 GMT+01:00 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Aur?lien,
>
> On Thu, Feb 19, 2015 at 10:15:10AM +0100, aur?lien bouin wrote:
>> 2015-02-18 21:41 GMT+01:00 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> > The transmitter is expected to be controlled by the UART's RTS pin.
>>
>> You definately can be more open in using the last patch I have sent
>> the 11th of februrary using rs485.padding[0] that give in parameter
>> the GPIO to use for transmit pin
> you have a link? Without having seen that patch this can well be a
> separate patch. And (also without having seen the patch) I wonder why
> the information which gpio to use doesn't come from the device tree but
> is supplied by userspace. I thought about expanding mctrl-gpio for that,
> but as there are a few conflicting patches to mctrl-gpio out I wanted to
> wait until the dust settles.
>
> Best regards
> Uwe
>
> --
> Pengutronix e.K.                           | Uwe Kleine-K?nig            |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 7/7] serial: imx: add support for half duplex rs485
  2015-02-19  9:45       ` aurélien bouin
@ 2015-02-20 15:34         ` Uwe Kleine-König
  2015-02-20 15:53           ` gianluca
  0 siblings, 1 reply; 16+ messages in thread
From: Uwe Kleine-König @ 2015-02-20 15:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Feb 19, 2015 at 10:45:47AM +0100, aur?lien bouin wrote:
> I hope this link will be ok :
> http://marc.info/?l=linux-kernel&m=142366865609389&q=raw
Good heavens, this patch is broken. It depends on user space to get the
reference counting for the gpio right if at all. It uses a reserved part
of the struct serial_rs485 while being driver specific. It ignores
gpio_request returning an error (well, it does a dev_err in this case,
but continues to use the gpio). It does change how frame error are
handled even if rs485 is off without mentioning in the changelog.

Are you aware what happens if a user issues the rs485 callback without
being aware that padding[0] has this meaning?

I'm sorry, I like my patch better.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 7/7] serial: imx: add support for half duplex rs485
  2015-02-20 15:34         ` Uwe Kleine-König
@ 2015-02-20 15:53           ` gianluca
  0 siblings, 0 replies; 16+ messages in thread
From: gianluca @ 2015-02-20 15:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,
speaking of serial patch for rs485, I wrote a device driver for mxs 
(iMX28): (it is half-duplex too)

It rely on device tree node as:

>> 				rs485_tx_en: rx485-tx-en {
>> 					fsl,pinmux-ids = <
>> 						0x2133 /* MX28_PAD_SSP2_SS0__GPIO_2_19 UART2_DIR */
>> 					>;
>> 					fsl,drive-strength = <0>;
>> 					fsl,pull-up = <1>;
>> 				};


and this:

>> 			auart2: serial at 8006e000 {
>> 				compatible = "fsl,imx28-ekuart";
>> 				pinctrl-names = "default";
>> 				pinctrl-0 = <&auart2_2pins_a
>> 					&rs485_tx_en>;
>> 				rs485-rts-active-low;
>> 				rts-gpio = <&gpio2 19 1>;
>> 				linux,rs485-enabled-at-boot-time;
>> 				rs485-rts-delay = <0 0>;
>> 				status = "okay";
>> 			};

And in attachment the driver. The hr_timer implementation is working 
correctly even with a big load and 3/4 serials at the time.

Give it a look if you want.

On 02/20/2015 04:34 PM, Uwe Kleine-K?nig wrote:
> On Thu, Feb 19, 2015 at 10:45:47AM +0100, aur?lien bouin wrote:
>> I hope this link will be ok :
>> http://marc.info/?l=linux-kernel&m=142366865609389&q=raw
> Good heavens, this patch is broken. It depends on user space to get the
> reference counting for the gpio right if at all. It uses a reserved part
> of the struct serial_rs485 while being driver specific. It ignores
> gpio_request returning an error (well, it does a dev_err in this case,
> but continues to use the gpio). It does change how frame error are
> handled even if rs485 is off without mentioning in the changelog.
>
> Are you aware what happens if a user issues the rs485 callback without
> being aware that padding[0] has this meaning?
>
> I'm sorry, I like my patch better.
>
> Best regards
> Uwe
>


-- 
Eurek s.r.l.                          |
Electronic Engineering                | http://www.eurek.it
via Celletta 8/B, 40026 Imola, Italy  | Phone: +39-(0)542-609120
p.iva 00690621206 - c.f. 04020030377  | Fax:   +39-(0)542-609212
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mxs_ekuart.c
Type: text/x-csrc
Size: 40090 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150220/549c4bd2/attachment-0001.bin>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/7] serial: imx: drop members from driver data that are only used during probe
  2015-02-18 20:41 [PATCH 1/7] serial: imx: drop members from driver data that are only used during probe Uwe Kleine-König
                   ` (5 preceding siblings ...)
  2015-02-18 20:41 ` [PATCH 7/7] serial: imx: add support for half duplex rs485 Uwe Kleine-König
@ 2015-02-21  8:58 ` Uwe Kleine-König
  6 siblings, 0 replies; 16+ messages in thread
From: Uwe Kleine-König @ 2015-02-21  8:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Greg,

On Wed, Feb 18, 2015 at 09:41:02PM +0100, Uwe Kleine-K?nig wrote:
> [... several changes to drivers/tty/serial/imx.c ...]
I noticed that some changes to this driver were merged after v3.19, some
of them conflict with my patches. I will rebase and resend once
v3.20-rc1 (however this will be called) is out.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2015-02-21  8:58 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-18 20:41 [PATCH 1/7] serial: imx: drop members from driver data that are only used during probe Uwe Kleine-König
2015-02-18 20:41 ` [PATCH 2/7] serial: imx: reformat and cleanup copyright header Uwe Kleine-König
2015-02-18 20:41 ` [PATCH 3/7] serial: imx: fix comment about which machines use the i.MX21 type Uwe Kleine-König
2015-02-18 20:41 ` [PATCH 4/7] serial: imx: drop support for IRDA Uwe Kleine-König
2015-02-18 21:16   ` Fabio Estevam
2015-02-18 22:06     ` Uwe Kleine-König
2015-02-18 20:41 ` [PATCH 5/7] serial: imx: Fix handling of receiver overrun Uwe Kleine-König
2015-02-18 20:41 ` [PATCH 6/7] serial: imx: remove long dead code Uwe Kleine-König
2015-02-18 20:41 ` [PATCH 7/7] serial: imx: add support for half duplex rs485 Uwe Kleine-König
2015-02-18 22:09   ` [PATCH 7'/7] fixup! " Uwe Kleine-König
2015-02-19  9:15   ` [PATCH 7/7] " aurélien bouin
2015-02-19  9:37     ` Uwe Kleine-König
2015-02-19  9:45       ` aurélien bouin
2015-02-20 15:34         ` Uwe Kleine-König
2015-02-20 15:53           ` gianluca
2015-02-21  8:58 ` [PATCH 1/7] serial: imx: drop members from driver data that are only used during probe Uwe Kleine-König

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).