From patchwork Thu Sep 21 16:18:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martyn Welch X-Patchwork-Id: 9964255 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 86D9E6020C for ; Thu, 21 Sep 2017 16:21:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 73FF52957B for ; Thu, 21 Sep 2017 16:21:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5FC0F29592; Thu, 21 Sep 2017 16:21:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D19FB2959F for ; Thu, 21 Sep 2017 16:21:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=iaEVQqT7Gja0gJ89goygahQqIMLeqH3TuGEsCyQC2QU=; b=nZdRmcNRJdvm8Idkb99QRtEzOa f7Gt/bJnUrcJxVcC/rGldi6U6Fuba4AQ4JjSxaCAyRBI9Iys/d4N6y7phuVvfdltW+dMtzO3thtnH xb4YZkGBbFTCEMzCskUhYRShDAkASIAOCDJQeRLe5MwLdS95R+4ZO9ySn9AG+fJk5ydyQaZIiODfP wOepk9fPgmBxyetgXYUYobgvyx5SQN+truUSAs3K+Gx8LFJXsfYrnAUBN63OG3ioJoZhn8JVpvoem SKMBGUqMe2+v7HM4T3hvJEesB1KPItVJWxdl8B9PrhlmsJuCp9OFiaDU4skV9iUq/2V8nkMQeKuTn 3QBE62XQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dv4EY-0005uG-Lb; Thu, 21 Sep 2017 16:21:50 +0000 Received: from bhuna.collabora.co.uk ([46.235.227.227]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dv4C5-0002gT-Bh for linux-arm-kernel@lists.infradead.org; Thu, 21 Sep 2017 16:19:22 +0000 Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: martyn) with ESMTPSA id BABCC268BBA Received: by kratos.localdomain (Postfix, from userid 1000) id DF5DF204D84BE; Thu, 21 Sep 2017 17:18:22 +0100 (BST) From: Martyn Welch To: Greg Kroah-Hartman Subject: [PATCH v3 6/6] serial: imx: Fix imx_shutdown procedure Date: Thu, 21 Sep 2017 17:18:17 +0100 Message-Id: <1506010697-22114-7-git-send-email-martyn.welch@collabora.co.uk> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1506010697-22114-1-git-send-email-martyn.welch@collabora.co.uk> References: <1506010697-22114-1-git-send-email-martyn.welch@collabora.co.uk> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170921_091918_045545_C18D4363 X-CRM114-Status: GOOD ( 11.75 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Martyn Welch , Nandor Han , linux-kernel@vger.kernel.org, Fabio Estevam , linux-serial@vger.kernel.org, u.kleine-koenig@pengutronix.de, Romain Perier , linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Nandor Han In some cases, it looks that interrupts can happen after the dma was disabled and port was not yet shutdown. This will result in interrupts handled by imx_rxint. This commits updates the shutdown function to ensure that underlying components are disabled in the right order. This disables RX and TX blocks, then it disabled interrupts. In case DMA is enabled, it disables DMA and free corresponding resources. It disables UART port and stop clocks. Signed-off-by: Nandor Han Signed-off-by: Romain Perier Signed-off-by: Martyn Welch --- drivers/tty/serial/imx.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 256b128..393c1c0 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -1368,44 +1368,40 @@ static void imx_shutdown(struct uart_port *port) unsigned long temp; unsigned long flags; - if (sport->dma_is_enabled) { - sport->dma_is_rxing = 0; - sport->dma_is_txing = 0; - dmaengine_terminate_sync(sport->dma_chan_tx); - dmaengine_terminate_sync(sport->dma_chan_rx); - + if (!sport->port.suspended) { spin_lock_irqsave(&sport->port.lock, flags); imx_stop_tx(port); imx_stop_rx(port); - imx_disable_dma(sport); + + if (sport->dma_is_inited && sport->dma_is_enabled) + imx_disable_dma(sport); + spin_unlock_irqrestore(&sport->port.lock, flags); imx_uart_dma_exit(sport); } - mctrl_gpio_disable_ms(sport->gpios); - spin_lock_irqsave(&sport->port.lock, flags); temp = readl(sport->port.membase + UCR2); - temp &= ~(UCR2_TXEN); + temp &= ~(UCR2_TXEN | UCR2_RXEN); writel(temp, sport->port.membase + UCR2); + temp = readl(sport->port.membase + UCR4); + temp &= ~UCR4_OREN; + writel(temp, sport->port.membase + UCR4); spin_unlock_irqrestore(&sport->port.lock, flags); - /* - * Stop our timer. - */ - del_timer_sync(&sport->timer); + mctrl_gpio_disable_ms(sport->gpios); - /* - * Disable all interrupts, port and break condition. - */ + /* Stop our timer. */ + del_timer_sync(&sport->timer); + /* Disable port. */ spin_lock_irqsave(&sport->port.lock, flags); temp = readl(sport->port.membase + UCR1); - temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); - + temp &= ~UCR1_UARTEN; writel(temp, sport->port.membase + UCR1); spin_unlock_irqrestore(&sport->port.lock, flags); + /* Disable clocks. */ clk_disable_unprepare(sport->clk_per); clk_disable_unprepare(sport->clk_ipg); }