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: 35513 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pd0-f200.google.com (mail-pd0-f200.google.com [209.85.192.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 279A020523 for ; Mon, 18 Aug 2014 14:28:45 +0000 (UTC) Received: by mail-pd0-f200.google.com with SMTP id w10sf42374568pde.11 for ; Mon, 18 Aug 2014 07:28:39 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=eEsvXReUbJV2jg1kKgJ4pWGXvsdvv5Witl2+qO0RI3I=; b=UdSpgSOrve5JTF27bUHBE8sLBKijl0vlVMcAuAmN/Y8Mxl171clvA8VLNSckqn3kGG TXgeHKSTVRZZ9oDG2atKySbTQEIJEynUUoLguIr08fZUynLbjqlf9t6dE8dHU/XH6QIu dg2akQ8KPe6Fb6v1RxoSF/9l9tKfppIC0z/DFUtBYiOMqrl+VD8slGBiZ0EHRRUjtpwi o+mWJK9NHgoNktTnFgVW05SHQnJT7A90pFPS5TLS0TqW6au1KaIYDJPuwDOW0NyAal2Z F/ADUHrPrAPvP1zYaXzvSoqrS4N9kqgolfw6KlKmN7mGaNEUx0x1CL8eCHXssKFcflgU cqDQ== X-Gm-Message-State: ALoCoQmzRZZWR8E0kXRfyrYKcBpawsyXJOVDtM1Tw2HmdasE/98P/fZw9q+lRaoQha/hcffOlHzS X-Received: by 10.68.219.226 with SMTP id pr2mr18490096pbc.4.1408372118177; Mon, 18 Aug 2014 07:28:38 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.96.202 with SMTP id k68ls2163527qge.48.gmail; Mon, 18 Aug 2014 07:28:38 -0700 (PDT) X-Received: by 10.221.61.5 with SMTP id wu5mr25227404vcb.13.1408372118040; Mon, 18 Aug 2014 07:28:38 -0700 (PDT) Received: from mail-vc0-f176.google.com (mail-vc0-f176.google.com [209.85.220.176]) by mx.google.com with ESMTPS id aa15si3885297vec.35.2014.08.18.07.28.38 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 18 Aug 2014 07:28:38 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.176 as permitted sender) client-ip=209.85.220.176; Received: by mail-vc0-f176.google.com with SMTP id id10so5800983vcb.35 for ; Mon, 18 Aug 2014 07:28:38 -0700 (PDT) X-Received: by 10.221.61.5 with SMTP id wu5mr25227402vcb.13.1408372117960; Mon, 18 Aug 2014 07:28:37 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.221.37.5 with SMTP id tc5csp156841vcb; Mon, 18 Aug 2014 07:28:36 -0700 (PDT) X-Received: by 10.194.89.200 with SMTP id bq8mr42853486wjb.52.1408372115678; Mon, 18 Aug 2014 07:28:35 -0700 (PDT) Received: from mail-wg0-f50.google.com (mail-wg0-f50.google.com [74.125.82.50]) by mx.google.com with ESMTPS id uq3si25674609wjc.26.2014.08.18.07.28.35 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 18 Aug 2014 07:28:35 -0700 (PDT) Received-SPF: pass (google.com: domain of daniel.thompson@linaro.org designates 74.125.82.50 as permitted sender) client-ip=74.125.82.50; Received: by mail-wg0-f50.google.com with SMTP id n12so4936169wgh.21 for ; Mon, 18 Aug 2014 07:28:35 -0700 (PDT) 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 Cc: Daniel Thompson , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kgdb-bugreport@lists.sourceforge.net, patches@linaro.org, linaro-kernel@lists.linaro.org, John Stultz , Anton Vorontsov , Colin Cross , kernel-team@android.com, Rob Herring , Linus Walleij , Ben Dooks , Catalin Marinas , Dave Martin , Fabio Estevam , Frederic Weisbecker , Nicolas Pitre , Greg Kroah-Hartman , Jiri Slaby , linux-serial@vger.kernel.org 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-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: daniel.thompson@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.176 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , 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