From patchwork Mon Aug 18 14:28:11 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Thompson X-Patchwork-Id: 4737101 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 1FBF5C0338 for ; Mon, 18 Aug 2014 14:33:22 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 37EAD2011D for ; Mon, 18 Aug 2014 14:33:16 +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 E7F4C200F2 for ; Mon, 18 Aug 2014 14:33:14 +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 1XJNwF-0005w0-9F; Mon, 18 Aug 2014 14:29:35 +0000 Received: from mail-wg0-f47.google.com ([74.125.82.47]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1XJNvf-000543-8L for linux-arm-kernel@lists.infradead.org; Mon, 18 Aug 2014 14:29:00 +0000 Received: by mail-wg0-f47.google.com with SMTP id b13so4957222wgh.6 for ; Mon, 18 Aug 2014 07:28:35 -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=eEsvXReUbJV2jg1kKgJ4pWGXvsdvv5Witl2+qO0RI3I=; b=e26A+W81mJ9BTvcVNGANPwQ1AS3JNy/MlR6JmL044TSlN64y5AIGc2CKrqKKPVvFr8 Kx93lGL22iXZ1uVzAU7zT1EmTxzmApNUfEh6NMv+i0GkJcodpOOLUbJX39VnROQQ0dSx 3EIpbMyBTKa5ICqm5I3zZNkf1Sq5yG3tkEAr1M+uZ/lXRgkCuNUmyGXB7qVNC3QGgMwL uKi7OyYsptuF7S6yusoc21YPXmG+XU9zFCqFS+mf02k03FY6/VPjx22LIFR+HukDIPmm PTkJcgno3KKHfuHbpOS8TXmwAny0/Xz9u9B3oxxLxbhBG3M6Vg51pJap4I+kAhM0/dC4 Xcwg== X-Gm-Message-State: ALoCoQmoxBnTUNiwaOFl3dVK35rP4YbjCsaAUVdOpNnvsb5SJgns2GMee4X/JZfQldChXjmPFRi2 X-Received: by 10.180.184.20 with SMTP id eq20mr40730421wic.37.1408372115138; Mon, 18 Aug 2014 07:28:35 -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 pe6sm42668080wjb.38.2014.08.18.07.28.33 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 18 Aug 2014 07:28:34 -0700 (PDT) From: Daniel Thompson To: Russell King Subject: [PATCH v9 16/16] serial: imx: Add support for KGDB's FIQ/NMI mode Date: Mon, 18 Aug 2014 15:28:11 +0100 Message-Id: <1408372091-12689-17-git-send-email-daniel.thompson@linaro.org> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1404979427-12943-1-git-send-email-daniel.thompson@linaro.org> References: <1404979427-12943-1-git-send-email-daniel.thompson@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140818_072859_550425_00641807 X-CRM114-Status: GOOD ( 20.13 ) 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