diff options
| -rw-r--r-- | drivers/serial/imx.c | 50 |
1 files changed, 39 insertions, 11 deletions
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 5a375bf0ebf4..6226e66c7966 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
| @@ -589,6 +589,7 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 589 | unsigned long flags; | 589 | unsigned long flags; |
| 590 | unsigned int ucr2, old_ucr1, old_txrxen, baud, quot; | 590 | unsigned int ucr2, old_ucr1, old_txrxen, baud, quot; |
| 591 | unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; | 591 | unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; |
| 592 | unsigned int div, num, denom, ufcr; | ||
| 592 | 593 | ||
| 593 | /* | 594 | /* |
| 594 | * If we don't support modem control lines, don't allow | 595 | * If we don't support modem control lines, don't allow |
| @@ -634,7 +635,7 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 634 | /* | 635 | /* |
| 635 | * Ask the core to calculate the divisor for us. | 636 | * Ask the core to calculate the divisor for us. |
| 636 | */ | 637 | */ |
| 637 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | 638 | baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16); |
| 638 | quot = uart_get_divisor(port, baud); | 639 | quot = uart_get_divisor(port, baud); |
| 639 | 640 | ||
| 640 | spin_lock_irqsave(&sport->port.lock, flags); | 641 | spin_lock_irqsave(&sport->port.lock, flags); |
| @@ -684,14 +685,41 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 684 | sport->port.membase + UCR2); | 685 | sport->port.membase + UCR2); |
| 685 | old_txrxen &= (UCR2_TXEN | UCR2_RXEN); | 686 | old_txrxen &= (UCR2_TXEN | UCR2_RXEN); |
| 686 | 687 | ||
| 687 | /* set the baud rate. We assume uartclk = 16 MHz | 688 | div = sport->port.uartclk / (baud * 16); |
| 688 | * | 689 | if (div > 7) |
| 689 | * baud * 16 UBIR - 1 | 690 | div = 7; |
| 690 | * --------- = -------- | 691 | if (!div) |
| 691 | * uartclk UBMR - 1 | 692 | div = 1; |
| 692 | */ | 693 | |
| 693 | writel((baud / 100) - 1, sport->port.membase + UBIR); | 694 | num = baud; |
| 694 | writel(10000 - 1, sport->port.membase + UBMR); | 695 | denom = port->uartclk / div / 16; |
| 696 | |||
| 697 | /* shift num and denom right until they fit into 16 bits */ | ||
| 698 | while (num > 0x10000 || denom > 0x10000) { | ||
| 699 | num >>= 1; | ||
| 700 | denom >>= 1; | ||
| 701 | } | ||
| 702 | if (num > 0) | ||
| 703 | num -= 1; | ||
| 704 | if (denom > 0) | ||
| 705 | denom -= 1; | ||
| 706 | |||
| 707 | writel(num, sport->port.membase + UBIR); | ||
| 708 | writel(denom, sport->port.membase + UBMR); | ||
| 709 | |||
| 710 | if (div == 7) | ||
| 711 | div = 6; /* 6 in RFDIV means divide by 7 */ | ||
| 712 | else | ||
| 713 | div = 6 - div; | ||
| 714 | |||
| 715 | ufcr = readl(sport->port.membase + UFCR); | ||
| 716 | ufcr = (ufcr & (~UFCR_RFDIV)) | | ||
| 717 | (div << 7); | ||
| 718 | writel(ufcr, sport->port.membase + UFCR); | ||
| 719 | |||
| 720 | #ifdef ONEMS | ||
| 721 | writel(sport->port.uartclk / div / 1000, sport->port.membase + ONEMS); | ||
| 722 | #endif | ||
| 695 | 723 | ||
| 696 | writel(old_ucr1, sport->port.membase + UCR1); | 724 | writel(old_ucr1, sport->port.membase + UCR1); |
| 697 | 725 | ||
| @@ -812,7 +840,6 @@ static struct imx_port imx_ports[] = { | |||
| 812 | .membase = (void *)IMX_UART1_BASE, | 840 | .membase = (void *)IMX_UART1_BASE, |
| 813 | .mapbase = 0x00206000, | 841 | .mapbase = 0x00206000, |
| 814 | .irq = UART1_MINT_RX, | 842 | .irq = UART1_MINT_RX, |
| 815 | .uartclk = 16000000, | ||
| 816 | .fifosize = 32, | 843 | .fifosize = 32, |
| 817 | .flags = UPF_BOOT_AUTOCONF, | 844 | .flags = UPF_BOOT_AUTOCONF, |
| 818 | .ops = &imx_pops, | 845 | .ops = &imx_pops, |
| @@ -828,7 +855,6 @@ static struct imx_port imx_ports[] = { | |||
| 828 | .membase = (void *)IMX_UART2_BASE, | 855 | .membase = (void *)IMX_UART2_BASE, |
| 829 | .mapbase = 0x00207000, | 856 | .mapbase = 0x00207000, |
| 830 | .irq = UART2_MINT_RX, | 857 | .irq = UART2_MINT_RX, |
| 831 | .uartclk = 16000000, | ||
| 832 | .fifosize = 32, | 858 | .fifosize = 32, |
| 833 | .flags = UPF_BOOT_AUTOCONF, | 859 | .flags = UPF_BOOT_AUTOCONF, |
| 834 | .ops = &imx_pops, | 860 | .ops = &imx_pops, |
| @@ -858,6 +884,8 @@ static void __init imx_init_ports(void) | |||
| 858 | init_timer(&imx_ports[i].timer); | 884 | init_timer(&imx_ports[i].timer); |
| 859 | imx_ports[i].timer.function = imx_timeout; | 885 | imx_ports[i].timer.function = imx_timeout; |
| 860 | imx_ports[i].timer.data = (unsigned long)&imx_ports[i]; | 886 | imx_ports[i].timer.data = (unsigned long)&imx_ports[i]; |
| 887 | |||
| 888 | imx_ports[i].port.uartclk = imx_get_perclk1(); | ||
| 861 | } | 889 | } |
| 862 | } | 890 | } |
| 863 | 891 | ||
