[PATCH] serial: imx: Prevent RTS line toggle delays for RS485

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When using RS485 in half duplex mode the RTS line is typically used to
toggle receive/transmit on the transceiver IC. As some protocols (OSDP
f.ex.) specify that the slave should respond within some short time period,
it is important that the RTS line toggles the transceiver from transmit
mode to receive mode within that time.

This change puts a pm_qos requirement on CPU_DMA_LATENCY when in RS485 tx
mode so that CPU wake times won't cause to long delays.

Signed-off-by: Einar Vading <einarv@xxxxxxxx>

Change-Id: I6a44ff2b5283d7bc728cdc1cbfb6f60c2bca73d5
---
 drivers/tty/serial/imx.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 521500c..9051e07 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -39,6 +39,7 @@
 #include <linux/of_device.h>
 #include <linux/io.h>
 #include <linux/dma-mapping.h>
+#include <linux/pm_qos.h>
 
 #include <asm/irq.h>
 #include <linux/platform_data/serial-imx.h>
@@ -228,6 +229,7 @@ struct imx_port {
 	unsigned int		dma_tx_nents;
 	unsigned int            saved_reg[10];
 	bool			context_saved;
+	struct pm_qos_request	pm_qos_req;
 };
 
 struct imx_port_ucrs {
@@ -384,6 +386,7 @@ static void imx_stop_tx(struct uart_port *port)
 		temp = readl(port->membase + UCR4);
 		temp &= ~UCR4_TCEN;
 		writel(temp, port->membase + UCR4);
+		pm_qos_update_request(&sport->pm_qos_req, PM_QOS_DEFAULT_VALUE);
 	}
 }
 
@@ -576,6 +579,7 @@ static void imx_start_tx(struct uart_port *port)
 	unsigned long temp;
 
 	if (port->rs485.flags & SER_RS485_ENABLED) {
+		pm_qos_update_request(&sport->pm_qos_req, 0);
 		temp = readl(port->membase + UCR2);
 		if (port->rs485.flags & SER_RS485_RTS_ON_SEND)
 			imx_port_rts_active(sport, &temp);
@@ -2216,6 +2220,9 @@ static int serial_imx_probe(struct platform_device *pdev)
 		}
 	}
 
+	pm_qos_add_request(&sport->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
+			PM_QOS_DEFAULT_VALUE);
+
 	imx_ports[sport->port.line] = sport;
 
 	platform_set_drvdata(pdev, sport);
@@ -2227,6 +2234,8 @@ static int serial_imx_remove(struct platform_device *pdev)
 {
 	struct imx_port *sport = platform_get_drvdata(pdev);
 
+	pm_qos_remove_request(&sport->pm_qos_req);
+
 	return uart_remove_one_port(&imx_reg, &sport->port);
 }
 
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux