aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2009-11-06 15:40:46 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 18:18:04 -0500
commitc934878cc09fdd4a06ffa554c5149b11d972456f (patch)
treeab839436bb2bf7bae0d3359f121d9de6161f38f1 /drivers/serial
parent4c0ebb8057bc335d345c8e205a3e6fd1320be21e (diff)
Serial: pxa: work around Errata #75
Intel(R) PXA27x Processor Family Specification Update (Nov 2005) says: E75. UART: Baud rate may not be programmed correctly on back-to-back writes. Problem: When programming the Divisor Latch registers, Low and High (DLL and DLH), with back-to-back writes, the second register write may not take effect. The result is an incorrect baud rate. Workaround: After programming the first Divisor Latch register, read and verify it before programming the second Divisor Latch register. This was hit when changing the baud rate from 115200 to 9600 while receiving characters at 9600 Bd. And fixed indention of some comments nearby. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Acked-by: Wolfram Sang <w.sang@pengutronix.de> Acked-by: Marc Kleine-Budde <mkl@pengutronix.de> Cc: Eric Miao <eric.y.miao@gmail.com> Cc: Alan Cox <alan@linux.intel.com> Cc: Mike Rapoport <mike@compulab.co.il> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/pxa.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index b8629d74f6a2..4a821046baae 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -438,6 +438,7 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
438 unsigned char cval, fcr = 0; 438 unsigned char cval, fcr = 0;
439 unsigned long flags; 439 unsigned long flags;
440 unsigned int baud, quot; 440 unsigned int baud, quot;
441 unsigned int dll;
441 442
442 switch (termios->c_cflag & CSIZE) { 443 switch (termios->c_cflag & CSIZE) {
443 case CS5: 444 case CS5:
@@ -534,10 +535,18 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios,
534 else 535 else
535 up->mcr &= ~UART_MCR_AFE; 536 up->mcr &= ~UART_MCR_AFE;
536 537
537 serial_out(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ 538 serial_out(up, UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */
538 serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */ 539 serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */
540
541 /*
542 * work around Errata #75 according to Intel(R) PXA27x Processor Family
543 * Specification Update (Nov 2005)
544 */
545 dll = serial_in(up, UART_DLL);
546 WARN_ON(dll != (quot & 0xff));
547
539 serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */ 548 serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */
540 serial_out(up, UART_LCR, cval); /* reset DLAB */ 549 serial_out(up, UART_LCR, cval); /* reset DLAB */
541 up->lcr = cval; /* Save LCR */ 550 up->lcr = cval; /* Save LCR */
542 serial_pxa_set_mctrl(&up->port, up->port.mctrl); 551 serial_pxa_set_mctrl(&up->port, up->port.mctrl);
543 serial_out(up, UART_FCR, fcr); 552 serial_out(up, UART_FCR, fcr);