diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9187240a02db5..f073b5102d4ed 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -133,6 +133,7 @@ config ARM
 	select HAVE_PERF_EVENTS
 	select HAVE_PERF_REGS
 	select HAVE_PERF_USER_STACK_DUMP
+	select HAVE_POSIX_CPU_TIMERS_TASK_WORK
 	select MMU_GATHER_RCU_TABLE_FREE if SMP && ARM_LPAE
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_RSEQ
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index afbd2ebe5c39d..6aa205a929205 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -375,6 +375,7 @@ void arm_notify_die(const char *str, struct pt_regs *regs,
 		unsigned long err, unsigned long trap)
 {
 	if (user_mode(regs)) {
+		local_irq_enable();
 		current->thread.error_code = err;
 		current->thread.trap_no = trap;
 
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index bf358604f3dff..7598ccd9319e4 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -609,6 +609,9 @@ void serial8250_suspend_port(int line)
 	struct uart_8250_port *up = &serial8250_ports[line];
 	struct uart_port *port = &up->port;
 
+	/* No irq_work may be queued when suspending. */
+	up->avoid_modem_status_work = true;
+
 	if (!console_suspend_enabled && uart_console(port) &&
 	    port->type != PORT_8250) {
 		unsigned char canary = 0xa5;
@@ -645,6 +648,12 @@ void serial8250_resume_port(int line)
 		port->uartclk = 921600*16;
 	}
 	uart_resume_port(&serial8250_reg, port);
+
+	/* irq_work allowed again. Handle MSR now if pending. */
+	up->avoid_modem_status_work = false;
+	guard(uart_port_lock_irqsave)(port);
+	if (uart_console(port) && up->msr_saved_flags)
+		serial8250_modem_status(up);
 }
 EXPORT_SYMBOL(serial8250_resume_port);
 
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 4263e423a0a38..aa4b0780638fb 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -3260,8 +3260,8 @@ void serial8250_fifo_wait_for_lsr_thre(struct uart_8250_port *up,
 		 * the ownership might timeout. The new owner will wait
 		 * for UART_LSR_THRE before reusing the fifo.
 		 */
-               if (wctxt && !nbcon_can_proceed(wctxt))
-                       return;
+		if (wctxt && !nbcon_can_proceed(wctxt))
+			return;
 
 		if (wait_for_lsr(up, UART_LSR_THRE))
 			return;
@@ -3501,10 +3501,21 @@ void serial8250_console_write(struct uart_8250_port *up,
 		 * For atomic, it must be deferred to irq_work because this
 		 * may be a context that does not permit waking up tasks.
 		 */
-		if (is_atomic)
-			irq_work_queue(&up->modem_status_work);
-		else
+		if (is_atomic) {
+			/*
+			 * For atomic, MSR handling must be deferred to
+			 * irq_work because this may be a context that does
+			 * not permit waking up tasks.
+			 *
+			 * But no irq_work may be queued when suspending.
+			 * In that case, the MSR handling will occur during
+			 * resume in serial8250_resume_port().
+			 */
+			if (!up->avoid_modem_status_work)
+				irq_work_queue(&up->modem_status_work);
+		} else {
 			serial8250_modem_status(up);
+		}
 	}
 
 	nbcon_exit_unsafe(wctxt);
@@ -3535,9 +3546,8 @@ static void modem_status_handler(struct irq_work *iwp)
 	struct uart_8250_port *up = container_of(iwp, struct uart_8250_port, modem_status_work);
 	struct uart_port *port = &up->port;
 
-	uart_port_lock(port);
+	guard(uart_port_lock)(port);
 	serial8250_modem_status(up);
-	uart_port_unlock(port);
 }
 
 int serial8250_console_setup(struct uart_port *port, char *options, bool probe)
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index 03b17423fc5af..12c2f6aadd420 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -158,6 +158,9 @@ struct uart_8250_port {
 	 */
 	bool			console_line_ended;
 
+	/* Do not queue irq_work for MSR handling when suspending. */
+	bool			avoid_modem_status_work;
+
 #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
 	unsigned char		msr_saved_flags;
 	struct irq_work		modem_status_work;
diff --git a/localversion-rt b/localversion-rt
index c3054d08a1129..1445cd65885cd 100644
--- a/localversion-rt
+++ b/localversion-rt
@@ -1 +1 @@
--rt2
+-rt3
