[SERIAL] 8250: set divisor register correctly for AMD Alchemy SoC uart

Alchemy SoC uart have got a non-standard divisor register that needs some
special handling.

This patch adds divisor read/write functions with test and special
handling for Alchemy internal uart.

Signed-off-by: Jon Anders Haugum <jonah@omegav.ntnu.no>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by Jon Anders Haugum and committed by Russell King b32b19b8 85835f44

+42 -13
+42 -13
drivers/serial/8250.c
··· 362 #define serial_inp(up, offset) serial_in(up, offset) 363 #define serial_outp(up, offset, value) serial_out(up, offset, value) 364 365 366 /* 367 * For the 16C950 ··· 528 */ 529 static int size_fifo(struct uart_8250_port *up) 530 { 531 - unsigned char old_fcr, old_mcr, old_dll, old_dlm, old_lcr; 532 int count; 533 534 old_lcr = serial_inp(up, UART_LCR); ··· 540 UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); 541 serial_outp(up, UART_MCR, UART_MCR_LOOP); 542 serial_outp(up, UART_LCR, UART_LCR_DLAB); 543 - old_dll = serial_inp(up, UART_DLL); 544 - old_dlm = serial_inp(up, UART_DLM); 545 - serial_outp(up, UART_DLL, 0x01); 546 - serial_outp(up, UART_DLM, 0x00); 547 serial_outp(up, UART_LCR, 0x03); 548 for (count = 0; count < 256; count++) 549 serial_outp(up, UART_TX, count); ··· 552 serial_outp(up, UART_FCR, old_fcr); 553 serial_outp(up, UART_MCR, old_mcr); 554 serial_outp(up, UART_LCR, UART_LCR_DLAB); 555 - serial_outp(up, UART_DLL, old_dll); 556 - serial_outp(up, UART_DLM, old_dlm); 557 serial_outp(up, UART_LCR, old_lcr); 558 559 return count; ··· 782 783 serial_outp(up, UART_LCR, 0xE0); 784 785 - quot = serial_inp(up, UART_DLM) << 8; 786 - quot += serial_inp(up, UART_DLL); 787 quot <<= 3; 788 789 status1 = serial_in(up, 0x04); /* EXCR1 */ ··· 790 status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ 791 serial_outp(up, 0x04, status1); 792 793 - serial_outp(up, UART_DLL, quot & 0xff); 794 - serial_outp(up, UART_DLM, quot >> 8); 795 796 serial_outp(up, UART_LCR, 0); 797 ··· 1892 serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ 1893 } 1894 1895 - serial_outp(up, UART_DLL, quot & 0xff); /* LS of divisor */ 1896 - serial_outp(up, UART_DLM, quot >> 8); /* MS of divisor */ 1897 1898 /* 1899 * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
··· 362 #define serial_inp(up, offset) serial_in(up, offset) 363 #define serial_outp(up, offset, value) serial_out(up, offset, value) 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 399 400 /* 401 * For the 16C950 ··· 494 */ 495 static int size_fifo(struct uart_8250_port *up) 496 { 497 + unsigned char old_fcr, old_mcr, old_lcr; 498 + unsigned short old_dl; 499 int count; 500 501 old_lcr = serial_inp(up, UART_LCR); ··· 505 UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); 506 serial_outp(up, UART_MCR, UART_MCR_LOOP); 507 serial_outp(up, UART_LCR, UART_LCR_DLAB); 508 + old_dl = serial_dl_read(up); 509 + serial_dl_write(up, 0x0001); 510 serial_outp(up, UART_LCR, 0x03); 511 for (count = 0; count < 256; count++) 512 serial_outp(up, UART_TX, count); ··· 519 serial_outp(up, UART_FCR, old_fcr); 520 serial_outp(up, UART_MCR, old_mcr); 521 serial_outp(up, UART_LCR, UART_LCR_DLAB); 522 + serial_dl_write(up, old_dl); 523 serial_outp(up, UART_LCR, old_lcr); 524 525 return count; ··· 750 751 serial_outp(up, UART_LCR, 0xE0); 752 753 + quot = serial_dl_read(up); 754 quot <<= 3; 755 756 status1 = serial_in(up, 0x04); /* EXCR1 */ ··· 759 status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ 760 serial_outp(up, 0x04, status1); 761 762 + serial_dl_write(up, quot); 763 764 serial_outp(up, UART_LCR, 0); 765 ··· 1862 serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ 1863 } 1864 1865 + serial_dl_write(up, quot); 1866 1867 /* 1868 * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR