aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/amba-pl011.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index ea7aa973ab43..d7e1edec50b5 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -1284,11 +1284,40 @@ static void pl011_break_ctl(struct uart_port *port, int break_state)
1284} 1284}
1285 1285
1286#ifdef CONFIG_CONSOLE_POLL 1286#ifdef CONFIG_CONSOLE_POLL
1287
1288static void pl011_quiesce_irqs(struct uart_port *port)
1289{
1290 struct uart_amba_port *uap = (struct uart_amba_port *)port;
1291 unsigned char __iomem *regs = uap->port.membase;
1292
1293 writew(readw(regs + UART011_MIS), regs + UART011_ICR);
1294 /*
1295 * There is no way to clear TXIM as this is "ready to transmit IRQ", so
1296 * we simply mask it. start_tx() will unmask it.
1297 *
1298 * Note we can race with start_tx(), and if the race happens, the
1299 * polling user might get another interrupt just after we clear it.
1300 * But it should be OK and can happen even w/o the race, e.g.
1301 * controller immediately got some new data and raised the IRQ.
1302 *
1303 * And whoever uses polling routines assumes that it manages the device
1304 * (including tx queue), so we're also fine with start_tx()'s caller
1305 * side.
1306 */
1307 writew(readw(regs + UART011_IMSC) & ~UART011_TXIM, regs + UART011_IMSC);
1308}
1309
1287static int pl011_get_poll_char(struct uart_port *port) 1310static int pl011_get_poll_char(struct uart_port *port)
1288{ 1311{
1289 struct uart_amba_port *uap = (struct uart_amba_port *)port; 1312 struct uart_amba_port *uap = (struct uart_amba_port *)port;
1290 unsigned int status; 1313 unsigned int status;
1291 1314
1315 /*
1316 * The caller might need IRQs lowered, e.g. if used with KDB NMI
1317 * debugger.
1318 */
1319 pl011_quiesce_irqs(port);
1320
1292 status = readw(uap->port.membase + UART01x_FR); 1321 status = readw(uap->port.membase + UART01x_FR);
1293 if (status & UART01x_FR_RXFE) 1322 if (status & UART01x_FR_RXFE)
1294 return NO_POLL_CHAR; 1323 return NO_POLL_CHAR;