From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751798AbdBFJbT (ORCPT ); Mon, 6 Feb 2017 04:31:19 -0500 Received: from smtpout.microchip.com ([198.175.253.82]:40409 "EHLO email.microchip.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751281AbdBFJbQ (ORCPT ); Mon, 6 Feb 2017 04:31:16 -0500 Subject: Re: [PATCH] tty/serial: atmel: ensure state is restored after suspending To: Alexandre Belloni , Richard Genoud References: <20170203225316.10466-1-alexandre.belloni@free-electrons.com> CC: Greg Kroah-Hartman , , , From: Nicolas Ferre Organization: atmel Message-ID: <8d788b97-5dfa-1beb-e561-2a558a62e56b@atmel.com> Date: Mon, 6 Feb 2017 10:31:42 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.7.0 MIME-Version: 1.0 In-Reply-To: <20170203225316.10466-1-alexandre.belloni@free-electrons.com> Content-Type: text/plain; charset="windows-1252" Content-Transfer-Encoding: 8bit X-Brightmail-Tracker: =?Windows-1252?Q?H4sIAAAAAAAAC+NgFrrFKsWRWlGSWpSXmKPExsXCxeXDopvsNCPC4Pnf?= =?Windows-1252?Q?Oyd4LDquLWayaF68ns1i0+NrrBaXd81hszizuJfdYvbONUwObB5PNl1k?= =?Windows-1252?Q?9Ng56y67x/65a9g9Ni+p9/i8SS6ANYo1My8pvyKBNePoFI6CdqmKg73H?= =?Windows-1252?Q?mBsYl4p2MXJxCAksZ5SYfPIlWxcjJ4ewQLBEZ0c7E4gtIpApsWDvDXYQ?= =?Windows-1252?Q?W0jAU+LxqiMsIA3MAjMZJf7v3wBWxCagK3F2whOgZg4OfgFhiTNT40HC?= =?Windows-1252?Q?vAI2EtsOPGQBsVkEVCSO7jwJNl9UIEJi/tNVTBA1ghInZz5hAWnlFPCS?= =?Windows-1252?Q?eNGWDhJmFjCQOLJoDiuELS/RvHU2M8QJKhJ97/vBzpEQCJT4uH01K4Tt?= =?Windows-1252?Q?JNF1ciIbhG0ncXj6RagaB4ntu76wwNTs+nyZGcLWltj+ah9Ur47EtoP9?= =?Windows-1252?Q?UDW2EntmTGSCsN0lHjxaDmX7Ssx62ABVEyXR+Owh0wRGqVlIPpiF5OxZ?= =?Windows-1252?Q?SM5ewMi8ilHa2cNPNzhM1zXC2cPARC83OaNANzcxM08vOT93EyMkljN3?= =?Windows-1252?Q?MLZ1RRxilORgUhLlNfSYGiHEl5SfUpmRWJwRX1Sak1p8iFGGg0NJgtfM?= =?Windows-1252?Q?YUaEkGBRanpqRVpmDjCpwKSZODgPMUpw8CiJ8CaA1PAWFyTmFmemQ+RP?= =?Windows-1252?Q?MUpKifP6gyQEQBIZpXlwvZcYRaWEeXcaAeV4ClKLcjNLIOK3GMU4HjJx?= =?Windows-1252?Q?PGYSYsnLz0uVAjqVAQgMGF8xinMwKgnz1oKM48nMK4Fb8wroAiagC7Zd?= =?Windows-1252?Q?mQZyQUkiQkqqgXHbI2uZf8fM3eT1z36NviV5XWe7RV8Wz7IZ1Yr2Lcs+?= =?Windows-1252?Q?sOT9Yec1+zwvrPfL7LdfjjmX2PC8OTI7vGHrzdzH0YURrmoB8cJcDaKb?= =?Windows-1252?Q?mooerFz0d6HVwx039+TkZAfnPwmO3N8tWjvVWb0kiFuu7brC8vZJyYtO?= =?Windows-1252?Q?Lrt1f9OHK61FMo8Dt0no/nmwe5cSS3FGoqEWc1FxIgCgFOZSbQMAAA?= =?Windows-1252?Q?=3D=3D?= Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Le 03/02/2017 à 23:53, Alexandre Belloni a écrit : > When going to suspend, the UART registers may be lost because the power to > VDDcore is cut. This is not an issue in the normal case but when > no_console_suspend is used, we need to restore the registers in order to > get a functional console. > > Signed-off-by: Alexandre Belloni Reviewed-by: Nicolas Ferre Thanks, > --- > drivers/tty/serial/atmel_serial.c | 44 +++++++++++++++++++++++++++++++++++++++ > 1 file changed, 44 insertions(+) > > diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c > index 168b10cad47b..22e0a73c0cb7 100644 > --- a/drivers/tty/serial/atmel_serial.c > +++ b/drivers/tty/serial/atmel_serial.c > @@ -175,6 +175,17 @@ struct atmel_uart_port { > unsigned int pending_status; > spinlock_t lock_suspended; > > + struct { > + u32 cr; > + u32 mr; > + u32 imr; > + u32 brgr; > + u32 rtor; > + u32 ttgr; > + u32 fmr; > + u32 fimr; > + } cache; > + > int (*prepare_rx)(struct uart_port *port); > int (*prepare_tx)(struct uart_port *port); > void (*schedule_rx)(struct uart_port *port); > @@ -2649,6 +2660,20 @@ static int atmel_serial_suspend(struct platform_device *pdev, > cpu_relax(); > } > > + if (atmel_is_console_port(port) && !console_suspend_enabled) { > + /* Cache register values as we won't get a full shutdown/startup > + * cycle > + */ > + atmel_port->cache.mr = atmel_uart_readl(port, ATMEL_US_MR); > + atmel_port->cache.imr = atmel_uart_readl(port, ATMEL_US_IMR); > + atmel_port->cache.brgr = atmel_uart_readl(port, ATMEL_US_BRGR); > + atmel_port->cache.rtor = atmel_uart_readl(port, > + atmel_port->rtor); > + atmel_port->cache.ttgr = atmel_uart_readl(port, ATMEL_US_TTGR); > + atmel_port->cache.fmr = atmel_uart_readl(port, ATMEL_US_FMR); > + atmel_port->cache.fimr = atmel_uart_readl(port, ATMEL_US_FIMR); > + } > + > /* we can not wake up if we're running on slow clock */ > atmel_port->may_wakeup = device_may_wakeup(&pdev->dev); > if (atmel_serial_clk_will_stop()) { > @@ -2671,6 +2696,25 @@ static int atmel_serial_resume(struct platform_device *pdev) > struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); > unsigned long flags; > > + if (atmel_is_console_port(port) && !console_suspend_enabled) { > + atmel_uart_writel(port, ATMEL_US_MR, atmel_port->cache.mr); > + atmel_uart_writel(port, ATMEL_US_IER, atmel_port->cache.imr); > + atmel_uart_writel(port, ATMEL_US_BRGR, atmel_port->cache.brgr); > + atmel_uart_writel(port, atmel_port->rtor, > + atmel_port->cache.rtor); > + atmel_uart_writel(port, ATMEL_US_TTGR, atmel_port->cache.ttgr); > + > + if (atmel_port->fifo_size) { > + atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_FIFOEN | > + ATMEL_US_RXFCLR | ATMEL_US_TXFLCLR); > + atmel_uart_writel(port, ATMEL_US_FMR, > + atmel_port->cache.fmr); > + atmel_uart_writel(port, ATMEL_US_FIER, > + atmel_port->cache.fimr); > + } > + atmel_start_rx(port); > + } > + > spin_lock_irqsave(&atmel_port->lock_suspended, flags); > if (atmel_port->pending) { > atmel_handle_receive(port, atmel_port->pending); > -- Nicolas Ferre