Linux Serial subsystem development
 help / color / mirror / Atom feed
* [PATCH v3 0/9] serial: qcom-geni: fix receiver enable
@ 2024-10-09 14:51 Johan Hovold
  2024-10-09 14:51 ` [PATCH v3 1/9] serial: qcom-geni: fix polled console initialisation Johan Hovold
                   ` (8 more replies)
  0 siblings, 9 replies; 15+ messages in thread
From: Johan Hovold @ 2024-10-09 14:51 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Jiri Slaby, Bjorn Andersson, Konrad Dybcio, Douglas Anderson,
	Mukesh Kumar Savaliya, linux-arm-msm, linux-kernel, linux-serial,
	Johan Hovold

This series is a follow up to the console fixes in 6.12-rc1 that can
interact badly with some pre-existing bugs.

Specifically, the receiver could end up being disabled when
set_termios() races with the console code during boot. This can manifest
itself as a serial getty not accepting input.

Fixing the missing locking in set_termios() exposes another
long-standing bug in the DMA implementation (e.g. used for Bluetooth),
which is also fixed.

Johan


Changes in v3
 - fix polled console initialisation
 - revert broken hibernation support
 - rename suspend PM ops

Changes in v2
 - keep the call to stop rx in shutdown() which is called also on
   hangups
 - fix rx dma cancellation
 - fix rx cancel dma status bit
 - drop flip buffer WARN()
 - drop unused receive parameter

Johan Hovold (9):
  serial: qcom-geni: fix polled console initialisation
  serial: qcom-geni: revert broken hibernation support
  serial: qcom-geni: fix shutdown race
  serial: qcom-geni: fix dma rx cancellation
  serial: qcom-geni: fix receiver enable
  serial: qcom-geni: fix rx cancel dma status bit
  serial: qcom-geni: drop flip buffer WARN()
  serial: qcom-geni: drop unused receive parameter
  serial: qcom-geni: rename suspend functions

 drivers/tty/serial/qcom_geni_serial.c | 103 ++++++++++++--------------
 include/linux/soc/qcom/geni-se.h      |   2 +-
 2 files changed, 49 insertions(+), 56 deletions(-)

-- 
2.45.2


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v3 1/9] serial: qcom-geni: fix polled console initialisation
  2024-10-09 14:51 [PATCH v3 0/9] serial: qcom-geni: fix receiver enable Johan Hovold
@ 2024-10-09 14:51 ` Johan Hovold
  2024-10-10 22:36   ` Doug Anderson
  2024-10-09 14:51 ` [PATCH v3 2/9] serial: qcom-geni: revert broken hibernation support Johan Hovold
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 15+ messages in thread
From: Johan Hovold @ 2024-10-09 14:51 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Jiri Slaby, Bjorn Andersson, Konrad Dybcio, Douglas Anderson,
	Mukesh Kumar Savaliya, linux-arm-msm, linux-kernel, linux-serial,
	Johan Hovold, stable

The polled console (KGDB/KDB) implementation must not call port setup
unconditionally as the port may already be in use by the console or a
getty.

Only make sure that the receiver is enabled, but do not enable any
device interrupts.

Fixes: d8851a96ba25 ("tty: serial: qcom-geni-serial: Add a poll_init() function")
Cc: stable@vger.kernel.org	# 6.4
Cc: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
 drivers/tty/serial/qcom_geni_serial.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 6f0db310cf69..c237c9d107cd 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -147,6 +147,7 @@ static struct uart_driver qcom_geni_uart_driver;
 
 static void __qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport);
 static void qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport);
+static int qcom_geni_serial_port_setup(struct uart_port *uport);
 
 static inline struct qcom_geni_serial_port *to_dev_port(struct uart_port *uport)
 {
@@ -395,6 +396,23 @@ static void qcom_geni_serial_poll_put_char(struct uart_port *uport,
 	writel(c, uport->membase + SE_GENI_TX_FIFOn);
 	qcom_geni_serial_poll_tx_done(uport);
 }
+
+static int qcom_geni_serial_poll_init(struct uart_port *uport)
+{
+	struct qcom_geni_serial_port *port = to_dev_port(uport);
+	int ret;
+
+	if (!port->setup) {
+		ret = qcom_geni_serial_port_setup(uport);
+		if (ret)
+			return ret;
+	}
+
+	if (!qcom_geni_serial_secondary_active(uport))
+		geni_se_setup_s_cmd(&port->se, UART_START_READ, 0);
+
+	return 0;
+}
 #endif
 
 #ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE
@@ -1582,7 +1600,7 @@ static const struct uart_ops qcom_geni_console_pops = {
 #ifdef CONFIG_CONSOLE_POLL
 	.poll_get_char	= qcom_geni_serial_get_char,
 	.poll_put_char	= qcom_geni_serial_poll_put_char,
-	.poll_init = qcom_geni_serial_port_setup,
+	.poll_init = qcom_geni_serial_poll_init,
 #endif
 	.pm = qcom_geni_serial_pm,
 };
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 2/9] serial: qcom-geni: revert broken hibernation support
  2024-10-09 14:51 [PATCH v3 0/9] serial: qcom-geni: fix receiver enable Johan Hovold
  2024-10-09 14:51 ` [PATCH v3 1/9] serial: qcom-geni: fix polled console initialisation Johan Hovold
@ 2024-10-09 14:51 ` Johan Hovold
  2024-10-09 14:51 ` [PATCH v3 3/9] serial: qcom-geni: fix shutdown race Johan Hovold
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Johan Hovold @ 2024-10-09 14:51 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Jiri Slaby, Bjorn Andersson, Konrad Dybcio, Douglas Anderson,
	Mukesh Kumar Savaliya, linux-arm-msm, linux-kernel, linux-serial,
	Johan Hovold, stable, Aniket Randive

This reverts commit 35781d8356a2eecaa6074ceeb80ee22e252fcdae.

Hibernation is not supported on Qualcomm platforms with mainline
kernels yet a broken vendor implementation for the GENI serial driver
made it upstream.

This is effectively dead code that cannot be tested and should just be
removed, but if these paths were ever hit for an open non-console port
they would crash the machine as the driver would fail to enable clocks
during restore() (i.e. all ports would have to be closed by drivers and
user space before hibernating the system to avoid this as a comment in
the code hinted at).

The broken implementation also added a random call to enable the
receiver in the port setup code where it does not belong and which
enables the receiver prematurely for console ports.

Fixes: 35781d8356a2 ("tty: serial: qcom-geni-serial: Add support for Hibernation feature")
Cc: stable@vger.kernel.org	# 6.2
Cc: Aniket Randive <quic_arandive@quicinc.com>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
 drivers/tty/serial/qcom_geni_serial.c | 41 ++-------------------------
 1 file changed, 2 insertions(+), 39 deletions(-)

diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index c237c9d107cd..2e4a5361f137 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -1170,7 +1170,6 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport)
 			       false, true, true);
 	geni_se_init(&port->se, UART_RX_WM, port->rx_fifo_depth - 2);
 	geni_se_select_mode(&port->se, port->dev_data->mode);
-	qcom_geni_serial_start_rx(uport);
 	port->setup = true;
 
 	return 0;
@@ -1799,38 +1798,6 @@ static int qcom_geni_serial_sys_resume(struct device *dev)
 	return ret;
 }
 
-static int qcom_geni_serial_sys_hib_resume(struct device *dev)
-{
-	int ret = 0;
-	struct uart_port *uport;
-	struct qcom_geni_private_data *private_data;
-	struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
-
-	uport = &port->uport;
-	private_data = uport->private_data;
-
-	if (uart_console(uport)) {
-		geni_icc_set_tag(&port->se, QCOM_ICC_TAG_ALWAYS);
-		geni_icc_set_bw(&port->se);
-		ret = uart_resume_port(private_data->drv, uport);
-		/*
-		 * For hibernation usecase clients for
-		 * console UART won't call port setup during restore,
-		 * hence call port setup for console uart.
-		 */
-		qcom_geni_serial_port_setup(uport);
-	} else {
-		/*
-		 * Peripheral register settings are lost during hibernation.
-		 * Update setup flag such that port setup happens again
-		 * during next session. Clients of HS-UART will close and
-		 * open the port during hibernation.
-		 */
-		port->setup = false;
-	}
-	return ret;
-}
-
 static const struct qcom_geni_device_data qcom_geni_console_data = {
 	.console = true,
 	.mode = GENI_SE_FIFO,
@@ -1842,12 +1809,8 @@ static const struct qcom_geni_device_data qcom_geni_uart_data = {
 };
 
 static const struct dev_pm_ops qcom_geni_serial_pm_ops = {
-	.suspend = pm_sleep_ptr(qcom_geni_serial_sys_suspend),
-	.resume = pm_sleep_ptr(qcom_geni_serial_sys_resume),
-	.freeze = pm_sleep_ptr(qcom_geni_serial_sys_suspend),
-	.poweroff = pm_sleep_ptr(qcom_geni_serial_sys_suspend),
-	.restore = pm_sleep_ptr(qcom_geni_serial_sys_hib_resume),
-	.thaw = pm_sleep_ptr(qcom_geni_serial_sys_hib_resume),
+	SYSTEM_SLEEP_PM_OPS(qcom_geni_serial_sys_suspend,
+					qcom_geni_serial_sys_resume)
 };
 
 static const struct of_device_id qcom_geni_serial_match_table[] = {
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 3/9] serial: qcom-geni: fix shutdown race
  2024-10-09 14:51 [PATCH v3 0/9] serial: qcom-geni: fix receiver enable Johan Hovold
  2024-10-09 14:51 ` [PATCH v3 1/9] serial: qcom-geni: fix polled console initialisation Johan Hovold
  2024-10-09 14:51 ` [PATCH v3 2/9] serial: qcom-geni: revert broken hibernation support Johan Hovold
@ 2024-10-09 14:51 ` Johan Hovold
  2024-10-10 22:36   ` Doug Anderson
  2024-10-09 14:51 ` [PATCH v3 4/9] serial: qcom-geni: fix dma rx cancellation Johan Hovold
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 15+ messages in thread
From: Johan Hovold @ 2024-10-09 14:51 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Jiri Slaby, Bjorn Andersson, Konrad Dybcio, Douglas Anderson,
	Mukesh Kumar Savaliya, linux-arm-msm, linux-kernel, linux-serial,
	Johan Hovold, stable, Bartosz Golaszewski

A commit adding back the stopping of tx on port shutdown failed to add
back the locking which had also been removed by commit e83766334f96
("tty: serial: qcom_geni_serial: No need to stop tx/rx on UART
shutdown").

Holding the port lock is needed to serialise against the console code,
which may update the interrupt enable register and access the port
state.

Fixes: d8aca2f96813 ("tty: serial: qcom-geni-serial: stop operations in progress at shutdown")
Fixes: 947cc4ecc06c ("serial: qcom-geni: fix soft lockup on sw flow control and suspend")
Cc: stable@vger.kernel.org	# 6.3
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
 drivers/tty/serial/qcom_geni_serial.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 2e4a5361f137..87cd974b76bf 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -1114,10 +1114,12 @@ static void qcom_geni_serial_shutdown(struct uart_port *uport)
 {
 	disable_irq(uport->irq);
 
+	uart_port_lock_irq(uport);
 	qcom_geni_serial_stop_tx(uport);
 	qcom_geni_serial_stop_rx(uport);
 
 	qcom_geni_serial_cancel_tx_cmd(uport);
+	uart_port_unlock_irq(uport);
 }
 
 static void qcom_geni_serial_flush_buffer(struct uart_port *uport)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 4/9] serial: qcom-geni: fix dma rx cancellation
  2024-10-09 14:51 [PATCH v3 0/9] serial: qcom-geni: fix receiver enable Johan Hovold
                   ` (2 preceding siblings ...)
  2024-10-09 14:51 ` [PATCH v3 3/9] serial: qcom-geni: fix shutdown race Johan Hovold
@ 2024-10-09 14:51 ` Johan Hovold
  2024-10-09 14:51 ` [PATCH v3 5/9] serial: qcom-geni: fix receiver enable Johan Hovold
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Johan Hovold @ 2024-10-09 14:51 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Jiri Slaby, Bjorn Andersson, Konrad Dybcio, Douglas Anderson,
	Mukesh Kumar Savaliya, linux-arm-msm, linux-kernel, linux-serial,
	Johan Hovold, stable, Bartosz Golaszewski

Make sure to wait for the DMA transfer to complete when cancelling the
rx command on stop_rx(). This specifically prevents the DMA completion
interrupt from firing after rx has been restarted, something which can
lead to an IOMMU fault and hosed rx when the interrupt handler unmaps
the DMA buffer for the new command:

	qcom_geni_serial 988000.serial: serial engine reports 0 RX bytes in!
	arm-smmu 15000000.iommu: FSR    = 00000402 [Format=2 TF], SID=0x563
	arm-smmu 15000000.iommu: FSYNR0 = 00210013 [S1CBNDX=33 WNR PLVL=3]
	Bluetooth: hci0: command 0xfc00 tx timeout
	Bluetooth: hci0: Reading QCA version information failed (-110)

Also add the missing state machine reset which is needed in case
cancellation fails.

Fixes: 2aaa43c70778 ("tty: serial: qcom-geni-serial: add support for serial engine DMA")
Cc: stable@vger.kernel.org      # 6.3
Cc: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
 drivers/tty/serial/qcom_geni_serial.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 87cd974b76bf..aaf24bd037a7 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -805,17 +805,27 @@ static void qcom_geni_serial_start_rx_fifo(struct uart_port *uport)
 static void qcom_geni_serial_stop_rx_dma(struct uart_port *uport)
 {
 	struct qcom_geni_serial_port *port = to_dev_port(uport);
+	bool done;
 
 	if (!qcom_geni_serial_secondary_active(uport))
 		return;
 
 	geni_se_cancel_s_cmd(&port->se);
-	qcom_geni_serial_poll_bit(uport, SE_GENI_S_IRQ_STATUS,
-				  S_CMD_CANCEL_EN, true);
-
-	if (qcom_geni_serial_secondary_active(uport))
+	done = qcom_geni_serial_poll_bit(uport, SE_DMA_RX_IRQ_STAT,
+			RX_EOT, true);
+	if (done) {
+		writel(RX_EOT | RX_DMA_DONE,
+				uport->membase + SE_DMA_RX_IRQ_CLR);
+	} else {
 		qcom_geni_serial_abort_rx(uport);
 
+		writel(1, uport->membase + SE_DMA_RX_FSM_RST);
+		qcom_geni_serial_poll_bit(uport, SE_DMA_RX_IRQ_STAT,
+				RX_RESET_DONE, true);
+		writel(RX_RESET_DONE | RX_DMA_DONE,
+				uport->membase + SE_DMA_RX_IRQ_CLR);
+	}
+
 	if (port->rx_dma_addr) {
 		geni_se_rx_dma_unprep(&port->se, port->rx_dma_addr,
 				      DMA_RX_BUF_SIZE);
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 5/9] serial: qcom-geni: fix receiver enable
  2024-10-09 14:51 [PATCH v3 0/9] serial: qcom-geni: fix receiver enable Johan Hovold
                   ` (3 preceding siblings ...)
  2024-10-09 14:51 ` [PATCH v3 4/9] serial: qcom-geni: fix dma rx cancellation Johan Hovold
@ 2024-10-09 14:51 ` Johan Hovold
  2024-10-10 22:36   ` Doug Anderson
  2024-10-09 14:51 ` [PATCH v3 6/9] serial: qcom-geni: fix rx cancel dma status bit Johan Hovold
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 15+ messages in thread
From: Johan Hovold @ 2024-10-09 14:51 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Jiri Slaby, Bjorn Andersson, Konrad Dybcio, Douglas Anderson,
	Mukesh Kumar Savaliya, linux-arm-msm, linux-kernel, linux-serial,
	Johan Hovold, stable, Bartosz Golaszewski

The receiver is supposed to be enabled in the startup() callback and not
in set_termios() which is called also during console setup.

This specifically avoids accepting input before the port has been opened
(and interrupts enabled), something which can also break the GENI
firmware (cancel fails and after abort, the "stale" counter handling
appears to be broken so that later input is not processed until twelve
chars have been received).

There also does not appear to be any need to keep the receiver disabled
while updating the port settings.

Since commit 6f3c3cafb115 ("serial: qcom-geni: disable interrupts during
console writes") the calls to manipulate the secondary interrupts, which
were done without holding the port lock, can also lead to the receiver
being left disabled when set_termios() races with the console code (e.g.
when init opens the tty during boot). This can manifest itself as a
serial getty not accepting input.

The calls to stop and start rx in set_termios() can similarly race with
DMA completion and, for example, cause the DMA buffer to be unmapped
twice or the mapping to be leaked.

Fix this by only enabling the receiver during startup and while holding
the port lock to avoid racing with the console code.

Fixes: 6f3c3cafb115 ("serial: qcom-geni: disable interrupts during console writes")
Fixes: 2aaa43c70778 ("tty: serial: qcom-geni-serial: add support for serial engine DMA")
Fixes: c4f528795d1a ("tty: serial: msm_geni_serial: Add serial driver support for GENI based QUP")
Cc: stable@vger.kernel.org      # 6.3
Cc: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
 drivers/tty/serial/qcom_geni_serial.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index aaf24bd037a7..6c4349ea5720 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -1197,6 +1197,11 @@ static int qcom_geni_serial_startup(struct uart_port *uport)
 		if (ret)
 			return ret;
 	}
+
+	uart_port_lock_irq(uport);
+	qcom_geni_serial_start_rx(uport);
+	uart_port_unlock_irq(uport);
+
 	enable_irq(uport->irq);
 
 	return 0;
@@ -1282,7 +1287,6 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
 	unsigned int avg_bw_core;
 	unsigned long timeout;
 
-	qcom_geni_serial_stop_rx(uport);
 	/* baud rate */
 	baud = uart_get_baud_rate(uport, termios, old, 300, 4000000);
 
@@ -1298,7 +1302,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
 		dev_err(port->se.dev,
 			"Couldn't find suitable clock rate for %u\n",
 			baud * sampling_rate);
-		goto out_restart_rx;
+		return;
 	}
 
 	dev_dbg(port->se.dev, "desired_rate = %u, clk_rate = %lu, clk_div = %u\n",
@@ -1389,8 +1393,6 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
 	writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN);
 	writel(ser_clk_cfg, uport->membase + GENI_SER_M_CLK_CFG);
 	writel(ser_clk_cfg, uport->membase + GENI_SER_S_CLK_CFG);
-out_restart_rx:
-	qcom_geni_serial_start_rx(uport);
 }
 
 #ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 6/9] serial: qcom-geni: fix rx cancel dma status bit
  2024-10-09 14:51 [PATCH v3 0/9] serial: qcom-geni: fix receiver enable Johan Hovold
                   ` (4 preceding siblings ...)
  2024-10-09 14:51 ` [PATCH v3 5/9] serial: qcom-geni: fix receiver enable Johan Hovold
@ 2024-10-09 14:51 ` Johan Hovold
  2024-10-09 14:51 ` [PATCH v3 7/9] serial: qcom-geni: drop flip buffer WARN() Johan Hovold
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Johan Hovold @ 2024-10-09 14:51 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Jiri Slaby, Bjorn Andersson, Konrad Dybcio, Douglas Anderson,
	Mukesh Kumar Savaliya, linux-arm-msm, linux-kernel, linux-serial,
	Johan Hovold

Cancelling an rx command is signalled using bit 14 of the rx DMA status
register and not bit 11.

This bit is currently unused, but this error becomes apparent, for
example, when tracing the status register when closing the port.

Fixes: eddac5af0654 ("soc: qcom: Add GENI based QUP Wrapper driver")
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
 include/linux/soc/qcom/geni-se.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/soc/qcom/geni-se.h b/include/linux/soc/qcom/geni-se.h
index c3bca9c0bf2c..2996a3c28ef3 100644
--- a/include/linux/soc/qcom/geni-se.h
+++ b/include/linux/soc/qcom/geni-se.h
@@ -258,8 +258,8 @@ struct geni_se {
 #define RX_DMA_PARITY_ERR		BIT(5)
 #define RX_DMA_BREAK			GENMASK(8, 7)
 #define RX_GENI_GP_IRQ			GENMASK(10, 5)
-#define RX_GENI_CANCEL_IRQ		BIT(11)
 #define RX_GENI_GP_IRQ_EXT		GENMASK(13, 12)
+#define RX_GENI_CANCEL_IRQ		BIT(14)
 
 /* SE_HW_PARAM_0 fields */
 #define TX_FIFO_WIDTH_MSK		GENMASK(29, 24)
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 7/9] serial: qcom-geni: drop flip buffer WARN()
  2024-10-09 14:51 [PATCH v3 0/9] serial: qcom-geni: fix receiver enable Johan Hovold
                   ` (5 preceding siblings ...)
  2024-10-09 14:51 ` [PATCH v3 6/9] serial: qcom-geni: fix rx cancel dma status bit Johan Hovold
@ 2024-10-09 14:51 ` Johan Hovold
  2024-10-09 14:51 ` [PATCH v3 8/9] serial: qcom-geni: drop unused receive parameter Johan Hovold
  2024-10-09 14:51 ` [PATCH v3 9/9] serial: qcom-geni: rename suspend functions Johan Hovold
  8 siblings, 0 replies; 15+ messages in thread
From: Johan Hovold @ 2024-10-09 14:51 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Jiri Slaby, Bjorn Andersson, Konrad Dybcio, Douglas Anderson,
	Mukesh Kumar Savaliya, linux-arm-msm, linux-kernel, linux-serial,
	Johan Hovold

Drop the unnecessary WARN() in case the TTY buffers are ever full in
favour of a rate limited dev_err() which doesn't kill the machine when
panic_on_warn is set.

Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
 drivers/tty/serial/qcom_geni_serial.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 6c4349ea5720..22e468065666 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -588,9 +588,8 @@ static void handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop)
 
 	ret = tty_insert_flip_string(tport, port->rx_buf, bytes);
 	if (ret != bytes) {
-		dev_err(uport->dev, "%s:Unable to push data ret %d_bytes %d\n",
-				__func__, ret, bytes);
-		WARN_ON_ONCE(1);
+		dev_err_ratelimited(uport->dev, "failed to push data (%d < %u)\n",
+				ret, bytes);
 	}
 	uport->icount.rx += ret;
 	tty_flip_buffer_push(tport);
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 8/9] serial: qcom-geni: drop unused receive parameter
  2024-10-09 14:51 [PATCH v3 0/9] serial: qcom-geni: fix receiver enable Johan Hovold
                   ` (6 preceding siblings ...)
  2024-10-09 14:51 ` [PATCH v3 7/9] serial: qcom-geni: drop flip buffer WARN() Johan Hovold
@ 2024-10-09 14:51 ` Johan Hovold
  2024-10-09 14:51 ` [PATCH v3 9/9] serial: qcom-geni: rename suspend functions Johan Hovold
  8 siblings, 0 replies; 15+ messages in thread
From: Johan Hovold @ 2024-10-09 14:51 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Jiri Slaby, Bjorn Andersson, Konrad Dybcio, Douglas Anderson,
	Mukesh Kumar Savaliya, linux-arm-msm, linux-kernel, linux-serial,
	Johan Hovold

Serial drivers should not be dropping characters themselves, but at
least drop the unused 'drop' parameter from the receive handler for now.

Reviewed-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
 drivers/tty/serial/qcom_geni_serial.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 22e468065666..9dd304cdcd86 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -580,7 +580,7 @@ static void handle_rx_console(struct uart_port *uport, u32 bytes, bool drop)
 }
 #endif /* CONFIG_SERIAL_QCOM_GENI_CONSOLE */
 
-static void handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop)
+static void handle_rx_uart(struct uart_port *uport, u32 bytes)
 {
 	struct qcom_geni_serial_port *port = to_dev_port(uport);
 	struct tty_port *tport = &uport->state->port;
@@ -873,7 +873,7 @@ static void qcom_geni_serial_handle_rx_dma(struct uart_port *uport, bool drop)
 	}
 
 	if (!drop)
-		handle_rx_uart(uport, rx_in, drop);
+		handle_rx_uart(uport, rx_in);
 
 	ret = geni_se_rx_dma_prep(&port->se, port->rx_buf,
 				  DMA_RX_BUF_SIZE,
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 9/9] serial: qcom-geni: rename suspend functions
  2024-10-09 14:51 [PATCH v3 0/9] serial: qcom-geni: fix receiver enable Johan Hovold
                   ` (7 preceding siblings ...)
  2024-10-09 14:51 ` [PATCH v3 8/9] serial: qcom-geni: drop unused receive parameter Johan Hovold
@ 2024-10-09 14:51 ` Johan Hovold
  2024-10-10 22:36   ` Doug Anderson
  8 siblings, 1 reply; 15+ messages in thread
From: Johan Hovold @ 2024-10-09 14:51 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Jiri Slaby, Bjorn Andersson, Konrad Dybcio, Douglas Anderson,
	Mukesh Kumar Savaliya, linux-arm-msm, linux-kernel, linux-serial,
	Johan Hovold

Drop the unnecessary "_sys" infix from the suspend PM ops.

Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
---
 drivers/tty/serial/qcom_geni_serial.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 9dd304cdcd86..5dfe4e599ad6 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -1779,7 +1779,7 @@ static void qcom_geni_serial_remove(struct platform_device *pdev)
 	uart_remove_one_port(drv, &port->uport);
 }
 
-static int qcom_geni_serial_sys_suspend(struct device *dev)
+static int qcom_geni_serial_suspend(struct device *dev)
 {
 	struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
 	struct uart_port *uport = &port->uport;
@@ -1796,7 +1796,7 @@ static int qcom_geni_serial_sys_suspend(struct device *dev)
 	return uart_suspend_port(private_data->drv, uport);
 }
 
-static int qcom_geni_serial_sys_resume(struct device *dev)
+static int qcom_geni_serial_resume(struct device *dev)
 {
 	int ret;
 	struct qcom_geni_serial_port *port = dev_get_drvdata(dev);
@@ -1822,8 +1822,7 @@ static const struct qcom_geni_device_data qcom_geni_uart_data = {
 };
 
 static const struct dev_pm_ops qcom_geni_serial_pm_ops = {
-	SYSTEM_SLEEP_PM_OPS(qcom_geni_serial_sys_suspend,
-					qcom_geni_serial_sys_resume)
+	SYSTEM_SLEEP_PM_OPS(qcom_geni_serial_suspend, qcom_geni_serial_resume)
 };
 
 static const struct of_device_id qcom_geni_serial_match_table[] = {
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 1/9] serial: qcom-geni: fix polled console initialisation
  2024-10-09 14:51 ` [PATCH v3 1/9] serial: qcom-geni: fix polled console initialisation Johan Hovold
@ 2024-10-10 22:36   ` Doug Anderson
  0 siblings, 0 replies; 15+ messages in thread
From: Doug Anderson @ 2024-10-10 22:36 UTC (permalink / raw)
  To: Johan Hovold
  Cc: Greg Kroah-Hartman, Jiri Slaby, Bjorn Andersson, Konrad Dybcio,
	Mukesh Kumar Savaliya, linux-arm-msm, linux-kernel, linux-serial,
	stable

Hi,

On Wed, Oct 9, 2024 at 7:51 AM Johan Hovold <johan+linaro@kernel.org> wrote:
>
> The polled console (KGDB/KDB) implementation must not call port setup
> unconditionally as the port may already be in use by the console or a
> getty.
>
> Only make sure that the receiver is enabled, but do not enable any
> device interrupts.
>
> Fixes: d8851a96ba25 ("tty: serial: qcom-geni-serial: Add a poll_init() function")
> Cc: stable@vger.kernel.org      # 6.4
> Cc: Douglas Anderson <dianders@chromium.org>
> Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
> ---
>  drivers/tty/serial/qcom_geni_serial.c | 20 +++++++++++++++++++-
>  1 file changed, 19 insertions(+), 1 deletion(-)

Reviewed-by: Douglas Anderson <dianders@chromium.org>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 3/9] serial: qcom-geni: fix shutdown race
  2024-10-09 14:51 ` [PATCH v3 3/9] serial: qcom-geni: fix shutdown race Johan Hovold
@ 2024-10-10 22:36   ` Doug Anderson
  2024-10-11  6:54     ` Johan Hovold
  0 siblings, 1 reply; 15+ messages in thread
From: Doug Anderson @ 2024-10-10 22:36 UTC (permalink / raw)
  To: Johan Hovold
  Cc: Greg Kroah-Hartman, Jiri Slaby, Bjorn Andersson, Konrad Dybcio,
	Mukesh Kumar Savaliya, linux-arm-msm, linux-kernel, linux-serial,
	stable, Bartosz Golaszewski

Hi,

On Wed, Oct 9, 2024 at 7:51 AM Johan Hovold <johan+linaro@kernel.org> wrote:
>
> A commit adding back the stopping of tx on port shutdown failed to add
> back the locking which had also been removed by commit e83766334f96
> ("tty: serial: qcom_geni_serial: No need to stop tx/rx on UART
> shutdown").
>
> Holding the port lock is needed to serialise against the console code,
> which may update the interrupt enable register and access the port
> state.
>
> Fixes: d8aca2f96813 ("tty: serial: qcom-geni-serial: stop operations in progress at shutdown")
> Fixes: 947cc4ecc06c ("serial: qcom-geni: fix soft lockup on sw flow control and suspend")
> Cc: stable@vger.kernel.org      # 6.3
> Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
> ---
>  drivers/tty/serial/qcom_geni_serial.c | 2 ++
>  1 file changed, 2 insertions(+)

Though this doesn't fix the preexisting bug I talked about [1] that
we'll need to touch the same code to fix:

Reviewed-by: Douglas Anderson <dianders@chromium.org>

[1] https://lore.kernel.org/r/CAD=FV=UZtZ1-0SkN2sOMp6YdU02em_RnK85Heg5z0jkH4U30eQ@mail.gmail.com

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 5/9] serial: qcom-geni: fix receiver enable
  2024-10-09 14:51 ` [PATCH v3 5/9] serial: qcom-geni: fix receiver enable Johan Hovold
@ 2024-10-10 22:36   ` Doug Anderson
  0 siblings, 0 replies; 15+ messages in thread
From: Doug Anderson @ 2024-10-10 22:36 UTC (permalink / raw)
  To: Johan Hovold
  Cc: Greg Kroah-Hartman, Jiri Slaby, Bjorn Andersson, Konrad Dybcio,
	Mukesh Kumar Savaliya, linux-arm-msm, linux-kernel, linux-serial,
	stable, Bartosz Golaszewski

Hi,

On Wed, Oct 9, 2024 at 7:51 AM Johan Hovold <johan+linaro@kernel.org> wrote:
>
> The receiver is supposed to be enabled in the startup() callback and not
> in set_termios() which is called also during console setup.
>
> This specifically avoids accepting input before the port has been opened
> (and interrupts enabled), something which can also break the GENI
> firmware (cancel fails and after abort, the "stale" counter handling
> appears to be broken so that later input is not processed until twelve
> chars have been received).
>
> There also does not appear to be any need to keep the receiver disabled
> while updating the port settings.
>
> Since commit 6f3c3cafb115 ("serial: qcom-geni: disable interrupts during
> console writes") the calls to manipulate the secondary interrupts, which
> were done without holding the port lock, can also lead to the receiver
> being left disabled when set_termios() races with the console code (e.g.
> when init opens the tty during boot). This can manifest itself as a
> serial getty not accepting input.
>
> The calls to stop and start rx in set_termios() can similarly race with
> DMA completion and, for example, cause the DMA buffer to be unmapped
> twice or the mapping to be leaked.
>
> Fix this by only enabling the receiver during startup and while holding
> the port lock to avoid racing with the console code.
>
> Fixes: 6f3c3cafb115 ("serial: qcom-geni: disable interrupts during console writes")
> Fixes: 2aaa43c70778 ("tty: serial: qcom-geni-serial: add support for serial engine DMA")
> Fixes: c4f528795d1a ("tty: serial: msm_geni_serial: Add serial driver support for GENI based QUP")
> Cc: stable@vger.kernel.org      # 6.3
> Cc: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
> ---
>  drivers/tty/serial/qcom_geni_serial.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)

Reviewed-by: Douglas Anderson <dianders@chromium.org>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 9/9] serial: qcom-geni: rename suspend functions
  2024-10-09 14:51 ` [PATCH v3 9/9] serial: qcom-geni: rename suspend functions Johan Hovold
@ 2024-10-10 22:36   ` Doug Anderson
  0 siblings, 0 replies; 15+ messages in thread
From: Doug Anderson @ 2024-10-10 22:36 UTC (permalink / raw)
  To: Johan Hovold
  Cc: Greg Kroah-Hartman, Jiri Slaby, Bjorn Andersson, Konrad Dybcio,
	Mukesh Kumar Savaliya, linux-arm-msm, linux-kernel, linux-serial

Hi,

On Wed, Oct 9, 2024 at 7:51 AM Johan Hovold <johan+linaro@kernel.org> wrote:
>
> Drop the unnecessary "_sys" infix from the suspend PM ops.
>
> Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
> ---
>  drivers/tty/serial/qcom_geni_serial.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)

Reviewed-by: Douglas Anderson <dianders@chromium.org>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 3/9] serial: qcom-geni: fix shutdown race
  2024-10-10 22:36   ` Doug Anderson
@ 2024-10-11  6:54     ` Johan Hovold
  0 siblings, 0 replies; 15+ messages in thread
From: Johan Hovold @ 2024-10-11  6:54 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Johan Hovold, Greg Kroah-Hartman, Jiri Slaby, Bjorn Andersson,
	Konrad Dybcio, Mukesh Kumar Savaliya, linux-arm-msm, linux-kernel,
	linux-serial, stable, Bartosz Golaszewski

On Thu, Oct 10, 2024 at 03:36:30PM -0700, Doug Anderson wrote:
> On Wed, Oct 9, 2024 at 7:51 AM Johan Hovold <johan+linaro@kernel.org> wrote:
> >
> > A commit adding back the stopping of tx on port shutdown failed to add
> > back the locking which had also been removed by commit e83766334f96
> > ("tty: serial: qcom_geni_serial: No need to stop tx/rx on UART
> > shutdown").
> >
> > Holding the port lock is needed to serialise against the console code,
> > which may update the interrupt enable register and access the port
> > state.
> >
> > Fixes: d8aca2f96813 ("tty: serial: qcom-geni-serial: stop operations in progress at shutdown")
> > Fixes: 947cc4ecc06c ("serial: qcom-geni: fix soft lockup on sw flow control and suspend")
> > Cc: stable@vger.kernel.org      # 6.3
> > Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
> > Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
> > ---
> >  drivers/tty/serial/qcom_geni_serial.c | 2 ++
> >  1 file changed, 2 insertions(+)
> 
> Though this doesn't fix the preexisting bug I talked about [1] that
> we'll need to touch the same code to fix:
> 
> Reviewed-by: Douglas Anderson <dianders@chromium.org>

Yeah, let's address that separately. Thanks for reviewing!

Johan

> [1] https://lore.kernel.org/r/CAD=FV=UZtZ1-0SkN2sOMp6YdU02em_RnK85Heg5z0jkH4U30eQ@mail.gmail.com

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2024-10-11  6:54 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-09 14:51 [PATCH v3 0/9] serial: qcom-geni: fix receiver enable Johan Hovold
2024-10-09 14:51 ` [PATCH v3 1/9] serial: qcom-geni: fix polled console initialisation Johan Hovold
2024-10-10 22:36   ` Doug Anderson
2024-10-09 14:51 ` [PATCH v3 2/9] serial: qcom-geni: revert broken hibernation support Johan Hovold
2024-10-09 14:51 ` [PATCH v3 3/9] serial: qcom-geni: fix shutdown race Johan Hovold
2024-10-10 22:36   ` Doug Anderson
2024-10-11  6:54     ` Johan Hovold
2024-10-09 14:51 ` [PATCH v3 4/9] serial: qcom-geni: fix dma rx cancellation Johan Hovold
2024-10-09 14:51 ` [PATCH v3 5/9] serial: qcom-geni: fix receiver enable Johan Hovold
2024-10-10 22:36   ` Doug Anderson
2024-10-09 14:51 ` [PATCH v3 6/9] serial: qcom-geni: fix rx cancel dma status bit Johan Hovold
2024-10-09 14:51 ` [PATCH v3 7/9] serial: qcom-geni: drop flip buffer WARN() Johan Hovold
2024-10-09 14:51 ` [PATCH v3 8/9] serial: qcom-geni: drop unused receive parameter Johan Hovold
2024-10-09 14:51 ` [PATCH v3 9/9] serial: qcom-geni: rename suspend functions Johan Hovold
2024-10-10 22:36   ` Doug Anderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox