Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2af7cd68 authored by Russell King's avatar Russell King Committed by Russell King
Browse files

[Serial] Don't miss modem status changes



Reading the MSR register on 8250-compatible UARTs results in any
modem status interrupts being cleared.  To avoid missing any
status changes, arrange for get_mctrl() to read the current
status via check_modem_status(), which will process any pending
state changes for us.

Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 88026842
Loading
Loading
Loading
Loading
+16 −17
Original line number Original line Diff line number Diff line
@@ -1255,15 +1255,11 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up)
		__stop_tx(up);
		__stop_tx(up);
}
}


static _INLINE_ void check_modem_status(struct uart_8250_port *up)
static unsigned int check_modem_status(struct uart_8250_port *up)
{
{
	int status;
	unsigned int status = serial_in(up, UART_MSR);

	status = serial_in(up, UART_MSR);

	if ((status & UART_MSR_ANY_DELTA) == 0)
		return;


	if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI) {
		if (status & UART_MSR_TERI)
		if (status & UART_MSR_TERI)
			up->port.icount.rng++;
			up->port.icount.rng++;
		if (status & UART_MSR_DDSR)
		if (status & UART_MSR_DDSR)
@@ -1276,6 +1272,9 @@ static _INLINE_ void check_modem_status(struct uart_8250_port *up)
		wake_up_interruptible(&up->port.info->delta_msr_wait);
		wake_up_interruptible(&up->port.info->delta_msr_wait);
	}
	}


	return status;
}

/*
/*
 * This handles the interrupt from one port.
 * This handles the interrupt from one port.
 */
 */
@@ -1454,10 +1453,10 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
static unsigned int serial8250_get_mctrl(struct uart_port *port)
static unsigned int serial8250_get_mctrl(struct uart_port *port)
{
{
	struct uart_8250_port *up = (struct uart_8250_port *)port;
	struct uart_8250_port *up = (struct uart_8250_port *)port;
	unsigned char status;
	unsigned int status;
	unsigned int ret;
	unsigned int ret;


	status = serial_in(up, UART_MSR);
	status = check_modem_status(up);


	ret = 0;
	ret = 0;
	if (status & UART_MSR_DCD)
	if (status & UART_MSR_DCD)