From patchwork Fri Sep 25 08:24:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthias Schiffer X-Patchwork-Id: 11799329 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5E591112C for ; Fri, 25 Sep 2020 08:26:41 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D448620888 for ; Fri, 25 Sep 2020 08:26:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="ialemE+u"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=tq-group.com header.i=@tq-group.com header.b="Ndz2p70T" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D448620888 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=ew.tq-group.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id: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:In-Reply-To:References:List-Owner; bh=S/ZVph1+ZKQsK1ibInwe8tM0nESewiPOEwhXPamhhJg=; b=ialemE+uxtLyy3goNObDjjSU/Z hQdeCSvlSJRqe8p2vot3F/bGlPaSSGJo7fcRfEkBwOO63b7eJAbxJ4wZdkRiMX7/QQ0faeq9+12tt 2HSLXK1IVNx9td4xj1UiIPyN7YjKSdKFIRmjOwtopDl9ftprFrrc2vPMsSbEGUS9HxTqYym0svb1k X1FXpVSL2ElriypNi26kF92BOCh3y2LPX6iUsfWAQ1K2XAIMj7AmXu4F4kp48bAgt/1DLVmSg5KpM gjgqJPwbAb0yaNDhvFRx/p+RskY70TpIuNTwrW+jREO2jIv9sKmJWlttifwqZ7nUG9q9/1qPOyD5z 7s7/jeEA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kLj3i-0003Qw-O9; Fri, 25 Sep 2020 08:26:26 +0000 Received: from mx1.tq-group.com ([62.157.118.193]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kLj3f-0003PA-IB for linux-arm-kernel@lists.infradead.org; Fri, 25 Sep 2020 08:26:24 +0000 IronPort-SDR: oukt6M82CajUSxmUI3NFGy+/eRMaQNpCdyRFjRXdYhvcXH+yPZNxZqv/9mDpWDEj/FS3ZQUoAO 5x3Z2HDIcow8spsV3lHRjho++hR80/EBfPVQlEEUT8axsGruIzYF6ULT4vqXwA147V5sVvTXRc L4lJtfJillK8mrS7gTf22lzNsyWFFpWaLZLYKGodOZtXVIB+iiHvuuLBqiWWVLB1VtnjJ0z7ro 3bbEuQqTmoKNsC2+nn3rHYs9PBIpTAg7FeCtRF0ESrI0mBSaw9gaoV5JYUMSncZa4wqpOiQ3SG 4dU= X-IronPort-AV: E=Sophos;i="5.77,301,1596492000"; d="scan'208";a="14020024" Received: from unknown (HELO tq-pgp-pr1.tq-net.de) ([192.168.6.15]) by mx1-pgp.tq-group.com with ESMTP; 25 Sep 2020 10:26:19 +0200 Received: from mx1.tq-group.com ([192.168.6.7]) by tq-pgp-pr1.tq-net.de (PGP Universal service); Fri, 25 Sep 2020 10:26:19 +0200 X-PGP-Universal: processed; by tq-pgp-pr1.tq-net.de on Fri, 25 Sep 2020 10:26:19 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=tq-group.com; i=@tq-group.com; q=dns/txt; s=key1; t=1601022379; x=1632558379; h=from:to:cc:subject:date:message-id; bh=wa4VDC7nYhm5Z0O3jCNMttNKrenLGZ76s9lR1PPSFmk=; b=Ndz2p70TJxcP/HF+mJCDKAnS9exTlUWaZba0QMxZSo06G0DlX7OsiSC0 Ep9Jv6q1X9BupahCBqeFfPxB+75i5YKo0DWZ15R/BgOhtu6zMDCzD6CyM 4kC8Amr8oSeAoP+k8teu5ggq+9pxOiCJTOVjOi8DLQeOqpN3HFSey/wxN 0IUBcEhe6zx3XmcMFm+qgw1KXS9+todCJ92wJHcPrLiwveDMDQERUKzxT SEZ/LtYutHV38/+uncqoNYQ7xaXWNHer1RZvbsNs0EhJAWOe8bl1pI5MD DzCvNxMhJo6xPQRD5mzJnPBn/9EVw85eVXZrZ5GHM00NYYsoxEsBx0t9C g==; IronPort-SDR: WOXDDWsnRCO4+uDrIDHyKZ5W0HGF4eNYnH3SogLviEQcXGb+xihJQgo/wf1N6D5GoZWYekR32j 5ClPcid/rnmYWzk66AgoojnEwhooxHw1qWSuM5iBuq+XpIzZGPCKhltWQHgDsU8OB8Do1p/c09 UqYBB7GtMQdqo+sbwDsQgr8OEYTMMNKMt6c8R1aEQT7QVa3v/QR3nAVKFopZ6YN1lxKj5nUWwU FF5saJ3TiFy+jvrgw/Ut1Dzuvgj4l4edpKKO8ndLJ1S4DBblKjLjZ+nQUHbmGXBp5/BLCoFpDD 43w= X-IronPort-AV: E=Sophos;i="5.77,301,1596492000"; d="scan'208";a="14020023" Received: from vtuxmail01.tq-net.de ([10.115.0.20]) by mx1.tq-group.com with ESMTP; 25 Sep 2020 10:26:19 +0200 Received: from schifferm-ubuntu4.tq-net.de (schifferm-ubuntu4.tq-net.de [10.117.48.12]) by vtuxmail01.tq-net.de (Postfix) with ESMTPA id D3CDB280070; Fri, 25 Sep 2020 10:26:18 +0200 (CEST) From: Matthias Schiffer To: Greg Kroah-Hartman , Jiri Slaby , Shawn Guo , Sascha Hauer Subject: [PATCH] tty: serial: imx: disable TXDC IRQ in imx_uart_shutdown() to avoid IRQ storm Date: Fri, 25 Sep 2020 10:24:12 +0200 Message-Id: <20200925082412.12960-1-matthias.schiffer@ew.tq-group.com> X-Mailer: git-send-email 2.17.1 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200925_042623_848925_78387B33 X-CRM114-Status: GOOD ( 16.95 ) X-Spam-Score: -0.1 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.1 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 SPF_NONE SPF: sender does not publish an SPF Record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Matthias Schiffer , linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, NXP Linux Team , Pengutronix Kernel Team , Fabio Estevam , 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 The IPG clock is disabled at the end of imx_uart_shutdown(); we really don't want to run any IRQ handlers after this point. At least on i.MX8MN, the UART will happily continue to generate interrupts even with its clocks disabled, but in this state, all register writes are ignored (which will cause the shadow registers to differ from the actual register values, resulting in all kinds of weirdness). In a transfer without DMA, this could lead to the following sequence of events: - The UART finishes its transmission while imx_uart_shutdown() is run, triggering the TXDC interrupt (we can trigger this fairly reliably by writing a single byte to the TTY and closing it right away) - imx_uart_shutdown() finishes, disabling the UART clocks - imx_uart_int() -> imx_uart_transmit_buffer() -> imx_uart_stop_tx() imx_uart_stop_tx() should now clear UCR4_TCEN to disable the TXDC interrupt, but this register write is ineffective. This results in an interrupt storm. To disable all interrupts in the same place, and to avoid setting UCR4 twice, clearing UCR4_OREN is moved below del_timer_sync() as well; this should be harmless. Signed-off-by: Matthias Schiffer --- While debugging this, I found one more instance of register writes with disabled clock: The IPG clock is disabled before calling uart_add_one_port() at the end of imx_uart_probe(). This results in the following call stack: imx_uart_writel+0x168/0x188 imx_uart_set_mctrl+0x3c/0xb8 uart_add_one_port+0x394/0x4c8 imx_uart_probe+0x530/0x810 Fortunately, in this case the register already matches the value that is written, so no inconsistent state results. I assume we'll have to do something about the way we handle the clocks in this driver to fix this... drivers/tty/serial/imx.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 4e6ead1f650e..1731d9728865 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -1552,10 +1552,6 @@ static void imx_uart_shutdown(struct uart_port *port) ucr2 = imx_uart_readl(sport, UCR2); ucr2 &= ~(UCR2_TXEN | UCR2_ATEN); imx_uart_writel(sport, ucr2, UCR2); - - ucr4 = imx_uart_readl(sport, UCR4); - ucr4 &= ~UCR4_OREN; - imx_uart_writel(sport, ucr4, UCR4); spin_unlock_irqrestore(&sport->port.lock, flags); /* @@ -1568,10 +1564,15 @@ static void imx_uart_shutdown(struct uart_port *port) */ spin_lock_irqsave(&sport->port.lock, flags); + ucr1 = imx_uart_readl(sport, UCR1); ucr1 &= ~(UCR1_TRDYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN | UCR1_RXDMAEN | UCR1_ATDMAEN); - imx_uart_writel(sport, ucr1, UCR1); + + ucr4 = imx_uart_readl(sport, UCR4); + ucr4 &= ~(UCR4_OREN | UCR4_TCEN); + imx_uart_writel(sport, ucr4, UCR4); + spin_unlock_irqrestore(&sport->port.lock, flags); clk_disable_unprepare(sport->clk_per);