Skip to contentSkip to conversation

imx: Add save/restore functions for UART control regs

PATCH New Dirk Behme 2 participants 4 messages Dec 22, 2011 – Dec 26, 2011

Subsystems (2)
lore
Share & tools
lore

Dirk Behme

author
#0 lore raw

PATCH v2 1/2 imx: Add save/restore functions for UART control regs

Factor out the uart save/restore functionality instead of having the same code several times in the driver.

CC Saleem Abdulrasool <[email protected]>
CC Sascha Hauer <[email protected]>
CC Fabio Estevam <[email protected]>
CC Uwe Kleine-Koenig <[email protected]>
CC linux-serial at vger.kernel.org
CC Alan Cox <[email protected]>

---
Changes in v2:
* Rename imx_console_mode/restore() to imx_port_ucrs_save/restore()
* Introduce struct imx_port_ucrs
* Add Alan Cox to CC

 drivers/tty/serial/imx.c |   43 +++++++++++++++++++++++++++++++++++--------
 1 files changed, 35 insertions(+), 8 deletions(-)
drivers/tty/serial/imx.c +35 -8
index 163fc90..3daa008 100644
@@ -207,6 +207,12 @@ struct imx_port {
 	struct imx_uart_data	*devdata;
 };
 
+struct imx_port_ucrs {
+	unsigned int	ucr1;
+	unsigned int	ucr2;
+	unsigned int	ucr3;
+};
+
 #ifdef CONFIG_IRDA
 #define USE_IRDA(sport)	((sport)->use_irda)
 #else
@@ -260,6 +266,27 @@ static inline int is_imx21_uart(struct imx_port *sport)
 }
 
 /*
+ * Save and restore functions for UCR1, UCR2 and UCR3 registers
+ */
+static void imx_port_ucrs_save(struct uart_port *port,
+			       struct imx_port_ucrs *ucr)
+{
+	/* save control registers */
+	ucr->ucr1 = readl(port->membase + UCR1);
+	ucr->ucr2 = readl(port->membase + UCR2);
+	ucr->ucr3 = readl(port->membase + UCR3);
+}
+
+static void imx_port_ucrs_restore(struct uart_port *port,
+				  struct imx_port_ucrs *ucr)
+{
+	/* restore control registers */
+	writel(ucr->ucr1, port->membase + UCR1);
+	writel(ucr->ucr2, port->membase + UCR2);
+	writel(ucr->ucr3, port->membase + UCR3);
+}
+
+/*
  * Handle any change of modem status signal since we were last called.
  */
 static void imx_mctrl_check(struct imx_port *sport)
@@ -1118,13 +1145,14 @@ static void
 imx_console_write(struct console *co, const char *s, unsigned int count)
 {
 	struct imx_port *sport = imx_ports[co->index];
-	unsigned int old_ucr1, old_ucr2, ucr1;
+	struct imx_port_ucrs old_ucr;
+	unsigned int ucr1;
 
 	/*
-	 *	First, save UCR1/2 and then disable interrupts
+	 *	First, save UCR1/2/3 and then disable interrupts
 	 */
-	ucr1 = old_ucr1 = readl(sport->port.membase + UCR1);
-	old_ucr2 = readl(sport->port.membase + UCR2);
+	imx_port_ucrs_save(&sport->port, &old_ucr);
+	ucr1 = old_ucr.ucr1;
 
 	if (is_imx1_uart(sport))
 		ucr1 |= IMX1_UCR1_UARTCLKEN;
@@ -1133,18 +1161,17 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
 
 	writel(ucr1, sport->port.membase + UCR1);
 
-	writel(old_ucr2 | UCR2_TXEN, sport->port.membase + UCR2);
+	writel(old_ucr.ucr2 | UCR2_TXEN, sport->port.membase + UCR2);
 
 	uart_console_write(&sport->port, s, count, imx_console_putchar);
 
 	/*
 	 *	Finally, wait for transmitter to become empty
-	 *	and restore UCR1/2
+	 *	and restore UCR1/2/3
 	 */
 	while (!(readl(sport->port.membase + USR2) & USR2_TXDC));
 
-	writel(old_ucr1, sport->port.membase + UCR1);
-	writel(old_ucr2, sport->port.membase + UCR2);
+	imx_port_ucrs_restore(&sport->port, &old_ucr);
 }
 
 /*
Signature · 1 line
1.7.7.4
author
#1 lore raw

PATCH v3 2/2 imx: add polled io uart methods

From: Saleem Abdulrasool <[email protected]>

These methods are invoked if the iMX uart is used in conjuction with kgdb during early boot. In order to access the UART without the interrupts, the kernel uses the basic polling methods for IO with the device. With these methods implemented, it is now possible to enable kgdb during early boot over serial.

CC Sascha Hauer <[email protected]>
CC Fabio Estevam <[email protected]>
CC Uwe Kleine-Koenig <[email protected]>
CC linux-serial at vger.kernel.org
CC Alan Cox <[email protected]>

---
Changes in v3:
* Remove blank line
* Remove '& 0xff' in 'return c' as 'c' is an unsigned char
* Rename imx_console_mode/restore() to imx_port_ucrs_save/restore()
* Add Alan Cox to CC

Changes in the v2 compared to Saleem's original version:
* Remove volatile form status variable
* Remove blank line
* Factor out imx_console_mode/restore()

 drivers/tty/serial/imx.c |   69 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 69 insertions(+), 0 deletions(-)
drivers/tty/serial/imx.c +69 -0
index 3daa008..d6162ec 100644
@@ -102,6 +102,7 @@
 #define  UCR2_STPB       (1<<6)	 /* Stop */
 #define  UCR2_WS         (1<<5)	 /* Word size */
 #define  UCR2_RTSEN      (1<<4)	 /* Request to send interrupt enable */
+#define  UCR2_ATEN       (1<<3)  /* Aging Timer Enable */
 #define  UCR2_TXEN       (1<<2)	 /* Transmitter enabled */
 #define  UCR2_RXEN       (1<<1)	 /* Receiver enabled */
 #define  UCR2_SRST 	 (1<<0)	 /* SW reset */
@@ -1106,6 +1107,70 @@ imx_verify_port(struct uart_port *port, struct serial_struct *ser)
 	return ret;
 }
 
+#if defined(CONFIG_CONSOLE_POLL)
+static int imx_poll_get_char(struct uart_port *port)
+{
+	struct imx_port_ucrs old_ucr;
+	unsigned int status;
+	unsigned char c;
+
+	/* save control registers */
+	imx_port_ucrs_save(port, &old_ucr);
+
+	/* disable interrupts */
+	writel(UCR1_UARTEN, port->membase + UCR1);
+	writel(old_ucr.ucr2 & ~(UCR2_ATEN | UCR2_RTSEN | UCR2_ESCI),
+	       port->membase + UCR2);
+	writel(old_ucr.ucr3 & ~(UCR3_DCD | UCR3_RI | UCR3_DTREN),
+	       port->membase + UCR3);
+
+	/* poll */
+	do {
+		status = readl(port->membase + USR2);
+	} while (~status & USR2_RDR);
+
+	/* read */
+	c = readl(port->membase + URXD0);
+
+	/* restore control registers */
+	imx_port_ucrs_restore(port, &old_ucr);
+
+	return c;
+}
+
+static void imx_poll_put_char(struct uart_port *port, unsigned char c)
+{
+	struct imx_port_ucrs old_ucr;
+	unsigned int status;
+
+	/* save control registers */
+	imx_port_ucrs_save(port, &old_ucr);
+
+	/* disable interrupts */
+	writel(UCR1_UARTEN, port->membase + UCR1);
+	writel(old_ucr.ucr2 & ~(UCR2_ATEN | UCR2_RTSEN | UCR2_ESCI),
+	       port->membase + UCR2);
+	writel(old_ucr.ucr3 & ~(UCR3_DCD | UCR3_RI | UCR3_DTREN),
+	       port->membase + UCR3);
+
+	/* drain */
+	do {
+		status = readl(port->membase + USR1);
+	} while (~status & USR1_TRDY);
+
+	/* write */
+	writel(c, port->membase + URTX0);
+
+	/* flush */
+	do {
+		status = readl(port->membase + USR2);
+	} while (~status & USR2_TXDC);
+
+	/* restore control registers */
+	imx_port_ucrs_restore(port, &old_ucr);
+}
+#endif
+
 static struct uart_ops imx_pops = {
 	.tx_empty	= imx_tx_empty,
 	.set_mctrl	= imx_set_mctrl,
@@ -1123,6 +1188,10 @@ static struct uart_ops imx_pops = {
 	.request_port	= imx_request_port,
 	.config_port	= imx_config_port,
 	.verify_port	= imx_verify_port,
+#if defined(CONFIG_CONSOLE_POLL)
+	.poll_get_char  = imx_poll_get_char,
+	.poll_put_char  = imx_poll_put_char,
+#endif
 };
 
 static struct imx_port *imx_ports[UART_NR];
Signature · 1 line
1.7.7.4
Applied
#2 lore raw

PATCH v3 2/2 imx: add polled io uart methods

Quoted 7 lines · Dirk Behme

From: Saleem Abdulrasool <[email protected]>

These methods are invoked if the iMX uart is used in conjuction with kgdb during early boot. In order to access the UART without the interrupts, the kernel uses the basic polling methods for IO with the device. With these methods implemented, it is now possible to enable kgdb during early boot over serial.

Quoted 7 lines

I queued this for 3.3, and will send a pull-request to Greg.

Signature · 2 lines
Regards,
Shawn
Applied
#3 lore raw

PATCH v2 1/2 imx: Add save/restore functions for UART control regs

In reply to Dirk Behme
Quoted 10 lines · Dirk Behme

Factor out the uart save/restore functionality instead of having the same code several times in the driver.

CC Saleem Abdulrasool <[email protected]>
CC Sascha Hauer <[email protected]>
CC Fabio Estevam <[email protected]>
CC Uwe Kleine-Koenig <[email protected]>
CC Alan Cox <[email protected]>

I queued this for 3.3, and will send a pull-request to Greg.

Signature · 2 lines
Regards,
Shawn