From patchwork Tue Aug 19 16:46:09 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Thompson X-Patchwork-Id: 4744891 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 4FBA9C0338 for ; Tue, 19 Aug 2014 17:01:37 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id DD11420109 for ; Tue, 19 Aug 2014 17:01:33 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1880A20166 for ; Tue, 19 Aug 2014 17:01:30 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1XJmkQ-0008Fj-Km; Tue, 19 Aug 2014 16:59:02 +0000 Received: from mail-wi0-f178.google.com ([209.85.212.178]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1XJmjd-0007Rl-9Q for linux-arm-kernel@lists.infradead.org; Tue, 19 Aug 2014 16:58:14 +0000 Received: by mail-wi0-f178.google.com with SMTP id hi2so5631372wib.11 for ; Tue, 19 Aug 2014 09:57:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=juRYkHelD0GUeJ2Bzk1KB/u5FUaC5COVrF9Wu6ezUiU=; b=OG7tEcOS+TGAJUdQvs1PjtiOVotMsAvJWIH02bXn9vQ7j5hfonQhJQqXfWeOKbcY8g 7jcHTABr9UDMPBqukAZlL4DNkdDM+1m54brZZrnOgTt6knWOVFx1q3nujA+RK2JXUTog W6jpSzXtn/Jyf2Nj3+WiNZX2ZvQteHxQM0Nfj21o/LX8p5xKNn2+thN0XC4/asibiF05 cBPWoD8Y7AVYoYPGQOscLbiOIwcsOdP8gN07BlKMd/n4f3vJSw5Msg7OtQxOVRlo/v+z X57LE519EwCgsuRKXl2WeGZRk/ZbRBA1sxzaCKh1JNv+ahsLpDx72KU392uOvGYPnYMZ fF5A== X-Gm-Message-State: ALoCoQmn3tXqWXknmQ+o29OjkVhO7sLHackTxmaWWS1/uTM2BawqzzCYhw7TwSEmZMYUZe3cYGg2 X-Received: by 10.194.78.243 with SMTP id e19mr12352307wjx.119.1408467470004; Tue, 19 Aug 2014 09:57:50 -0700 (PDT) Received: from sundance.lan (cpc4-aztw19-0-0-cust157.18-1.cable.virginm.net. [82.33.25.158]) by mx.google.com with ESMTPSA id gc8sm36225wic.3.2014.08.19.09.57.47 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Aug 2014 09:57:49 -0700 (PDT) From: Daniel Thompson To: Russell King Subject: [PATCH v10 19/19] serial: imx: Add support for KGDB's FIQ/NMI mode Date: Tue, 19 Aug 2014 17:46:09 +0100 Message-Id: <1408466769-20004-20-git-send-email-daniel.thompson@linaro.org> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1408466769-20004-1-git-send-email-daniel.thompson@linaro.org> References: <1408369264-14242-1-git-send-email-daniel.thompson@linaro.org> <1408466769-20004-1-git-send-email-daniel.thompson@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140819_095813_506502_2637CBFE X-CRM114-Status: GOOD ( 19.87 ) X-Spam-Score: -0.7 (/) Cc: Daniel Thompson , linaro-kernel@lists.linaro.org, Catalin Marinas , linux-serial@vger.kernel.org, patches@linaro.org, kgdb-bugreport@lists.sourceforge.net, Linus Walleij , Nicolas Pitre , linux-kernel@vger.kernel.org, Frederic Weisbecker , Anton Vorontsov , Greg Kroah-Hartman , Ben Dooks , John Stultz , Fabio Estevam , Colin Cross , Jiri Slaby , kernel-team@android.com, Dave Martin , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch makes it possible to use the imx uart with KGDB's FIQ/NMI mode. Main changes are: .poll_init() will, if KGDB+FIQ are enabled, perform deeper hardware initialization to ensure the serial port is always active (required otherwise FIQ is not triggered by UART activity). This has an impact on power usage so it is conservatively enabled. imx_put_poll_char() has been simplified to remove the code to disable interrupts. The present code can corrupt register state when re-entered from FIQ handler. Both imx_put_poll_char() and imx_get_poll_char() adopt _relaxed() MMIO functions (which are safe for polled I/O and needed to avoid taking spin locks). Signed-off-by: Daniel Thompson Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: linux-serial@vger.kernel.org Acked-by: Dirk Behme --- drivers/tty/serial/imx.c | 71 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 19 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 983668a..a201c61 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -1505,44 +1506,73 @@ imx_verify_port(struct uart_port *port, struct serial_struct *ser) } #if defined(CONFIG_CONSOLE_POLL) + +#if defined(CONFIG_KGDB_FIQ) +/* + * Prepare the UART to be used from kgdb's NMI support. + */ +static int imx_poll_init(struct uart_port *port) +{ + struct imx_port *sport = (struct imx_port *)port; + unsigned long flags; + unsigned long temp; + int retval; + + retval = clk_prepare_enable(sport->clk_ipg); + if (retval) + return retval; + retval = clk_prepare_enable(sport->clk_per); + if (retval) + clk_disable_unprepare(sport->clk_ipg); + + imx_setup_ufcr(sport, 0); + + spin_lock_irqsave(&sport->port.lock, flags); + + temp = readl(sport->port.membase + UCR1); + if (is_imx1_uart(sport)) + temp |= IMX1_UCR1_UARTCLKEN; + temp |= UCR1_UARTEN | UCR1_RRDYEN; + temp &= ~(UCR1_TXMPTYEN | UCR1_RTSDEN); + writel(temp, sport->port.membase + UCR1); + + temp = readl(sport->port.membase + UCR2); + temp |= UCR2_RXEN; + writel(temp, sport->port.membase + UCR2); + + spin_unlock_irqrestore(&sport->port.lock, flags); + + /* register the FIQ with kgdb */ + kgdb_register_fiq(sport->port.irq); + + return 0; +} +#endif /* CONFIG_KGDB_FIQ */ + static int imx_poll_get_char(struct uart_port *port) { - if (!(readl(port->membase + USR2) & USR2_RDR)) + if (!(readl_relaxed(port->membase + USR2) & USR2_RDR)) return NO_POLL_CHAR; - return readl(port->membase + URXD0) & URXD_RX_DATA; + return readl_relaxed(port->membase + URXD0) & URXD_RX_DATA; } static void imx_poll_put_char(struct uart_port *port, unsigned char c) { - struct imx_port_ucrs old_ucr; unsigned int status; - /* save control registers */ - imx_port_ucrs_save(port, &old_ucr); - - /* disable interrupts */ - writel(UCR1_UARTEN, port->membase + UCR1); - writel(old_ucr.ucr2 & ~(UCR2_ATEN | UCR2_RTSEN | UCR2_ESCI), - port->membase + UCR2); - writel(old_ucr.ucr3 & ~(UCR3_DCD | UCR3_RI | UCR3_DTREN), - port->membase + UCR3); - /* drain */ do { - status = readl(port->membase + USR1); + status = readl_relaxed(port->membase + USR1); } while (~status & USR1_TRDY); /* write */ - writel(c, port->membase + URTX0); + writel_relaxed(c, port->membase + URTX0); /* flush */ do { - status = readl(port->membase + USR2); + status = readl_relaxed(port->membase + USR2); } while (~status & USR2_TXDC); - - /* restore control registers */ - imx_port_ucrs_restore(port, &old_ucr); } #endif @@ -1563,6 +1593,9 @@ static struct uart_ops imx_pops = { .config_port = imx_config_port, .verify_port = imx_verify_port, #if defined(CONFIG_CONSOLE_POLL) +#if defined(CONFIG_KGDB_FIQ) + .poll_init = imx_poll_init, +#endif .poll_get_char = imx_poll_get_char, .poll_put_char = imx_poll_put_char, #endif