Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752276AbdF3MFb (ORCPT ); Fri, 30 Jun 2017 08:05:31 -0400 Received: from bhuna.collabora.co.uk ([46.235.227.227]:37582 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752016AbdF3MFV (ORCPT ); Fri, 30 Jun 2017 08:05:21 -0400 From: Romain Perier To: Greg Kroah-Hartman Cc: linux-serial@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Nandor Han , Romain Perier Subject: [PATCH 6/7] serial: imx: update the stop rx,tx procedures Date: Fri, 30 Jun 2017 14:04:45 +0200 Message-Id: <20170630120446.13994-7-romain.perier@collabora.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170630120446.13994-1-romain.perier@collabora.com> References: <20170630120446.13994-1-romain.perier@collabora.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2759 Lines: 87 From: Nandor Han According to "Documentation/serial/driver" both procedures should stop receiving or sending data. Based on this the procedures should stop the activity regardless if DMA is enabled or not. This commit updates both imx_stop_{rx|tx} procedures to stop the activity and disable the interrupts related to that. In case DMA is used the sg buffers are also un-maped. Signed-off-by: Nandor Han Signed-off-by: Romain Perier --- drivers/tty/serial/imx.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 58d6b1c..d5b6e09 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -360,6 +360,9 @@ static void imx_port_rts_auto(struct imx_port *sport, unsigned long *ucr2) *ucr2 |= UCR2_CTSC; } +static void imx_stop_rx_dma(struct imx_port *sport); +static void imx_stop_tx_dma(struct imx_port *sport); + /* * interrupts disabled on entry */ @@ -368,15 +371,14 @@ static void imx_stop_tx(struct uart_port *port) struct imx_port *sport = (struct imx_port *)port; unsigned long temp; - /* - * We are maybe in the SMP context, so if the DMA TX thread is running - * on other cpu, we have to wait for it to finish. - */ - if (sport->dma_is_enabled && sport->dma_is_txing) - return; + sport->tx_bytes = 0; + + if (sport->dma_is_enabled) + imx_stop_tx_dma(sport); temp = readl(port->membase + UCR1); - writel(temp & ~UCR1_TXMPTYEN, port->membase + UCR1); + temp &= ~(UCR1_TXMPTYEN | UCR1_TRDYEN | UCR1_RTSDEN); + writel(temp, port->membase + UCR1); /* in rs485 mode disable transmitter if shifter is empty */ if (port->rs485.flags & SER_RS485_ENABLED && @@ -403,21 +405,20 @@ static void imx_stop_rx(struct uart_port *port) struct imx_port *sport = (struct imx_port *)port; unsigned long temp; - if (sport->dma_is_enabled && sport->dma_is_rxing) { - if (sport->port.suspended) { - dmaengine_terminate_all(sport->dma_chan_rx); - sport->dma_is_rxing = 0; - } else { - return; - } - } + if (sport->dma_is_enabled) + imx_stop_rx_dma(sport); + + temp = readl(sport->port.membase + UCR1); + temp &= ~UCR1_RRDYEN; + writel(temp, sport->port.membase + UCR1); temp = readl(sport->port.membase + UCR2); - writel(temp & ~UCR2_RXEN, sport->port.membase + UCR2); + temp &= ~UCR2_ATEN; + writel(temp, sport->port.membase + UCR2); - /* disable the `Receiver Ready Interrrupt` */ - temp = readl(sport->port.membase + UCR1); - writel(temp & ~UCR1_RRDYEN, sport->port.membase + UCR1); + temp = readl(sport->port.membase + UCR3); + temp &= ~UCR3_AWAKEN; + writel(temp, sport->port.membase + UCR3); } /* -- 1.8.3.1