[PATCH 5.9 259/391] tty: serial: 21285: fix lockup on open

From: Greg Kroah-Hartman
Date: Tue Nov 03 2020 - 15:47:50 EST


From: Russell King <rmk+kernel@xxxxxxxxxxxxxxx>

commit 82776f6c75a90e1d2103e689b84a689de8f1aa02 upstream.

Commit 293f89959483 ("tty: serial: 21285: stop using the unused[]
variable from struct uart_port") introduced a bug which stops the
transmit interrupt being disabled when there are no characters to
transmit - disabling the transmit interrupt at the interrupt controller
is the only way to stop an interrupt storm. If this interrupt is not
disabled when there are no transmit characters, we end up with an
interrupt storm which prevents the machine making forward progress.

Fixes: 293f89959483 ("tty: serial: 21285: stop using the unused[] variable from struct uart_port")
Signed-off-by: Russell King <rmk+kernel@xxxxxxxxxxxxxxx>
Cc: stable <stable@xxxxxxxxxxxxxxx>
Link: https://lore.kernel.org/r/E1kU4GS-0006lE-OO@xxxxxxxxxxxxxxxxxxxxxx
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
drivers/tty/serial/21285.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

--- a/drivers/tty/serial/21285.c
+++ b/drivers/tty/serial/21285.c
@@ -50,25 +50,25 @@ static const char serial21285_name[] = "

static bool is_enabled(struct uart_port *port, int bit)
{
- unsigned long private_data = (unsigned long)port->private_data;
+ unsigned long *private_data = (unsigned long *)&port->private_data;

- if (test_bit(bit, &private_data))
+ if (test_bit(bit, private_data))
return true;
return false;
}

static void enable(struct uart_port *port, int bit)
{
- unsigned long private_data = (unsigned long)port->private_data;
+ unsigned long *private_data = (unsigned long *)&port->private_data;

- set_bit(bit, &private_data);
+ set_bit(bit, private_data);
}

static void disable(struct uart_port *port, int bit)
{
- unsigned long private_data = (unsigned long)port->private_data;
+ unsigned long *private_data = (unsigned long *)&port->private_data;

- clear_bit(bit, &private_data);
+ clear_bit(bit, private_data);
}

#define is_tx_enabled(port) is_enabled(port, tx_enabled_bit)