diff options
Diffstat (limited to 'drivers/serial/pxa.c')
-rw-r--r-- | drivers/serial/pxa.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index b8629d74f6a2..1102a39b44f5 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/serial_core.h> | 44 | #include <linux/serial_core.h> |
45 | #include <linux/clk.h> | 45 | #include <linux/clk.h> |
46 | #include <linux/io.h> | 46 | #include <linux/io.h> |
47 | #include <linux/slab.h> | ||
47 | 48 | ||
48 | struct uart_pxa_port { | 49 | struct uart_pxa_port { |
49 | struct uart_port port; | 50 | struct uart_port port; |
@@ -438,6 +439,7 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios, | |||
438 | unsigned char cval, fcr = 0; | 439 | unsigned char cval, fcr = 0; |
439 | unsigned long flags; | 440 | unsigned long flags; |
440 | unsigned int baud, quot; | 441 | unsigned int baud, quot; |
442 | unsigned int dll; | ||
441 | 443 | ||
442 | switch (termios->c_cflag & CSIZE) { | 444 | switch (termios->c_cflag & CSIZE) { |
443 | case CS5: | 445 | case CS5: |
@@ -534,10 +536,18 @@ serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios, | |||
534 | else | 536 | else |
535 | up->mcr &= ~UART_MCR_AFE; | 537 | up->mcr &= ~UART_MCR_AFE; |
536 | 538 | ||
537 | serial_out(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ | 539 | serial_out(up, UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */ |
538 | serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */ | 540 | serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */ |
541 | |||
542 | /* | ||
543 | * work around Errata #75 according to Intel(R) PXA27x Processor Family | ||
544 | * Specification Update (Nov 2005) | ||
545 | */ | ||
546 | dll = serial_in(up, UART_DLL); | ||
547 | WARN_ON(dll != (quot & 0xff)); | ||
548 | |||
539 | serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */ | 549 | serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */ |
540 | serial_out(up, UART_LCR, cval); /* reset DLAB */ | 550 | serial_out(up, UART_LCR, cval); /* reset DLAB */ |
541 | up->lcr = cval; /* Save LCR */ | 551 | up->lcr = cval; /* Save LCR */ |
542 | serial_pxa_set_mctrl(&up->port, up->port.mctrl); | 552 | serial_pxa_set_mctrl(&up->port, up->port.mctrl); |
543 | serial_out(up, UART_FCR, fcr); | 553 | serial_out(up, UART_FCR, fcr); |
@@ -747,7 +757,7 @@ static int serial_pxa_resume(struct device *dev) | |||
747 | return 0; | 757 | return 0; |
748 | } | 758 | } |
749 | 759 | ||
750 | static struct dev_pm_ops serial_pxa_pm_ops = { | 760 | static const struct dev_pm_ops serial_pxa_pm_ops = { |
751 | .suspend = serial_pxa_suspend, | 761 | .suspend = serial_pxa_suspend, |
752 | .resume = serial_pxa_resume, | 762 | .resume = serial_pxa_resume, |
753 | }; | 763 | }; |