diff options
Diffstat (limited to 'drivers/tty/serial/8250.c')
-rw-r--r-- | drivers/tty/serial/8250.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index c10a6a909c76..b3b881bc4712 100644 --- a/drivers/tty/serial/8250.c +++ b/drivers/tty/serial/8250.c | |||
@@ -954,6 +954,23 @@ static int broken_efr(struct uart_8250_port *up) | |||
954 | return 0; | 954 | return 0; |
955 | } | 955 | } |
956 | 956 | ||
957 | static inline int ns16550a_goto_highspeed(struct uart_8250_port *up) | ||
958 | { | ||
959 | unsigned char status; | ||
960 | |||
961 | status = serial_in(up, 0x04); /* EXCR2 */ | ||
962 | #define PRESL(x) ((x) & 0x30) | ||
963 | if (PRESL(status) == 0x10) { | ||
964 | /* already in high speed mode */ | ||
965 | return 0; | ||
966 | } else { | ||
967 | status &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ | ||
968 | status |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ | ||
969 | serial_outp(up, 0x04, status); | ||
970 | } | ||
971 | return 1; | ||
972 | } | ||
973 | |||
957 | /* | 974 | /* |
958 | * We know that the chip has FIFOs. Does it have an EFR? The | 975 | * We know that the chip has FIFOs. Does it have an EFR? The |
959 | * EFR is located in the same register position as the IIR and | 976 | * EFR is located in the same register position as the IIR and |
@@ -1025,12 +1042,8 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
1025 | quot = serial_dl_read(up); | 1042 | quot = serial_dl_read(up); |
1026 | quot <<= 3; | 1043 | quot <<= 3; |
1027 | 1044 | ||
1028 | status1 = serial_in(up, 0x04); /* EXCR2 */ | 1045 | if (ns16550a_goto_highspeed(up)) |
1029 | status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ | 1046 | serial_dl_write(up, quot); |
1030 | status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ | ||
1031 | serial_outp(up, 0x04, status1); | ||
1032 | |||
1033 | serial_dl_write(up, quot); | ||
1034 | 1047 | ||
1035 | serial_outp(up, UART_LCR, 0); | 1048 | serial_outp(up, UART_LCR, 0); |
1036 | 1049 | ||
@@ -3025,15 +3038,10 @@ void serial8250_resume_port(int line) | |||
3025 | struct uart_8250_port *up = &serial8250_ports[line]; | 3038 | struct uart_8250_port *up = &serial8250_ports[line]; |
3026 | 3039 | ||
3027 | if (up->capabilities & UART_NATSEMI) { | 3040 | if (up->capabilities & UART_NATSEMI) { |
3028 | unsigned char tmp; | ||
3029 | |||
3030 | /* Ensure it's still in high speed mode */ | 3041 | /* Ensure it's still in high speed mode */ |
3031 | serial_outp(up, UART_LCR, 0xE0); | 3042 | serial_outp(up, UART_LCR, 0xE0); |
3032 | 3043 | ||
3033 | tmp = serial_in(up, 0x04); /* EXCR2 */ | 3044 | ns16550a_goto_highspeed(up); |
3034 | tmp &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ | ||
3035 | tmp |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ | ||
3036 | serial_outp(up, 0x04, tmp); | ||
3037 | 3045 | ||
3038 | serial_outp(up, UART_LCR, 0); | 3046 | serial_outp(up, UART_LCR, 0); |
3039 | up->port.uartclk = 921600*16; | 3047 | up->port.uartclk = 921600*16; |