summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/0005-serial-msm-Use-uart_prepare_sysrq_char.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches-rt/0005-serial-msm-Use-uart_prepare_sysrq_char.patch')
-rw-r--r--debian/patches-rt/0005-serial-msm-Use-uart_prepare_sysrq_char.patch116
1 files changed, 116 insertions, 0 deletions
diff --git a/debian/patches-rt/0005-serial-msm-Use-uart_prepare_sysrq_char.patch b/debian/patches-rt/0005-serial-msm-Use-uart_prepare_sysrq_char.patch
new file mode 100644
index 000000000..75c822db4
--- /dev/null
+++ b/debian/patches-rt/0005-serial-msm-Use-uart_prepare_sysrq_char.patch
@@ -0,0 +1,116 @@
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Fri, 1 Mar 2024 22:45:18 +0100
+Subject: [PATCH 05/18] serial: msm: Use uart_prepare_sysrq_char().
+Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz
+
+The port lock is a spinlock_t which is becomes a sleeping lock on PREEMPT_RT.
+The driver splits the locking function into two parts: local_irq_save() and
+uart_port_lock() and this breaks PREEMPT_RT.
+
+Delay handling sysrq until port lock is dropped.
+Remove the special case in the console write routine an always use the
+complete locking function.
+
+Cc: Bjorn Andersson <andersson@kernel.org>
+Cc: Konrad Dybcio <konrad.dybcio@linaro.org>
+Cc: linux-arm-msm@vger.kernel.org
+Link: https://lore.kernel.org/r/20240301215246.891055-6-bigeasy@linutronix.de
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/tty/serial/msm_serial.c | 33 ++++++++++-----------------------
+ 1 file changed, 10 insertions(+), 23 deletions(-)
+
+--- a/drivers/tty/serial/msm_serial.c
++++ b/drivers/tty/serial/msm_serial.c
+@@ -588,16 +588,14 @@ static void msm_complete_rx_dma(void *ar
+ if (!(port->read_status_mask & MSM_UART_SR_RX_BREAK))
+ flag = TTY_NORMAL;
+
+- uart_port_unlock_irqrestore(port, flags);
+- sysrq = uart_handle_sysrq_char(port, dma->virt[i]);
+- uart_port_lock_irqsave(port, &flags);
++ sysrq = uart_prepare_sysrq_char(port, dma->virt[i]);
+ if (!sysrq)
+ tty_insert_flip_char(tport, dma->virt[i], flag);
+ }
+
+ msm_start_rx_dma(msm_port);
+ done:
+- uart_port_unlock_irqrestore(port, flags);
++ uart_unlock_and_check_sysrq_irqrestore(port, flags);
+
+ if (count)
+ tty_flip_buffer_push(tport);
+@@ -763,9 +761,7 @@ static void msm_handle_rx_dm(struct uart
+ if (!(port->read_status_mask & MSM_UART_SR_RX_BREAK))
+ flag = TTY_NORMAL;
+
+- uart_port_unlock(port);
+- sysrq = uart_handle_sysrq_char(port, buf[i]);
+- uart_port_lock(port);
++ sysrq = uart_prepare_sysrq_char(port, buf[i]);
+ if (!sysrq)
+ tty_insert_flip_char(tport, buf[i], flag);
+ }
+@@ -825,9 +821,7 @@ static void msm_handle_rx(struct uart_po
+ else if (sr & MSM_UART_SR_PAR_FRAME_ERR)
+ flag = TTY_FRAME;
+
+- uart_port_unlock(port);
+- sysrq = uart_handle_sysrq_char(port, c);
+- uart_port_lock(port);
++ sysrq = uart_prepare_sysrq_char(port, c);
+ if (!sysrq)
+ tty_insert_flip_char(tport, c, flag);
+ }
+@@ -948,11 +942,10 @@ static irqreturn_t msm_uart_irq(int irq,
+ struct uart_port *port = dev_id;
+ struct msm_port *msm_port = to_msm_port(port);
+ struct msm_dma *dma = &msm_port->rx_dma;
+- unsigned long flags;
+ unsigned int misr;
+ u32 val;
+
+- uart_port_lock_irqsave(port, &flags);
++ uart_port_lock(port);
+ misr = msm_read(port, MSM_UART_MISR);
+ msm_write(port, 0, MSM_UART_IMR); /* disable interrupt */
+
+@@ -984,7 +977,7 @@ static irqreturn_t msm_uart_irq(int irq,
+ msm_handle_delta_cts(port);
+
+ msm_write(port, msm_port->imr, MSM_UART_IMR); /* restore interrupt */
+- uart_port_unlock_irqrestore(port, flags);
++ uart_unlock_and_check_sysrq(port);
+
+ return IRQ_HANDLED;
+ }
+@@ -1621,14 +1614,10 @@ static void __msm_console_write(struct u
+ num_newlines++;
+ count += num_newlines;
+
+- local_irq_save(flags);
+-
+- if (port->sysrq)
+- locked = 0;
+- else if (oops_in_progress)
+- locked = uart_port_trylock(port);
++ if (oops_in_progress)
++ locked = uart_port_trylock_irqsave(port, &flags);
+ else
+- uart_port_lock(port);
++ uart_port_lock_irqsave(port, &flags);
+
+ if (is_uartdm)
+ msm_reset_dm_count(port, count);
+@@ -1667,9 +1656,7 @@ static void __msm_console_write(struct u
+ }
+
+ if (locked)
+- uart_port_unlock(port);
+-
+- local_irq_restore(flags);
++ uart_port_unlock_irqrestore(port, flags);
+ }
+
+ static void msm_console_write(struct console *co, const char *s,