From patchwork Mon Jun 24 13:31:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johan Hovold X-Patchwork-Id: 807200 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7A6D8143744; Mon, 24 Jun 2024 13:31:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719235901; cv=none; b=Lp8vt7p/+aVyAsHT1A9QdTrFAzEL4zDWhQsQMLkY8YKglpv1zkXWYt8XiiawLPf3ueZDVv4o4F9D4+O5hf/zNhMWht6RYYKt1aih/EV40AkHORaUTMQDIHtUFfuKILVXqfXbzDhwHGTzXQhTcvkAXNwFu/jJ9LZ6WUYawXG1y7I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719235901; c=relaxed/simple; bh=+hgftWIbBlBvZAXUD3E1PCs1OVr32meclo/Zqr2LEZU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tKnZr7oEhhDtfFq9QmApa+1f4yFqvOExFb3vUEH2amai1u7LYjAh2Rvqu02vpnsouaT42X7WsU3E4RGrWsHROswTsqlSy3QNp56KeiApnwZOP29rJT1ypHqZSlBCN9Jdk+UnsYG2+xNrTr5mZPZpP5dxv2JdD6t/WuxssMLk8uk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=P9PNzTHC; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="P9PNzTHC" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1717EC32782; Mon, 24 Jun 2024 13:31:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1719235901; bh=+hgftWIbBlBvZAXUD3E1PCs1OVr32meclo/Zqr2LEZU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=P9PNzTHCzP5GAFoFXLzXgc38xUR/SwrOKYlQ1ZRTT1wT0pxqnjlXbA5sLd8W773x3 9C2rV4pIBGYFe1Ep4VseYcHNNukG5txaQYvNS4Frr7MvX0o7uGWlNjy3XzxEJLGe5h VFQqZJZe4hJxYmobYtuTd1X1nT9UycaGsrc28O/sTPPWEQWzVHOfmk5oYFpdG521Ck NnGk7JBuRU2FVhwhIU1sAb1XkaJEt8pyagKpGH00a1pp9PefonEnGJskSw3jIX5E+s hAmzXij1JhnlP2AYYg/15i+7D9JlpqBR0S8fP1KI3g+45vR272WcQGyKPmW41uqTU+ S3L2Dp28Ja6Qw== Received: from johan by xi.lan with local (Exim 4.97.1) (envelope-from ) id 1sLjnO-000000001wU-40Pa; Mon, 24 Jun 2024 15:31:46 +0200 From: Johan Hovold To: Greg Kroah-Hartman , Jiri Slaby Cc: Konrad Dybcio , Douglas Anderson , Bjorn Andersson , linux-arm-msm@vger.kernel.org, linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, Johan Hovold Subject: [PATCH 1/3] serial: qcom-geni: fix hard lockup on buffer flush Date: Mon, 24 Jun 2024 15:31:33 +0200 Message-ID: <20240624133135.7445-2-johan+linaro@kernel.org> X-Mailer: git-send-email 2.44.1 In-Reply-To: <20240624133135.7445-1-johan+linaro@kernel.org> References: <20240624133135.7445-1-johan+linaro@kernel.org> Precedence: bulk X-Mailing-List: linux-serial@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The Qualcomm GENI serial driver does not handle buffer flushing and used to print garbage characters when the circular buffer was cleared. Since commit 1788cf6a91d9 ("tty: serial: switch from circ_buf to kfifo") this instead results in a lockup due to qcom_geni_serial_send_chunk_fifo() spinning indefinitely in the interrupt handler. This is easily triggered by interrupting a command such as dmesg in a serial console but can also happen when stopping a serial getty on reboot. Fix the immediate issue by printing NUL characters until the current TX command has been completed. Fixes: 1788cf6a91d9 ("tty: serial: switch from circ_buf to kfifo") Reported-by: Douglas Anderson Signed-off-by: Johan Hovold --- drivers/tty/serial/qcom_geni_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 2bd25afe0d92..1d5d6045879a 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -862,7 +862,7 @@ static void qcom_geni_serial_send_chunk_fifo(struct uart_port *uport, memset(buf, 0, sizeof(buf)); tx_bytes = min(remaining, BYTES_PER_FIFO_WORD); - tx_bytes = uart_fifo_out(uport, buf, tx_bytes); + uart_fifo_out(uport, buf, tx_bytes); iowrite32_rep(uport->membase + SE_GENI_TX_FIFOn, buf, 1); From patchwork Mon Jun 24 13:31:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johan Hovold X-Patchwork-Id: 808489 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 76723143739; Mon, 24 Jun 2024 13:31:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719235901; cv=none; b=XeZxudDtavjODIut7deOK42g9NSVQzCJKnYMQmvHJTbE7nleck33D7RBynwS55V1y39Kg7/NKQg4lCeUHKxJPBvTZxiI3DxXdrDFxJB6slF8qS5l9hQj0xZNy8LcuobJ05PBSwwgnwD9ujgsTyO6DlYHB3Ztg9/T7xKgCw1dZS0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719235901; c=relaxed/simple; bh=iaBx0pKDhCtH1GENa4aTAEo0/WKpJ6n5K95+bmY8LOo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NDPggz2HsLIIh3d6L+ZVHwDN8UiVP5oe2zZxbex0qgyVdpk1N0fO9m9EsPIZBfyOyteE7w5kewJc4zgiEdEo9/MQGaQq7lnI3HGZT0hf49ILD6yLBQ7ld64koR3qIrxmrF6fbcW94Tv2Jub6/T6rtFGuGgFw0A3cxzgLIl4nLpw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rCzQE2Yg; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rCzQE2Yg" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1CF43C4AF0C; Mon, 24 Jun 2024 13:31:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1719235901; bh=iaBx0pKDhCtH1GENa4aTAEo0/WKpJ6n5K95+bmY8LOo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rCzQE2Yg0lqmETb8TJ1/zkmnO7Rp2BwFfitRhF7MALOvcaR910Dri3TO9I8yECWnS DVx66kwp7A5M524psW4+za38z6XGl2NyA7x70wHXZr2zPYmAsNMOdYXB83gDv+QKWi VSBQXAgJ1nUwtEaTW9gAUr/7+gibvDtk1KDF8Z0mvINUKZY5xsuko9Qt0WJY9L4VXs JF6EZY0d0mPJzgoU72DoYUyEwKwjkXZL6NbPX/EOFfpGJTPqrVeEjJmJgz0pnx1XQ4 j15FUCc3IAK0VT7MSns6hINh4E7SbcReYGaMX8Yje0Ste21WOgihv8ywZJvaCDbAzS yrYsANG4GM1JQ== Received: from johan by xi.lan with local (Exim 4.97.1) (envelope-from ) id 1sLjnP-000000001wW-0HIo; Mon, 24 Jun 2024 15:31:47 +0200 From: Johan Hovold To: Greg Kroah-Hartman , Jiri Slaby Cc: Konrad Dybcio , Douglas Anderson , Bjorn Andersson , linux-arm-msm@vger.kernel.org, linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, Johan Hovold , stable@vger.kernel.org Subject: [PATCH 2/3] serial: qcom-geni: fix soft lockup on sw flow control and suspend Date: Mon, 24 Jun 2024 15:31:34 +0200 Message-ID: <20240624133135.7445-3-johan+linaro@kernel.org> X-Mailer: git-send-email 2.44.1 In-Reply-To: <20240624133135.7445-1-johan+linaro@kernel.org> References: <20240624133135.7445-1-johan+linaro@kernel.org> Precedence: bulk X-Mailing-List: linux-serial@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The stop_tx() callback is used to implement software flow control and must not discard data as the Qualcomm GENI driver is currently doing when there is an active TX command. Cancelling an active command can also leave data in the hardware FIFO, which prevents the watermark interrupt from being enabled when TX is later restarted. This results in a soft lockup and is easily triggered by stopping TX using software flow control in a serial console but this can also happen after suspend. Fix this by only stopping any active command, and effectively clearing the hardware fifo, when shutting down the port. Make sure to temporarily raise the watermark level so that the interrupt fires when TX is restarted. Fixes: c4f528795d1a ("tty: serial: msm_geni_serial: Add serial driver support for GENI based QUP") Cc: stable@vger.kernel.org # 4.17 Signed-off-by: Johan Hovold --- drivers/tty/serial/qcom_geni_serial.c | 28 +++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 1d5d6045879a..72addeb9f461 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -651,13 +651,8 @@ static void qcom_geni_serial_start_tx_fifo(struct uart_port *uport) { u32 irq_en; - if (qcom_geni_serial_main_active(uport) || - !qcom_geni_serial_tx_empty(uport)) - return; - irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN); irq_en |= M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN; - writel(DEF_TX_WM, uport->membase + SE_GENI_TX_WATERMARK_REG); writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN); } @@ -665,16 +660,28 @@ static void qcom_geni_serial_start_tx_fifo(struct uart_port *uport) static void qcom_geni_serial_stop_tx_fifo(struct uart_port *uport) { u32 irq_en; - struct qcom_geni_serial_port *port = to_dev_port(uport); irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN); irq_en &= ~(M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN); writel(0, uport->membase + SE_GENI_TX_WATERMARK_REG); writel(irq_en, uport->membase + SE_GENI_M_IRQ_EN); - /* Possible stop tx is called multiple times. */ +} + +static void qcom_geni_serial_clear_tx_fifo(struct uart_port *uport) +{ + struct qcom_geni_serial_port *port = to_dev_port(uport); + if (!qcom_geni_serial_main_active(uport)) return; + /* + * Increase watermark level so that TX can be restarted and wait for + * sequencer to start to prevent lockups. + */ + writel(port->tx_fifo_depth, uport->membase + SE_GENI_TX_WATERMARK_REG); + qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, + M_TX_FIFO_WATERMARK_EN, true); + geni_se_cancel_m_cmd(&port->se); if (!qcom_geni_serial_poll_bit(uport, SE_GENI_M_IRQ_STATUS, M_CMD_CANCEL_EN, true)) { @@ -684,6 +691,8 @@ static void qcom_geni_serial_stop_tx_fifo(struct uart_port *uport) writel(M_CMD_ABORT_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); } writel(M_CMD_CANCEL_EN, uport->membase + SE_GENI_M_IRQ_CLEAR); + + port->tx_remaining = 0; } static void qcom_geni_serial_handle_rx_fifo(struct uart_port *uport, bool drop) @@ -1069,11 +1078,10 @@ static void qcom_geni_serial_shutdown(struct uart_port *uport) { disable_irq(uport->irq); - if (uart_console(uport)) - return; - qcom_geni_serial_stop_tx(uport); qcom_geni_serial_stop_rx(uport); + + qcom_geni_serial_clear_tx_fifo(uport); } static int qcom_geni_serial_port_setup(struct uart_port *uport) From patchwork Mon Jun 24 13:31:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johan Hovold X-Patchwork-Id: 807201 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 766B7142E6F; Mon, 24 Jun 2024 13:31:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719235901; cv=none; b=kc0XJEj42g4nxhSijNVSyf9AqPacZX1Atg9qIrz6Ss4fzMYv6pl1DPuevaAvpraGSJcBC9fhBRlKXXrhma7CUq1WMvrM6Sb50fTNlsPuXxt7Y/rdKJztyffjOwbgaYShLZtt3Mx7jAvW+caBGJErttYdUN8NkgwcBunCJssDnro= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719235901; c=relaxed/simple; bh=JT50kJAxXSVLOVDE7qwzG8MW4VwAdei3qjuQkLBLq2I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cYb3GdySmHFVX1gDyZWDhSI9yNqs2Hc3fnXRmFE/0FXV4LTn/1eTOMUZECjX4y6QJI/k/X3UgVZxnfy0HFY7g/jtctGQ26ii+988/60MkJNbPOFtL/NXPIWmJ2uIjMkPb5yfPJBsYzIrZ2nT4AjgxDX0ZDE2xKG70fJ7Gp7iDLo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=O9W3mh5/; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="O9W3mh5/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 17AD9C4AF0A; Mon, 24 Jun 2024 13:31:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1719235901; bh=JT50kJAxXSVLOVDE7qwzG8MW4VwAdei3qjuQkLBLq2I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=O9W3mh5/6j2/ymSepi34zTH0gKwchWbRSK39XTO5jYJpvAqt17dzFu2a0AZDXz6rx cebHPWIUdsF/+GDvyoN9OE61NuAfeMVjPcG+4IxKZKMBreUUd9+3crkQpvxaLuFcvl 2ySztRlAr8kGuuXrWrIvmiXinBsG1gYcn+mdwyYTEP/Mo1TZn6Fdja7d5uLRflzWPK +HhYkEeltBypGo+/LZoNdtwmIVN8H3E/Bv3udMJcfkfOzGsf8xik5hxqbR9DL4NJXO sbLk//HCOjm4VU8dq7YB5hIPR3M/5OmLzg/FR+Tz1lbIRl5j06auNFdBobQDZIvPAT ymvQ+XQDw/xpw== Received: from johan by xi.lan with local (Exim 4.97.1) (envelope-from ) id 1sLjnP-000000001wY-0gzi; Mon, 24 Jun 2024 15:31:47 +0200 From: Johan Hovold To: Greg Kroah-Hartman , Jiri Slaby Cc: Konrad Dybcio , Douglas Anderson , Bjorn Andersson , linux-arm-msm@vger.kernel.org, linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, Johan Hovold , stable@vger.kernel.org Subject: [PATCH 3/3] serial: qcom-geni: fix garbage output after buffer flush Date: Mon, 24 Jun 2024 15:31:35 +0200 Message-ID: <20240624133135.7445-4-johan+linaro@kernel.org> X-Mailer: git-send-email 2.44.1 In-Reply-To: <20240624133135.7445-1-johan+linaro@kernel.org> References: <20240624133135.7445-1-johan+linaro@kernel.org> Precedence: bulk X-Mailing-List: linux-serial@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The Qualcomm GENI serial driver does not handle buffer flushing and outputs garbage (or NUL) characters for the remainder of any active TX command after the write buffer has been cleared. Implement the flush_buffer() callback and use it to cancel any active TX command when the write buffer has been emptied. Fixes: a1fee899e5be ("tty: serial: qcom_geni_serial: Fix softlock") Cc: stable@vger.kernel.org # 5.0 Reported-by: Douglas Anderson Signed-off-by: Johan Hovold --- drivers/tty/serial/qcom_geni_serial.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 72addeb9f461..5fbb72f1c0c7 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -1084,6 +1084,11 @@ static void qcom_geni_serial_shutdown(struct uart_port *uport) qcom_geni_serial_clear_tx_fifo(uport); } +static void qcom_geni_serial_flush_buffer(struct uart_port *uport) +{ + qcom_geni_serial_clear_tx_fifo(uport); +} + static int qcom_geni_serial_port_setup(struct uart_port *uport) { struct qcom_geni_serial_port *port = to_dev_port(uport); @@ -1540,6 +1545,7 @@ static const struct uart_ops qcom_geni_console_pops = { .request_port = qcom_geni_serial_request_port, .config_port = qcom_geni_serial_config_port, .shutdown = qcom_geni_serial_shutdown, + .flush_buffer = qcom_geni_serial_flush_buffer, .type = qcom_geni_serial_get_type, .set_mctrl = qcom_geni_serial_set_mctrl, .get_mctrl = qcom_geni_serial_get_mctrl,