diff options
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/amba-pl011.c | 29 |
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 | |||
1288 | static 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 | |||
1287 | static int pl011_get_poll_char(struct uart_port *port) | 1310 | static 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; |