From patchwork Tue Jan 10 12:56:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Vasut X-Patchwork-Id: 13095082 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 30B3CC54EBE for ; Tue, 10 Jan 2023 12:57:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:Cc :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=xr4EfjfvG4kn9dR3VgWnJyg4HptECwOtkl6BTFUFYsE=; b=t9VUT7OgoU9w9T NFWsp6YCp8VHEd7pOM+XmBnSKOHBSIjWn7QCCFT1vdBdNO1Ev3U3TP1ZgVAR9Yy/t/BrV/EPsZle4 RiZSOt25oLxiz80ukMZgw7aiGyEOeoho4FPm+RYvYW27Dhux+G6Ro3u298k/dFUGEa6vyPv4/QAN3 3Pjmq8nlx8YnorAJY12ugdBaj/CxKH41eaawu2TEqCL7hiszys9eSjBluD2V2X0vO/8rjqzQHM6Uk MHIT32u462byYRHGvoWCWlVui/lnN6b0iRUBLQIzXb7fs2uOJ6hixd0t8Jks7fTehH1WL/ewpyp9Q +Ldj/IQ2r042apqFoOaw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1pFEBA-006yGp-Ko; Tue, 10 Jan 2023 12:56:36 +0000 Received: from phobos.denx.de ([85.214.62.61]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1pFEB7-006yFq-2L for linux-arm-kernel@lists.infradead.org; Tue, 10 Jan 2023 12:56:34 +0000 Received: from tr.lan (ip-86-49-120-218.bb.vodafone.cz [86.49.120.218]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: marex@denx.de) by phobos.denx.de (Postfix) with ESMTPSA id 83C178532C; Tue, 10 Jan 2023 13:56:30 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=denx.de; s=phobos-20191101; t=1673355391; bh=ylFu7wP5e77SDo+4dZFXcsiGvF9QhpKWcWLNNm3Xjqs=; h=From:To:Cc:Subject:Date:From; b=njjUA8KTwHKU6Dp+6kQfHVNgzdfzGCNgWKnCHlKVpD/57CKclQS8ndV0Zq7KtKyRM yNJaFDetNZjDcsvIikbEXXGWuqlkIpnRiAzkV+ReI8oWbM9vNyKj8OHjusL8duUHup LuNZy1IVunV+Nz/Sh5RvEGIVvaXvH4r+gQppBlo+v+sdmOAsYaY7jSHfERA9wQqj7l JMeYlsB4GDM8CkFH3vVcCP2TnsliRKKwgJwV7bnGVKHVjV4YDmLp0u0hNcLtKwAZVO OJGo9n0gNEH1ReVfOpM8wKH36my1flti3Ix2YWjsWTZkrklj8+4auoObJKXoLyQxsD 7aA3V8sj0I/EQ== From: Marek Vasut To: linux-serial@vger.kernel.org Cc: Marek Vasut , Sebastian Andrzej Siewior , Valentin Caron , Alexandre Torgue , Erwan Le Ray , Greg Kroah-Hartman , Jiri Slaby , Maxime Coquelin , Thomas Gleixner , linux-arm-kernel@lists.infradead.org, linux-stm32@st-md-mailman.stormreply.com Subject: [PATCH v4] serial: stm32: Merge hard IRQ and threaded IRQ handling into single IRQ handler Date: Tue, 10 Jan 2023 13:56:21 +0100 Message-Id: <20230110125621.89877-1-marex@denx.de> X-Mailer: git-send-email 2.39.0 MIME-Version: 1.0 X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230110_045633_431704_4DACEB1F X-CRM114-Status: GOOD ( 17.90 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Requesting an interrupt with IRQF_ONESHOT will run the primary handler in the hard-IRQ context even in the force-threaded mode. The force-threaded mode is used by PREEMPT_RT in order to avoid acquiring sleeping locks (spinlock_t) in hard-IRQ context. This combination makes it impossible and leads to "sleeping while atomic" warnings. Use one interrupt handler for both handlers (primary and secondary) and drop the IRQF_ONESHOT flag which is not needed. Fixes: e359b4411c283 ("serial: stm32: fix threaded interrupt handling") Reviewed-by: Sebastian Andrzej Siewior Tested-by: Valentin Caron # V3 Signed-off-by: Marek Vasut --- Cc: Alexandre Torgue Cc: Erwan Le Ray Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: Maxime Coquelin Cc: Sebastian Andrzej Siewior Cc: Thomas Gleixner Cc: Valentin Caron Cc: linux-arm-kernel@lists.infradead.org Cc: linux-stm32@st-md-mailman.stormreply.com To: linux-serial@vger.kernel.org --- V2: - Update patch subject, was: serial: stm32: Move hard IRQ handling to threaded interrupt context - Use request_irq() instead, rename the IRQ handler function V3: - Update the commit message per suggestion from Sebastian - Add RB from Sebastian - Add Fixes tag V4: - Remove uart_console() deadlock check from stm32_usart_of_dma_rx_probe() - Use plain spin_lock()/spin_unlock() instead of the _irqsave/_irqrestore variants in IRQ handler - Add TB from Valentin --- drivers/tty/serial/stm32-usart.c | 33 +++++--------------------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index a1490033aa164..50c9e011b723b 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -751,8 +751,8 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) struct tty_port *tport = &port->state->port; struct stm32_port *stm32_port = to_stm32_port(port); const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; - u32 sr; unsigned int size; + u32 sr; sr = readl_relaxed(port->membase + ofs->isr); @@ -797,23 +797,9 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) spin_unlock(&port->lock); } - if (stm32_usart_rx_dma_enabled(port)) - return IRQ_WAKE_THREAD; - else - return IRQ_HANDLED; -} - -static irqreturn_t stm32_usart_threaded_interrupt(int irq, void *ptr) -{ - struct uart_port *port = ptr; - struct tty_port *tport = &port->state->port; - struct stm32_port *stm32_port = to_stm32_port(port); - unsigned int size; - unsigned long flags; - /* Receiver timeout irq for DMA RX */ - if (!stm32_port->throttled) { - spin_lock_irqsave(&port->lock, flags); + if (stm32_usart_rx_dma_enabled(port) && !stm32_port->throttled) { + spin_lock(&port->lock); size = stm32_usart_receive_chars(port, false); uart_unlock_and_check_sysrq_irqrestore(port, flags); if (size) @@ -1015,10 +1001,8 @@ static int stm32_usart_startup(struct uart_port *port) u32 val; int ret; - ret = request_threaded_irq(port->irq, stm32_usart_interrupt, - stm32_usart_threaded_interrupt, - IRQF_ONESHOT | IRQF_NO_SUSPEND, - name, port); + ret = request_irq(port->irq, stm32_usart_interrupt, + IRQF_NO_SUSPEND, name, port); if (ret) return ret; @@ -1601,13 +1585,6 @@ static int stm32_usart_of_dma_rx_probe(struct stm32_port *stm32port, struct dma_slave_config config; int ret; - /* - * Using DMA and threaded handler for the console could lead to - * deadlocks. - */ - if (uart_console(port)) - return -ENODEV; - stm32port->rx_buf = dma_alloc_coherent(dev, RX_BUF_L, &stm32port->rx_dma_buf, GFP_KERNEL);