From 697beb0b85aca54f9d09df20b5228c16c6563edb Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Mon, 24 Sep 2012 14:27:55 -0700 Subject: [PATCH] --- yaml --- r: 325796 b: refs/heads/master c: 5c8124a0f8f50c5671b028b7a030d893a3a1a539 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/tty/serial/amba-pl011.c | 29 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index ea005e5fae89..d551a417628b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b3564c2cf464e11f8cb4f8d9c124e5e0f5418e3f +refs/heads/master: 5c8124a0f8f50c5671b028b7a030d893a3a1a539 diff --git a/trunk/drivers/tty/serial/amba-pl011.c b/trunk/drivers/tty/serial/amba-pl011.c index ea7aa973ab43..d7e1edec50b5 100644 --- a/trunk/drivers/tty/serial/amba-pl011.c +++ b/trunk/drivers/tty/serial/amba-pl011.c @@ -1284,11 +1284,40 @@ static void pl011_break_ctl(struct uart_port *port, int break_state) } #ifdef CONFIG_CONSOLE_POLL + +static void pl011_quiesce_irqs(struct uart_port *port) +{ + struct uart_amba_port *uap = (struct uart_amba_port *)port; + unsigned char __iomem *regs = uap->port.membase; + + writew(readw(regs + UART011_MIS), regs + UART011_ICR); + /* + * There is no way to clear TXIM as this is "ready to transmit IRQ", so + * we simply mask it. start_tx() will unmask it. + * + * Note we can race with start_tx(), and if the race happens, the + * polling user might get another interrupt just after we clear it. + * But it should be OK and can happen even w/o the race, e.g. + * controller immediately got some new data and raised the IRQ. + * + * And whoever uses polling routines assumes that it manages the device + * (including tx queue), so we're also fine with start_tx()'s caller + * side. + */ + writew(readw(regs + UART011_IMSC) & ~UART011_TXIM, regs + UART011_IMSC); +} + static int pl011_get_poll_char(struct uart_port *port) { struct uart_amba_port *uap = (struct uart_amba_port *)port; unsigned int status; + /* + * The caller might need IRQs lowered, e.g. if used with KDB NMI + * debugger. + */ + pl011_quiesce_irqs(port); + status = readw(uap->port.membase + UART01x_FR); if (status & UART01x_FR_RXFE) return NO_POLL_CHAR;