From patchwork Mon Jan 26 00:10:16 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Agner X-Patchwork-Id: 5705861 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 8ACAF9F2ED for ; Mon, 26 Jan 2015 00:14:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A32A320154 for ; Mon, 26 Jan 2015 00:14:18 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D097E20142 for ; Mon, 26 Jan 2015 00:14:17 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YFXGU-0007u5-0j; Mon, 26 Jan 2015 00:10:50 +0000 Received: from mail.kmu-office.ch ([2a02:418:6a02::a2]) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YFXGP-0007ss-LH for linux-arm-kernel@lists.infradead.org; Mon, 26 Jan 2015 00:10:47 +0000 Received: from trochilidae.agner.local (195-226-23-137.pool.cyberlink.ch [195.226.23.137]) by mail.kmu-office.ch (Postfix) with ESMTPSA id 6D3585C0771; Mon, 26 Jan 2015 01:08:22 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=agner.ch; s=dkim; t=1422230902; bh=uBgNDwNUr9HErq+LT8qBmDFliDPR62WKLQQY4LDGW5g=; h=From:To:Cc:Subject:Date:From; b=uLk7NCZffPivNr+LOL/kg/eL4Sj00JKJcyX+ASpbxYxD8rdD6lYc25LCGe6hknR4f RD73egYh4lVzEm5Bg0h8ju+jC2DK0dCPkvCtvDzgBVSmz8t/YUJEyMoTvBawPaNIGa uhWI+LBjRXB5OJYnctxnM5gmuZ+7gjTV4p4hVnyY= From: Stefan Agner To: gregkh@linuxfoundation.org Subject: [PATCH] tty: serial: fsl_lpuart: terminate DMA on buffer flush Date: Mon, 26 Jan 2015 01:10:16 +0100 Message-Id: <1422231016-27793-1-git-send-email-stefan@agner.ch> X-Mailer: git-send-email 2.2.2 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150125_161045_859504_29DE052F X-CRM114-Status: UNSURE ( 9.91 ) X-CRM114-Notice: Please train this message. X-Spam-Score: -0.1 (/) Cc: linux-kernel@vger.kernel.org, stefan@agner.ch, linux-serial@vger.kernel.org, jingchang.lu@freescale.com, shawn.guo@linaro.org, jslaby@suse.cz, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On uart buffer flush, serial core resets the circular buffer. If a DMA transfer is in progress at that time, the callback lpuart_dma_tx_complete will move buffer's tail unconditionally, hence tail moves beyond head. Use the flush_buffer hook to terminate the DMA imeaditely and avoid lpuart_dma_tx_complete being called in this situation. This bug often showed up while shutdown and lead to duplicate serial console output. Signed-off-by: Stefan Agner --- drivers/tty/serial/fsl_lpuart.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index e95c497..7615b5d 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -454,6 +454,15 @@ static int lpuart_dma_rx(struct lpuart_port *sport) return 0; } +static void lpuart_flush_buffer(struct uart_port *port) +{ + struct lpuart_port *sport = container_of(port, struct lpuart_port, port); + if (sport->lpuart_dma_tx_use) { + dmaengine_terminate_all(sport->dma_tx_chan); + sport->dma_tx_in_progress = 0; + } +} + static void lpuart_dma_rx_complete(void *arg) { struct lpuart_port *sport = arg; @@ -1519,6 +1528,7 @@ static struct uart_ops lpuart_pops = { .release_port = lpuart_release_port, .config_port = lpuart_config_port, .verify_port = lpuart_verify_port, + .flush_buffer = lpuart_flush_buffer, }; static struct uart_ops lpuart32_pops = { @@ -1537,6 +1547,7 @@ static struct uart_ops lpuart32_pops = { .release_port = lpuart_release_port, .config_port = lpuart_config_port, .verify_port = lpuart_verify_port, + .flush_buffer = lpuart_flush_buffer, }; static struct lpuart_port *lpuart_ports[UART_NR];