aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2011-12-22 03:57:53 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2012-01-04 19:30:35 -0500
commit01f56abd089dd216e537817b61497c58bb66aab3 (patch)
treefdcd62ec26fe0b88f7cd485e7da04e1c8cfc132e
parent0ad5a81472a9d6a0e826e0c6ebe66d3792932a93 (diff)
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 <compnerd@compnerd.org> Signed-off-by: Dirk Behme <dirk.behme@gmail.com> CC: Sascha Hauer <s.hauer@pengutronix.de> CC: Fabio Estevam <festevam@gmail.com> CC: Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> CC: linux-serial@vger.kernel.org CC: Alan Cox <alan@linux.intel.com> Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/tty/serial/imx.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 225922c7ce99..6b98a524eca2 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -102,6 +102,7 @@
102#define UCR2_STPB (1<<6) /* Stop */ 102#define UCR2_STPB (1<<6) /* Stop */
103#define UCR2_WS (1<<5) /* Word size */ 103#define UCR2_WS (1<<5) /* Word size */
104#define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */ 104#define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */
105#define UCR2_ATEN (1<<3) /* Aging Timer Enable */
105#define UCR2_TXEN (1<<2) /* Transmitter enabled */ 106#define UCR2_TXEN (1<<2) /* Transmitter enabled */
106#define UCR2_RXEN (1<<1) /* Receiver enabled */ 107#define UCR2_RXEN (1<<1) /* Receiver enabled */
107#define UCR2_SRST (1<<0) /* SW reset */ 108#define UCR2_SRST (1<<0) /* SW reset */
@@ -1109,6 +1110,70 @@ imx_verify_port(struct uart_port *port, struct serial_struct *ser)
1109 return ret; 1110 return ret;
1110} 1111}
1111 1112
1113#if defined(CONFIG_CONSOLE_POLL)
1114static int imx_poll_get_char(struct uart_port *port)
1115{
1116 struct imx_port_ucrs old_ucr;
1117 unsigned int status;
1118 unsigned char c;
1119
1120 /* save control registers */
1121 imx_port_ucrs_save(port, &old_ucr);
1122
1123 /* disable interrupts */
1124 writel(UCR1_UARTEN, port->membase + UCR1);
1125 writel(old_ucr.ucr2 & ~(UCR2_ATEN | UCR2_RTSEN | UCR2_ESCI),
1126 port->membase + UCR2);
1127 writel(old_ucr.ucr3 & ~(UCR3_DCD | UCR3_RI | UCR3_DTREN),
1128 port->membase + UCR3);
1129
1130 /* poll */
1131 do {
1132 status = readl(port->membase + USR2);
1133 } while (~status & USR2_RDR);
1134
1135 /* read */
1136 c = readl(port->membase + URXD0);
1137
1138 /* restore control registers */
1139 imx_port_ucrs_restore(port, &old_ucr);
1140
1141 return c;
1142}
1143
1144static void imx_poll_put_char(struct uart_port *port, unsigned char c)
1145{
1146 struct imx_port_ucrs old_ucr;
1147 unsigned int status;
1148
1149 /* save control registers */
1150 imx_port_ucrs_save(port, &old_ucr);
1151
1152 /* disable interrupts */
1153 writel(UCR1_UARTEN, port->membase + UCR1);
1154 writel(old_ucr.ucr2 & ~(UCR2_ATEN | UCR2_RTSEN | UCR2_ESCI),
1155 port->membase + UCR2);
1156 writel(old_ucr.ucr3 & ~(UCR3_DCD | UCR3_RI | UCR3_DTREN),
1157 port->membase + UCR3);
1158
1159 /* drain */
1160 do {
1161 status = readl(port->membase + USR1);
1162 } while (~status & USR1_TRDY);
1163
1164 /* write */
1165 writel(c, port->membase + URTX0);
1166
1167 /* flush */
1168 do {
1169 status = readl(port->membase + USR2);
1170 } while (~status & USR2_TXDC);
1171
1172 /* restore control registers */
1173 imx_port_ucrs_restore(port, &old_ucr);
1174}
1175#endif
1176
1112static struct uart_ops imx_pops = { 1177static struct uart_ops imx_pops = {
1113 .tx_empty = imx_tx_empty, 1178 .tx_empty = imx_tx_empty,
1114 .set_mctrl = imx_set_mctrl, 1179 .set_mctrl = imx_set_mctrl,
@@ -1126,6 +1191,10 @@ static struct uart_ops imx_pops = {
1126 .request_port = imx_request_port, 1191 .request_port = imx_request_port,
1127 .config_port = imx_config_port, 1192 .config_port = imx_config_port,
1128 .verify_port = imx_verify_port, 1193 .verify_port = imx_verify_port,
1194#if defined(CONFIG_CONSOLE_POLL)
1195 .poll_get_char = imx_poll_get_char,
1196 .poll_put_char = imx_poll_put_char,
1197#endif
1129}; 1198};
1130 1199
1131static struct imx_port *imx_ports[UART_NR]; 1200static struct imx_port *imx_ports[UART_NR];