diff options
| -rw-r--r-- | drivers/serial/8250.c | 55 |
1 files changed, 42 insertions, 13 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index d641ac4e976e..9cc74712795d 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
| @@ -362,6 +362,40 @@ serial_out(struct uart_8250_port *up, int offset, int value) | |||
| 362 | #define serial_inp(up, offset) serial_in(up, offset) | 362 | #define serial_inp(up, offset) serial_in(up, offset) |
| 363 | #define serial_outp(up, offset, value) serial_out(up, offset, value) | 363 | #define serial_outp(up, offset, value) serial_out(up, offset, value) |
| 364 | 364 | ||
| 365 | /* Uart divisor latch read */ | ||
| 366 | static inline int _serial_dl_read(struct uart_8250_port *up) | ||
| 367 | { | ||
| 368 | return serial_inp(up, UART_DLL) | serial_inp(up, UART_DLM) << 8; | ||
| 369 | } | ||
| 370 | |||
| 371 | /* Uart divisor latch write */ | ||
| 372 | static inline void _serial_dl_write(struct uart_8250_port *up, int value) | ||
| 373 | { | ||
| 374 | serial_outp(up, UART_DLL, value & 0xff); | ||
| 375 | serial_outp(up, UART_DLM, value >> 8 & 0xff); | ||
| 376 | } | ||
| 377 | |||
| 378 | #ifdef CONFIG_SERIAL_8250_AU1X00 | ||
| 379 | /* Au1x00 haven't got a standard divisor latch */ | ||
| 380 | static int serial_dl_read(struct uart_8250_port *up) | ||
| 381 | { | ||
| 382 | if (up->port.iotype == UPIO_AU) | ||
| 383 | return __raw_readl(up->port.membase + 0x28); | ||
| 384 | else | ||
| 385 | return _serial_dl_read(up); | ||
| 386 | } | ||
| 387 | |||
| 388 | static void serial_dl_write(struct uart_8250_port *up, int value) | ||
| 389 | { | ||
| 390 | if (up->port.iotype == UPIO_AU) | ||
| 391 | __raw_writel(value, up->port.membase + 0x28); | ||
| 392 | else | ||
| 393 | _serial_dl_write(up, value); | ||
| 394 | } | ||
| 395 | #else | ||
| 396 | #define serial_dl_read(up) _serial_dl_read(up) | ||
| 397 | #define serial_dl_write(up, value) _serial_dl_write(up, value) | ||
| 398 | #endif | ||
| 365 | 399 | ||
| 366 | /* | 400 | /* |
| 367 | * For the 16C950 | 401 | * For the 16C950 |
| @@ -494,7 +528,8 @@ static void disable_rsa(struct uart_8250_port *up) | |||
| 494 | */ | 528 | */ |
| 495 | static int size_fifo(struct uart_8250_port *up) | 529 | static int size_fifo(struct uart_8250_port *up) |
| 496 | { | 530 | { |
| 497 | unsigned char old_fcr, old_mcr, old_dll, old_dlm, old_lcr; | 531 | unsigned char old_fcr, old_mcr, old_lcr; |
| 532 | unsigned short old_dl; | ||
| 498 | int count; | 533 | int count; |
| 499 | 534 | ||
| 500 | old_lcr = serial_inp(up, UART_LCR); | 535 | old_lcr = serial_inp(up, UART_LCR); |
| @@ -505,10 +540,8 @@ static int size_fifo(struct uart_8250_port *up) | |||
| 505 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); | 540 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); |
| 506 | serial_outp(up, UART_MCR, UART_MCR_LOOP); | 541 | serial_outp(up, UART_MCR, UART_MCR_LOOP); |
| 507 | serial_outp(up, UART_LCR, UART_LCR_DLAB); | 542 | serial_outp(up, UART_LCR, UART_LCR_DLAB); |
| 508 | old_dll = serial_inp(up, UART_DLL); | 543 | old_dl = serial_dl_read(up); |
| 509 | old_dlm = serial_inp(up, UART_DLM); | 544 | serial_dl_write(up, 0x0001); |
| 510 | serial_outp(up, UART_DLL, 0x01); | ||
| 511 | serial_outp(up, UART_DLM, 0x00); | ||
| 512 | serial_outp(up, UART_LCR, 0x03); | 545 | serial_outp(up, UART_LCR, 0x03); |
| 513 | for (count = 0; count < 256; count++) | 546 | for (count = 0; count < 256; count++) |
| 514 | serial_outp(up, UART_TX, count); | 547 | serial_outp(up, UART_TX, count); |
| @@ -519,8 +552,7 @@ static int size_fifo(struct uart_8250_port *up) | |||
| 519 | serial_outp(up, UART_FCR, old_fcr); | 552 | serial_outp(up, UART_FCR, old_fcr); |
| 520 | serial_outp(up, UART_MCR, old_mcr); | 553 | serial_outp(up, UART_MCR, old_mcr); |
| 521 | serial_outp(up, UART_LCR, UART_LCR_DLAB); | 554 | serial_outp(up, UART_LCR, UART_LCR_DLAB); |
| 522 | serial_outp(up, UART_DLL, old_dll); | 555 | serial_dl_write(up, old_dl); |
| 523 | serial_outp(up, UART_DLM, old_dlm); | ||
| 524 | serial_outp(up, UART_LCR, old_lcr); | 556 | serial_outp(up, UART_LCR, old_lcr); |
| 525 | 557 | ||
| 526 | return count; | 558 | return count; |
| @@ -750,8 +782,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
| 750 | 782 | ||
| 751 | serial_outp(up, UART_LCR, 0xE0); | 783 | serial_outp(up, UART_LCR, 0xE0); |
| 752 | 784 | ||
| 753 | quot = serial_inp(up, UART_DLM) << 8; | 785 | quot = serial_dl_read(up); |
| 754 | quot += serial_inp(up, UART_DLL); | ||
| 755 | quot <<= 3; | 786 | quot <<= 3; |
| 756 | 787 | ||
| 757 | status1 = serial_in(up, 0x04); /* EXCR1 */ | 788 | status1 = serial_in(up, 0x04); /* EXCR1 */ |
| @@ -759,8 +790,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) | |||
| 759 | status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ | 790 | status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ |
| 760 | serial_outp(up, 0x04, status1); | 791 | serial_outp(up, 0x04, status1); |
| 761 | 792 | ||
| 762 | serial_outp(up, UART_DLL, quot & 0xff); | 793 | serial_dl_write(up, quot); |
| 763 | serial_outp(up, UART_DLM, quot >> 8); | ||
| 764 | 794 | ||
| 765 | serial_outp(up, UART_LCR, 0); | 795 | serial_outp(up, UART_LCR, 0); |
| 766 | 796 | ||
| @@ -1862,8 +1892,7 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios, | |||
| 1862 | serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ | 1892 | serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ |
| 1863 | } | 1893 | } |
| 1864 | 1894 | ||
| 1865 | serial_outp(up, UART_DLL, quot & 0xff); /* LS of divisor */ | 1895 | serial_dl_write(up, quot); |
| 1866 | serial_outp(up, UART_DLM, quot >> 8); /* MS of divisor */ | ||
| 1867 | 1896 | ||
| 1868 | /* | 1897 | /* |
| 1869 | * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR | 1898 | * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR |
