Skip to contentSkip to conversation

No subject

PATCH New Saleem Abdulrasool 6 participants 11 messages Sep 19, 2011 – Dec 4, 2011

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

Hi.

The attached patch adds polled io methods for the mxcuart. I needed them in order to use kgdb during the early boot. The changes have been sitting in (my and) Genesi's tree for quite some time now. I believe that the changes are generally useful and would like you to consider merging them in the "upstream" repository.

Thanks.

Signature · 2 lines
Saleem Abdulrasool
compnerd (at) compnerd (dot) org
#1 lore raw

PATCH 1/1 mxcuart: add polled io methods

---
 drivers/serial/mxc_uart.c |   78 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 78 insertions(+), 0 deletions(-)
drivers/serial/mxc_uart.c +78 -0
index 347a746..5769465 100644
@@ -1534,6 +1534,79 @@ mxcuart_pm(struct uart_port *port, unsigned int state, unsigned int oldstate)
 		clk_enable(umxc->clk);
 }
 
+#ifdef CONFIG_CONSOLE_POLL
+static int mxc_uart_get_poll_char(struct uart_port *port)
+{
+       volatile unsigned int status;
+       unsigned int cr1, cr2, cr3;
+       unsigned char c;
+
+       /* save control registers */
+       cr1 = readl(port->membase + MXC_UARTUCR1);
+       cr2 = readl(port->membase + MXC_UARTUCR2);
+       cr3 = readl(port->membase + MXC_UARTUCR3);
+
+       /* disable interrupts */
+       writel(MXC_UARTUCR1_UARTEN, port->membase + MXC_UARTUCR1);
+       writel(cr2 & ~(MXC_UARTUCR2_ATEN | MXC_UARTUCR2_RTSEN | MXC_UARTUCR2_ESCI),
+              port->membase + MXC_UARTUCR2);
+       writel(cr3 & ~(MXC_UARTUCR3_DCD | MXC_UARTUCR3_RI | MXC_UARTUCR3_DTRDEN),
+              port->membase + MXC_UARTUCR3);
+
+       /* poll */
+       do {
+               status = readl(port->membase + MXC_UARTUSR2);
+       } while (~status & MXC_UARTUSR2_RDR);
+
+       /* read */
+       c = readl(port->membase + MXC_UARTURXD);
+
+       /* restore control registers */
+       writel(cr1, port->membase + MXC_UARTUCR1);
+       writel(cr2, port->membase + MXC_UARTUCR2);
+       writel(cr3, port->membase + MXC_UARTUCR3);
+
+       return c & 0xff;
+}
+
+static void mxc_uart_put_poll_char(struct uart_port *port,
+                                  unsigned char c)
+{
+       volatile unsigned int status;
+       unsigned int cr1, cr2, cr3;
+
+       /* save control registers */
+       cr1 = readl(port->membase + MXC_UARTUCR1);
+       cr2 = readl(port->membase + MXC_UARTUCR2);
+       cr3 = readl(port->membase + MXC_UARTUCR3);
+
+       /* disable interrupts */
+       writel(MXC_UARTUCR1_UARTEN, port->membase + MXC_UARTUCR1);
+       writel(cr2 & ~(MXC_UARTUCR2_ATEN | MXC_UARTUCR2_RTSEN | MXC_UARTUCR2_ESCI),
+              port->membase + MXC_UARTUCR2);
+       writel(cr3 & ~(MXC_UARTUCR3_DCD | MXC_UARTUCR3_RI | MXC_UARTUCR3_DTRDEN),
+              port->membase + MXC_UARTUCR3);
+
+       /* drain */
+       do {
+               status = readl(port->membase + MXC_UARTUSR1);
+       } while (~status & MXC_UARTUSR1_TRDY);
+
+       /* write */
+       writel(c, port->membase + MXC_UARTUTXD);
+
+       /* flush */
+       do {
+               status = readl(port->membase + MXC_UARTUSR2);
+       } while (~status & MXC_UARTUSR2_TXDC);
+
+       /* restore control registers */
+       writel(cr1, port->membase + MXC_UARTUCR1);
+       writel(cr2, port->membase + MXC_UARTUCR2);
+       writel(cr3, port->membase + MXC_UARTUCR3);
+}
+#endif
+
 /*!
  * This structure contains the pointers to the control functions that are
  * invoked by the core serial driver to access the UART hardware. The
@@ -1558,6 +1631,11 @@ static struct uart_ops mxc_ops = {
 	.config_port = mxcuart_config_port,
 	.verify_port = mxcuart_verify_port,
 	.send_xchar = mxcuart_send_xchar,
+
+#ifdef CONFIG_CONSOLE_POLL
+        .poll_get_char = mxc_uart_get_poll_char,
+        .poll_put_char = mxc_uart_put_poll_char,
+#endif
 };
 
 #ifdef CONFIG_SERIAL_MXC_CONSOLE
Signature · 1 line
1.7.6.1
reviewer
#2 lore raw

PATCH 1/1 mxcuart: add polled io methods

Hi Saleem,

drivers/serial/mxc_uart.c

Quoted 8 lines · Saleem Abdulrasool

---
?drivers/serial/mxc_uart.c | ? 78 +++++++++++++++++++++++++++++++++++++++++++++ ?1 files changed, 78 insertions(+), 0 deletions(-)

drivers/serial/mxc_uart.c +0 -0
index 347a746..5769465 100644

You missed a commit message and your Signed-off-by line.

Have you tried using KGDB after applying your patch?

Regards,

Fabio Estevam

#3 lore raw

PATCH 1/1 imx: add polled io uart methods

Hi,

Ive updated the patch to be signed of, and be based on the right tree.

In regards to Fabio's question, yes, I had tried kgdb with this patch applied, and it seemed to work fine.

Sorry about the delay in the updated patch, please let me know if there are any other changes that need to be made.

Thanks,

Signature · 2 lines
Saleem Abdulrasool
compnerd (at) compnerd (dot) org
#4 lore raw

PATCH 1/1 imx: add polled io uart methods

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.

---
 drivers/tty/serial/imx.c |   77 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 77 insertions(+), 0 deletions(-)
drivers/tty/serial/imx.c +77 -0
index 7e91b3d..4fcf9ca 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 */
@@ -1075,6 +1076,77 @@ 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)
+{
+	volatile unsigned int status;
+	unsigned int cr1, cr2, cr3;
+	unsigned char c;
+
+	/* save control registers */
+	cr1 = readl(port->membase + UCR1);
+	cr2 = readl(port->membase + UCR2);
+	cr3 = readl(port->membase + UCR3);
+
+	/* disable interrupts */
+	writel(UCR1_UARTEN, port->membase + UCR1);
+	writel(cr2 & ~(UCR2_ATEN | UCR2_RTSEN | UCR2_ESCI),
+	       port->membase + UCR2);
+	writel(cr3 & ~(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 */
+	writel(cr1, port->membase + UCR1);
+	writel(cr2, port->membase + UCR2);
+	writel(cr3, port->membase + UCR3);
+
+	return (c & 0xff);
+}
+
+static void imx_poll_put_char(struct uart_port *port, unsigned char c)
+{
+	volatile unsigned int status;
+	unsigned int cr1, cr2, cr3;
+
+	/* save control registers */
+	cr1 = readl(port->membase + UCR1);
+	cr2 = readl(port->membase + UCR2);
+	cr3 = readl(port->membase + UCR3);
+
+	/* disable interrupts */
+	writel(UCR1_UARTEN, port->membase + UCR1);
+	writel(cr2 & ~(UCR2_ATEN | UCR2_RTSEN | UCR2_ESCI),
+	       port->membase + UCR2);
+	writel(cr3 & ~(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 */
+	writel(cr1, port->membase + UCR1);
+	writel(cr2, port->membase + UCR2);
+	writel(cr3, port->membase + UCR3);
+}
+#endif
+
 static struct uart_ops imx_pops = {
 	.tx_empty	= imx_tx_empty,
 	.set_mctrl	= imx_set_mctrl,
@@ -1092,6 +1164,11 @@ 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.6.1
reviewer
#5 lore raw

PATCH 1/1 imx: add polled io uart methods

Quoted 9 lines · Saleem Abdulrasool

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.

---
?drivers/tty/serial/imx.c | ? 77 ++++++++++++++++++++++++++++++++++++++++++++++ ?1 files changed, 77 insertions(+), 0 deletions(-)

You should run ./scripts/getmaintainer.pl to see what are the other lists/maintainers you should also copy.

Regards,

Fabio Estevam

maintainer
#6 lore raw

PATCH 1/1 imx: add polled io uart methods

In reply to Saleem Abdulrasool
Quoted 85 lines · Saleem Abdulrasool

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.

---
 drivers/tty/serial/imx.c |   77 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 77 insertions(+), 0 deletions(-)
drivers/tty/serial/imx.c +60 -0
index 7e91b3d..4fcf9ca 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 */
@@ -1075,6 +1076,77 @@ 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)
+{
+	volatile unsigned int status;
+	unsigned int cr1, cr2, cr3;
+	unsigned char c;
+
+	/* save control registers */
+	cr1 = readl(port->membase + UCR1);
+	cr2 = readl(port->membase + UCR2);
+	cr3 = readl(port->membase + UCR3);
+
+	/* disable interrupts */
+	writel(UCR1_UARTEN, port->membase + UCR1);
+	writel(cr2 & ~(UCR2_ATEN | UCR2_RTSEN | UCR2_ESCI),
+	       port->membase + UCR2);
+	writel(cr3 & ~(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 */
+	writel(cr1, port->membase + UCR1);
+	writel(cr2, port->membase + UCR2);
+	writel(cr3, port->membase + UCR3);
+
+	return (c & 0xff);
+}
+
+static void imx_poll_put_char(struct uart_port *port, unsigned char c)
+{
+	volatile unsigned int status;
+	unsigned int cr1, cr2, cr3;
+
+	/* save control registers */
+	cr1 = readl(port->membase + UCR1);
+	cr2 = readl(port->membase + UCR2);
+	cr3 = readl(port->membase + UCR3);
+
+	/* disable interrupts */
+	writel(UCR1_UARTEN, port->membase + UCR1);
+	writel(cr2 & ~(UCR2_ATEN | UCR2_RTSEN | UCR2_ESCI),
+	       port->membase + UCR2);
+	writel(cr3 & ~(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);
+

drivers/tty/serial/imx.c imx_verify_port(struct uart_port *port, struct serial_struct *ser) · line 1147

Quoted 10 lines
drivers/tty/serial/imx.c +10 -0
+	/* flush */
+	do {
+		status = readl(port->membase + USR2);
+	} while (~status & USR2_TXDC);
+
+	/* restore control registers */
+	writel(cr1, port->membase + UCR1);
+	writel(cr2, port->membase + UCR2);
+	writel(cr3, port->membase + UCR3);
+}

We should factor out the uart save/restore functionality instead of having the same code three times in the driver. I'm thinking about:

imx_console_mode(struct uart_port *port, u32 *ucr1, u32 *ucr2, u32 *ucr2); imx_console_restore(struct uart_port *port, u32 ucr1, u32 ucr2, u32 ucr3);

These functions could correctly handle ucr3 (which is missing in mainline) and i.MX1 (which is missing in your patch).

Sascha

Signature · 4 lines
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
#7 lore raw

PATCH 1/1 imx: add polled io uart methods

Quoted 100 lines · Sascha Hauer
Quoted 85 lines · Saleem Abdulrasool

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.

---
  drivers/tty/serial/imx.c |   77 ++++++++++++++++++++++++++++++++++++++++++++++
  1 files changed, 77 insertions(+), 0 deletions(-)
drivers/tty/serial/imx.c +60 -0
index 7e91b3d..4fcf9ca 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 */
@@ -1075,6 +1076,77 @@ 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)
+{
+	volatile unsigned int status;
+	unsigned int cr1, cr2, cr3;
+	unsigned char c;
+
+	/* save control registers */
+	cr1 = readl(port->membase + UCR1);
+	cr2 = readl(port->membase + UCR2);
+	cr3 = readl(port->membase + UCR3);
+
+	/* disable interrupts */
+	writel(UCR1_UARTEN, port->membase + UCR1);
+	writel(cr2&  ~(UCR2_ATEN | UCR2_RTSEN | UCR2_ESCI),
+	       port->membase + UCR2);
+	writel(cr3&  ~(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 */
+	writel(cr1, port->membase + UCR1);
+	writel(cr2, port->membase + UCR2);
+	writel(cr3, port->membase + UCR3);
+
+	return (c&  0xff);
+}
+
+static void imx_poll_put_char(struct uart_port *port, unsigned char c)
+{
+	volatile unsigned int status;
+	unsigned int cr1, cr2, cr3;
+
+	/* save control registers */
+	cr1 = readl(port->membase + UCR1);
+	cr2 = readl(port->membase + UCR2);
+	cr3 = readl(port->membase + UCR3);
+
+	/* disable interrupts */
+	writel(UCR1_UARTEN, port->membase + UCR1);
+	writel(cr2&  ~(UCR2_ATEN | UCR2_RTSEN | UCR2_ESCI),
+	       port->membase + UCR2);
+	writel(cr3&  ~(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);
+

drivers/tty/serial/imx.c imx_verify_port(struct uart_port *port, struct serial_struct *ser) · line 1147

Quoted 10 lines
drivers/tty/serial/imx.c +10 -0
+	/* flush */
+	do {
+		status = readl(port->membase + USR2);
+	} while (~status&  USR2_TXDC);
+
+	/* restore control registers */
+	writel(cr1, port->membase + UCR1);
+	writel(cr2, port->membase + UCR2);
+	writel(cr3, port->membase + UCR3);
+}

We should factor out the uart save/restore functionality instead of having the same code three times in the driver. I'm thinking about:

Quoted 5 lines

imx_console_mode(struct uart_port *port, u32 *ucr1, u32 *ucr2, u32 *ucr2); imx_console_restore(struct uart_port *port, u32 ucr1, u32 ucr2, u32 ucr3);

These functions could correctly handle ucr3 (which is missing in mainline) and i.MX1 (which is missing in your patch).

What's about anything like this? [1] [2]

Best regards

Dirk

[1]
From: Dirk Behme <[email protected]>
Subject: [PATCH 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-K?nig <[email protected]>
CC linux-serial at vger.kernel.org
---
  drivers/tty/serial/imx.c |   38 +++++++++++++++++++++++++++++++-------
  1 files changed, 31 insertions(+), 7 deletions(-)
drivers/tty/serial/imx.c +0 -0
index 163fc90..6a01c2a 100644
@@ -260,6 +260,31 @@ static inline int is_imx21_uart(struct imx_port 

*sport)
}

/*
+ * Save and restore functions for UCR1, UCR2 and UCR3 registers
+ */
+static void imx_console_mode(struct uart_port *port,

+			     unsigned int *ucr1,
+			     unsigned int *ucr2,
+			     unsigned int *ucr3)

+{
+ /* save control registers */
+ *ucr1 = readl(port->membase + UCR1);
+ *ucr2 = readl(port->membase + UCR2);
+ *ucr3 = readl(port->membase + UCR3);
+}
+
+static void imx_console_restore(struct uart_port *port,
+ unsigned int ucr1,
+ unsigned int ucr2,
+ unsigned int ucr3)
+{
+ /* restore control registers */
+ writel(ucr1, port->membase + UCR1);
+ writel(ucr2, port->membase + UCR2);
+ writel(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 +1143,13 @@ 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;
+ unsigned int old_ucr1, old_ucr2, old_ucr3, 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_console_mode(&sport->port, &old_ucr1, &old_ucr2, &old_ucr3);
+ ucr1 = old_ucr1;

if (is_imx1_uart(sport))
ucr1 |= IMX1_UCR1_UARTCLKEN;
@@ -1139,12 +1164,11 @@ imx_console_write(struct console *co, const char *s, unsigned int count)

/*
* 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_console_restore(&sport->port, old_ucr1, old_ucr2, old_ucr3);
}

/*

Signature · 29 lines
1.7.7.4

[2]
From: Saleem Abdulrasool <[email protected]>
Subject: [PATCH 2/2 v2] imx: add polled io uart methods

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.

Signed-off-by: Saleem Abdulrasool <[email protected]>
Signed-off-by: Dirk Behme <[email protected]>
CC: Sascha Hauer <[email protected]>
CC: Fabio Estevam <[email protected]>
CC: Uwe Kleine-K?nig <[email protected]>
CC: linux-serial at vger.kernel.org
---
Note: 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 |   66 
++++++++++++++++++++++++++++++++++++++++++++++
  1 files changed, 66 insertions(+), 0 deletions(-)
drivers/tty/serial/imx.c +1 -0
index 6a01c2a..cd81ac0 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 */
@@ -1104,6 +1105,66 @@ 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)
+{
+ unsigned int status, cr1, cr2, cr3;
+ unsigned char c;
+
+ /* save control registers */
+ imx_console_mode(port, &cr1, &cr2, &cr3);
+
+ /* disable interrupts */
+ writel(UCR1_UARTEN, port->membase + UCR1);
+ writel(cr2 & ~(UCR2_ATEN | UCR2_RTSEN | UCR2_ESCI),
+ port->membase + UCR2);
+ writel(cr3 & ~(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_console_restore(port, cr1, cr2, cr3);
+
+ return c & 0xff;
+}
+
+static void imx_poll_put_char(struct uart_port *port, unsigned char c) +{
+ unsigned int status, cr1, cr2, cr3;
+
+ /* save control registers */
+ imx_console_mode(port, &cr1, &cr2, &cr3);
+
+ /* disable interrupts */
+ writel(UCR1_UARTEN, port->membase + UCR1);
+ writel(cr2 & ~(UCR2_ATEN | UCR2_RTSEN | UCR2_ESCI),
+ port->membase + UCR2);
+ writel(cr3 & ~(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_console_restore(port, cr1, cr2, cr3);
+}
+#endif
+
static struct uart_ops imx_pops = {
.tx_empty = imx_tx_empty,
.set_mctrl = imx_set_mctrl,
@@ -1121,6 +1182,11 @@ 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 · 20 lines
1.7.7.4





-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-imx-Add-save-restore-functions-for-UART-control-regs.patch
Type: text/x-patch
Size: 2728 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20111204/7a2ff7dd/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-imx-add-polled-io-uart-methods.patch
Type: text/x-patch
Size: 3603 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20111204/7a2ff7dd/attachment-0001.bin>
#8 lore raw

PATCH 1/1 imx: add polled io uart methods

In reply to Saleem Abdulrasool
Quoted 23 lines · Saleem Abdulrasool

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.

---
 drivers/tty/serial/imx.c |   77 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 77 insertions(+), 0 deletions(-)
drivers/tty/serial/imx.c +1 -0
index 7e91b3d..4fcf9ca 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 */

drivers/tty/serial/imx.c imx_verify_port(struct uart_port *port, struct serial_struct *ser) · line 1079

Quoted 4 lines
drivers/tty/serial/imx.c +1 -0
@@ -1075,6 +1076,77 @@ imx_verify_port(struct uart_port *port, struct serial_struct *ser)
 	return ret;
 }
 
+

needless newline

drivers/tty/serial/imx.c imx_verify_port(struct uart_port *port, struct serial_struct *ser) · line 1083

Quoted 4 lines
drivers/tty/serial/imx.c +4 -0
+#if defined(CONFIG_CONSOLE_POLL)
+static int imx_poll_get_char(struct uart_port *port)
+{
+	volatile unsigned int status;

Why is that volatile?

drivers/tty/serial/imx.c imx_verify_port(struct uart_port *port, struct serial_struct *ser) · line 1091

Quoted 8 lines
drivers/tty/serial/imx.c +8 -0
+	unsigned int cr1, cr2, cr3;
+	unsigned char c;
+
+	/* save control registers */
+	cr1 = readl(port->membase + UCR1);
+	cr2 = readl(port->membase + UCR2);
+	cr3 = readl(port->membase + UCR3);
+

Best regards
Uwe

Signature · 2 lines
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
#9 lore raw

PATCH 1/1 imx: add polled io uart methods

Quoted 27 lines · Uwe Kleine-K?nig
Quoted 26 lines · Saleem Abdulrasool

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.

---
 drivers/tty/serial/imx.c |   77 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 77 insertions(+), 0 deletions(-)
drivers/tty/serial/imx.c +1 -0
index 7e91b3d..4fcf9ca 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 */
@@ -1075,6 +1076,77 @@ imx_verify_port(struct uart_port *port, struct serial_struct *ser)
 	return ret;
 }
 
Quoted 2 lines

drivers/tty/serial/imx.c imx_verify_port(struct uart_port *port, struct serial_struct *ser) · line 1079

Quoted 1 line
drivers/tty/serial/imx.c +1 -0
+

needless newline

Removed.

Quoted 5 lines

drivers/tty/serial/imx.c imx_verify_port(struct uart_port *port, struct serial_struct *ser) · line 1083

Quoted 4 lines
drivers/tty/serial/imx.c +4 -0
+#if defined(CONFIG_CONSOLE_POLL)
+static int imx_poll_get_char(struct uart_port *port)
+{
+	volatile unsigned int status;

Why is that volatile?

It shouldnt be, removed the volatile attribute. Im not sure why that was there, it really doesnt make any sense since there isnt any inline assembler there to confuse the compiler.

Quoted 11 lines

drivers/tty/serial/imx.c imx_verify_port(struct uart_port *port, struct serial_struct *ser) · line 1091

Quoted 8 lines
drivers/tty/serial/imx.c +8 -0
+	unsigned int cr1, cr2, cr3;
+	unsigned char c;
+
+	/* save control registers */
+	cr1 = readl(port->membase + UCR1);
+	cr2 = readl(port->membase + UCR2);
+	cr3 = readl(port->membase + UCR3);
+

Best regards
Uwe

Thanks for the review. Ive not attached the updated patch since Id like to make the changes that Sascha suggested, and I shall post the updated patch subsequently.

Quoted 3 lines
Signature · 2 lines
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Signature · 2 lines
Saleem Abdulrasool
compnerd (at) compnerd (dot) org
#10 lore raw

PATCH 1/1 imx: add polled io uart methods

Quoted 55 lines · Saleem Abdulrasool
Quoted 27 lines · Uwe Kleine-K?nig
Quoted 26 lines · Saleem Abdulrasool

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.

---
 drivers/tty/serial/imx.c |   77 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 77 insertions(+), 0 deletions(-)
drivers/tty/serial/imx.c +1 -0
index 7e91b3d..4fcf9ca 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 */
@@ -1075,6 +1076,77 @@ imx_verify_port(struct uart_port *port, struct serial_struct *ser)
 	return ret;
 }
 
Quoted 2 lines

drivers/tty/serial/imx.c imx_verify_port(struct uart_port *port, struct serial_struct *ser) · line 1079

Quoted 1 line
drivers/tty/serial/imx.c +1 -0
+

needless newline

Removed.

Quoted 5 lines

drivers/tty/serial/imx.c imx_verify_port(struct uart_port *port, struct serial_struct *ser) · line 1083

Quoted 4 lines
drivers/tty/serial/imx.c +4 -0
+#if defined(CONFIG_CONSOLE_POLL)
+static int imx_poll_get_char(struct uart_port *port)
+{
+	volatile unsigned int status;

Why is that volatile?

It shouldnt be, removed the volatile attribute. Im not sure why that was there, it really doesnt make any sense since there isnt any inline assembler there to confuse the compiler.

Quoted 10 lines

drivers/tty/serial/imx.c imx_verify_port(struct uart_port *port, struct serial_struct *ser) · line 1091

Quoted 8 lines
drivers/tty/serial/imx.c +8 -0
+	unsigned int cr1, cr2, cr3;
+	unsigned char c;
+
+	/* save control registers */
+	cr1 = readl(port->membase + UCR1);
+	cr2 = readl(port->membase + UCR2);
+	cr3 = readl(port->membase + UCR3);
+

Best regards
Uwe

Quoted 3 lines

Thanks for the review. Ive not attached the updated patch since Id like to make the changes that Sascha suggested, and I shall post the updated patch subsequently.

Any update on this?

Many thanks

Dirk