Skip to content

Commit c131b21

Browse files
Pavel Krasavingregkh
authored andcommitted
tty: serial: meson: fix hard LOCKUP on crtscts mode
[ Upstream commit 2a1d728 ] There might be hard lockup if we set crtscts mode on port without RTS/CTS configured: # stty -F /dev/ttyAML6 crtscts; echo 1 > /dev/ttyAML6; echo 2 > /dev/ttyAML6 [ 95.890386] rcu: INFO: rcu_preempt detected stalls on CPUs/tasks: [ 95.890857] rcu: 3-...0: (201 ticks this GP) idle=e33c/1/0x4000000000000000 softirq=5844/5846 fqs=4984 [ 95.900212] rcu: (detected by 2, t=21016 jiffies, g=7753, q=296 ncpus=4) [ 95.906972] Task dump for CPU 3: [ 95.910178] task:bash state:R running task stack:0 pid:205 ppid:1 flags:0x00000202 [ 95.920059] Call trace: [ 95.922485] __switch_to+0xe4/0x168 [ 95.925951] 0xffffff8003477508 [ 95.974379] watchdog: Watchdog detected hard LOCKUP on cpu 3 [ 95.974424] Modules linked in: 88x2cs(O) rtc_meson_vrtc Possible solution would be to not allow to setup crtscts on such port. Tested on S905X3 based board. Fixes: ff7693d ("ARM: meson: serial: add MesonX SoC on-chip uart driver") Cc: [email protected] Signed-off-by: Pavel Krasavin <[email protected]> Reviewed-by: Neil Armstrong <[email protected]> Reviewed-by: Dmitry Rokosov <[email protected]> v6: stable tag added v5: https://lore.kernel.org/lkml/[email protected]/ added missed Reviewed-by tags, Fixes tag added according to Dmitry and Neil notes v4: https://lore.kernel.org/lkml/[email protected]/ More correct patch subject according to Jiri's note v3: https://lore.kernel.org/lkml/[email protected]/ "From:" line added to the mail v2: https://lore.kernel.org/lkml/[email protected]/ braces for single statement removed according to Dmitry's note v1: https://lore.kernel.org/lkml/[email protected]/ Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 62fdc81 commit c131b21

File tree

1 file changed

+11
-3
lines changed

1 file changed

+11
-3
lines changed

drivers/tty/serial/meson_uart.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -371,10 +371,14 @@ static void meson_uart_set_termios(struct uart_port *port,
371371
else
372372
val |= AML_UART_STOP_BIT_1SB;
373373

374-
if (cflags & CRTSCTS)
375-
val &= ~AML_UART_TWO_WIRE_EN;
376-
else
374+
if (cflags & CRTSCTS) {
375+
if (port->flags & UPF_HARD_FLOW)
376+
val &= ~AML_UART_TWO_WIRE_EN;
377+
else
378+
termios->c_cflag &= ~CRTSCTS;
379+
} else {
377380
val |= AML_UART_TWO_WIRE_EN;
381+
}
378382

379383
writel(val, port->membase + AML_UART_CONTROL);
380384

@@ -670,6 +674,7 @@ static int meson_uart_probe(struct platform_device *pdev)
670674
u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
671675
int ret = 0;
672676
int irq;
677+
bool has_rtscts;
673678

674679
if (pdev->dev.of_node)
675680
pdev->id = of_alias_get_id(pdev->dev.of_node, "serial");
@@ -697,6 +702,7 @@ static int meson_uart_probe(struct platform_device *pdev)
697702
return irq;
698703

699704
of_property_read_u32(pdev->dev.of_node, "fifo-size", &fifosize);
705+
has_rtscts = of_property_read_bool(pdev->dev.of_node, "uart-has-rtscts");
700706

701707
if (meson_ports[pdev->id]) {
702708
dev_err(&pdev->dev, "port %d already allocated\n", pdev->id);
@@ -721,6 +727,8 @@ static int meson_uart_probe(struct platform_device *pdev)
721727
port->mapsize = resource_size(res_mem);
722728
port->irq = irq;
723729
port->flags = UPF_BOOT_AUTOCONF | UPF_LOW_LATENCY;
730+
if (has_rtscts)
731+
port->flags |= UPF_HARD_FLOW;
724732
port->dev = &pdev->dev;
725733
port->line = pdev->id;
726734
port->type = PORT_MESON;

0 commit comments

Comments
 (0)