From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751817AbaHRRdM (ORCPT ); Mon, 18 Aug 2014 13:33:12 -0400 Received: from mail-wi0-f172.google.com ([209.85.212.172]:41507 "EHLO mail-wi0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751767AbaHRRdI (ORCPT ); Mon, 18 Aug 2014 13:33:08 -0400 Message-ID: <53F238CB.3080007@gmail.com> Date: Mon, 18 Aug 2014 19:32:59 +0200 From: Dirk Behme User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.0 MIME-Version: 1.0 To: Daniel Thompson , Russell King CC: 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: Re: [PATCH v9 16/16] serial: imx: Add support for KGDB's FIQ/NMI mode References: <1404979427-12943-1-git-send-email-daniel.thompson@linaro.org> <1408372091-12689-17-git-send-email-daniel.thompson@linaro.org> In-Reply-To: <1408372091-12689-17-git-send-email-daniel.thompson@linaro.org> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 18.08.2014 16:28, Daniel Thompson wrote: > 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 Thanks Dirk > --- > 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 >