Skip to content

Commit

Permalink
NS16550A: Restore HS settings in EXCR2 on resume
Browse files Browse the repository at this point in the history
After a suspend/resume cycle, the UART may have been reset into
low-speed mode -- either because it's actually been reset, or because
the firmware pokes at the old-style divisor registers. If we detected it
as a NS16550A SuperIO chip in the first place and set baud_base to
921600, then we should do so again in the resume path.

This patch adds that code to serial8250_resume_port(), and also makes
serial8250_resume() actually call serial8250_resume_port() for each port
instead of just calling uart_resume_port() directly. And thus fixes
serial port operation after suspend/resume.

It also fixes a bogus comment where we write the EXCR2 register with a
comment saying /* EXCR1 */

Signed-off-by: David Woodhouse <[email protected]>
Acked-by: Alan Cox <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
dwmw2 authored and Linus Torvalds committed May 17, 2007
1 parent c97a9e1 commit b5b82df
Showing 1 changed file with 18 additions and 3 deletions.
21 changes: 18 additions & 3 deletions drivers/serial/8250.c
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,7 @@ static void autoconfig_16550a(struct uart_8250_port *up)
quot = serial_dl_read(up);
quot <<= 3;

status1 = serial_in(up, 0x04); /* EXCR1 */
status1 = serial_in(up, 0x04); /* EXCR2 */
status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */
serial_outp(up, 0x04, status1);
Expand Down Expand Up @@ -2617,7 +2617,22 @@ void serial8250_suspend_port(int line)
*/
void serial8250_resume_port(int line)
{
uart_resume_port(&serial8250_reg, &serial8250_ports[line].port);
struct uart_8250_port *up = &serial8250_ports[line];

if (up->capabilities & UART_NATSEMI) {
unsigned char tmp;

/* Ensure it's still in high speed mode */
serial_outp(up, UART_LCR, 0xE0);

tmp = serial_in(up, 0x04); /* EXCR2 */
tmp &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
tmp |= 0x10; /* 1.625 divisor for baud_base --> 921600 */
serial_outp(up, 0x04, tmp);

serial_outp(up, UART_LCR, 0);
}
uart_resume_port(&serial8250_reg, &up->port);
}

/*
Expand Down Expand Up @@ -2694,7 +2709,7 @@ static int serial8250_resume(struct platform_device *dev)
struct uart_8250_port *up = &serial8250_ports[i];

if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
uart_resume_port(&serial8250_reg, &up->port);
serial8250_resume_port(i);
}

return 0;
Expand Down

0 comments on commit b5b82df

Please sign in to comment.