From patchwork Tue Jan 17 10:52:28 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 6252 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 5B64B23E0E for ; Tue, 17 Jan 2012 10:53:07 +0000 (UTC) Received: from mail-bk0-f52.google.com (mail-bk0-f52.google.com [209.85.214.52]) by fiordland.canonical.com (Postfix) with ESMTP id 45507A18447 for ; Tue, 17 Jan 2012 10:53:07 +0000 (UTC) Received: by bkbzt4 with SMTP id zt4so1520851bkb.11 for ; Tue, 17 Jan 2012 02:53:07 -0800 (PST) Received: by 10.205.26.67 with SMTP id rl3mr6555448bkb.45.1326797586964; Tue, 17 Jan 2012 02:53:06 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.205.82.144 with SMTP id ac16cs115830bkc; Tue, 17 Jan 2012 02:53:06 -0800 (PST) Received: by 10.180.101.101 with SMTP id ff5mr21845172wib.14.1326797585123; Tue, 17 Jan 2012 02:53:05 -0800 (PST) Received: from eu1sys200aog118.obsmtp.com (eu1sys200aog118.obsmtp.com. [207.126.144.145]) by mx.google.com with SMTP id q19si14888884eeh.45.2012.01.17.02.52.59 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 17 Jan 2012 02:53:05 -0800 (PST) Received-SPF: neutral (google.com: 207.126.144.145 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) client-ip=207.126.144.145; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.145 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) smtp.mail=linus.walleij@stericsson.com Received: from beta.dmz-us.st.com ([167.4.1.35]) (using TLSv1) by eu1sys200aob118.postini.com ([207.126.147.11]) with SMTP ID DSNKTxVTCe40IRnz6vf+/aXI5+8R83nHyHYz@postini.com; Tue, 17 Jan 2012 10:53:04 UTC Received: from zeta.dmz-us.st.com (ns4.st.com [167.4.16.71]) by beta.dmz-us.st.com (STMicroelectronics) with ESMTP id 7945251; Tue, 17 Jan 2012 10:52:29 +0000 (GMT) Received: from relay1.stm.gmessaging.net (unknown [10.230.100.17]) by zeta.dmz-us.st.com (STMicroelectronics) with ESMTP id A697E45; Tue, 17 Jan 2012 09:58:22 +0000 (GMT) Received: from exdcvycastm003.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm003", Issuer "exdcvycastm003" (not verified)) by relay1.stm.gmessaging.net (Postfix) with ESMTPS id 18CC824C080; Tue, 17 Jan 2012 11:52:31 +0100 (CET) Received: from steludxu4075.lud.stericsson.com (10.230.100.153) by smtp.stericsson.com (10.230.100.1) with Microsoft SMTP Server (TLS) id 8.3.83.0; Tue, 17 Jan 2012 11:52:36 +0100 From: Linus Walleij To: Greg Kroah-Hartman , Cc: , Rabin Vincent , , Linus Walleij Subject: [PATCH] serial: amba-pl011: lock console writes against interrupts Date: Tue, 17 Jan 2012 11:52:28 +0100 Message-ID: <1326797548-3353-1-git-send-email-linus.walleij@stericsson.com> X-Mailer: git-send-email 1.7.8 MIME-Version: 1.0 From: Rabin Vincent Protect against pl011_console_write() and the interrupt for the console UART running concurrently on different CPUs. Otherwise the console_write could spin for a long time waiting for the UART to become not busy, while the other CPU continuously services UART interrupts and keeps the UART busy. The checks for sysrq and oops_in_progress are taken from 8250.c. Cc: stable@kernel.org Signed-off-by: Rabin Vincent Reviewed-by: Srinidhi Kasagar Reviewed-by: Bibek Basu Reviewed-by: Shreshtha Kumar Sahu Signed-off-by: Linus Walleij --- drivers/tty/serial/amba-pl011.c | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 6958594..89178b4 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1740,9 +1740,19 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) { struct uart_amba_port *uap = amba_ports[co->index]; unsigned int status, old_cr, new_cr; + unsigned long flags; + int locked = 1; clk_enable(uap->clk); + local_irq_save(flags); + if (uap->port.sysrq) + locked = 0; + else if (oops_in_progress) + locked = spin_trylock(&uap->port.lock); + else + spin_lock(&uap->port.lock); + /* * First save the CR then disable the interrupts */ @@ -1762,6 +1772,10 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) } while (status & UART01x_FR_BUSY); writew(old_cr, uap->port.membase + UART011_CR); + if (locked) + spin_unlock(&uap->port.lock); + local_irq_restore(flags); + clk_disable(uap->clk); }