[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <53F238CB.3080007@gmail.com>
Date: Mon, 18 Aug 2014 19:32:59 +0200
From: Dirk Behme <dirk.behme@...il.com>
To: Daniel Thompson <daniel.thompson@...aro.org>,
Russell King <linux@....linux.org.uk>
CC: linux-kernel@...r.kernel.org, linux-arm-kernel@...ts.infradead.org,
kgdb-bugreport@...ts.sourceforge.net, patches@...aro.org,
linaro-kernel@...ts.linaro.org,
John Stultz <john.stultz@...aro.org>,
Anton Vorontsov <anton.vorontsov@...aro.org>,
Colin Cross <ccross@...roid.com>, kernel-team@...roid.com,
Rob Herring <robherring2@...il.com>,
Linus Walleij <linus.walleij@...aro.org>,
Ben Dooks <ben.dooks@...ethink.co.uk>,
Catalin Marinas <catalin.marinas@....com>,
Dave Martin <Dave.Martin@....com>,
Fabio Estevam <festevam@...il.com>,
Frederic Weisbecker <fweisbec@...il.com>,
Nicolas Pitre <nico@...aro.org>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Jiri Slaby <jslaby@...e.cz>, linux-serial@...r.kernel.org
Subject: Re: [PATCH v9 16/16] serial: imx: Add support for KGDB's FIQ/NMI
mode
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 <daniel.thompson@...aro.org>
> Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
> Cc: Jiri Slaby <jslaby@...e.cz>
> Cc: linux-serial@...r.kernel.org
Acked-by: Dirk Behme <dirk.behme@...bosch.com>
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 <linux/of_device.h>
> #include <linux/io.h>
> #include <linux/dma-mapping.h>
> +#include <linux/kgdb.h>
>
> #include <asm/irq.h>
> #include <linux/platform_data/serial-imx.h>
> @@ -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
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists