diff options
Diffstat (limited to 'drivers/serial/ioc4_serial.c')
-rw-r--r-- | drivers/serial/ioc4_serial.c | 50 |
1 files changed, 19 insertions, 31 deletions
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c index d054f1265701..ba4e13a22a50 100644 --- a/drivers/serial/ioc4_serial.c +++ b/drivers/serial/ioc4_serial.c | |||
@@ -838,7 +838,7 @@ static int inline port_init(struct ioc4_port *port) | |||
838 | port->ip_tx_prod = readl(&port->ip_serial_regs->stcir) & PROD_CONS_MASK; | 838 | port->ip_tx_prod = readl(&port->ip_serial_regs->stcir) & PROD_CONS_MASK; |
839 | writel(port->ip_tx_prod, &port->ip_serial_regs->stpir); | 839 | writel(port->ip_tx_prod, &port->ip_serial_regs->stpir); |
840 | port->ip_rx_cons = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK; | 840 | port->ip_rx_cons = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK; |
841 | writel(port->ip_rx_cons, &port->ip_serial_regs->srcir); | 841 | writel(port->ip_rx_cons | IOC4_SRCIR_ARM, &port->ip_serial_regs->srcir); |
842 | 842 | ||
843 | /* Disable interrupts for this 16550 */ | 843 | /* Disable interrupts for this 16550 */ |
844 | uart = port->ip_uart_regs; | 844 | uart = port->ip_uart_regs; |
@@ -1272,8 +1272,9 @@ static inline int set_rx_timeout(struct ioc4_port *port, int timeout) | |||
1272 | * and set the rx threshold to that amount. There are 4 chars | 1272 | * and set the rx threshold to that amount. There are 4 chars |
1273 | * per ring entry, so we'll divide the number of chars that will | 1273 | * per ring entry, so we'll divide the number of chars that will |
1274 | * arrive in timeout by 4. | 1274 | * arrive in timeout by 4. |
1275 | * So .... timeout * baud / 10 / HZ / 4, with HZ = 100. | ||
1275 | */ | 1276 | */ |
1276 | threshold = timeout * port->ip_baud / 10 / HZ / 4; | 1277 | threshold = timeout * port->ip_baud / 4000; |
1277 | if (threshold == 0) | 1278 | if (threshold == 0) |
1278 | threshold = 1; /* otherwise we'll intr all the time! */ | 1279 | threshold = 1; /* otherwise we'll intr all the time! */ |
1279 | 1280 | ||
@@ -1285,8 +1286,10 @@ static inline int set_rx_timeout(struct ioc4_port *port, int timeout) | |||
1285 | 1286 | ||
1286 | writel(port->ip_sscr, &port->ip_serial_regs->sscr); | 1287 | writel(port->ip_sscr, &port->ip_serial_regs->sscr); |
1287 | 1288 | ||
1288 | /* Now set the rx timeout to the given value */ | 1289 | /* Now set the rx timeout to the given value |
1289 | timeout = timeout * IOC4_SRTR_HZ / HZ; | 1290 | * again timeout * IOC4_SRTR_HZ / HZ |
1291 | */ | ||
1292 | timeout = timeout * IOC4_SRTR_HZ / 100; | ||
1290 | if (timeout > IOC4_SRTR_CNT) | 1293 | if (timeout > IOC4_SRTR_CNT) |
1291 | timeout = IOC4_SRTR_CNT; | 1294 | timeout = IOC4_SRTR_CNT; |
1292 | 1295 | ||
@@ -1380,7 +1383,7 @@ config_port(struct ioc4_port *port, | |||
1380 | if (port->ip_tx_lowat == 0) | 1383 | if (port->ip_tx_lowat == 0) |
1381 | port->ip_tx_lowat = 1; | 1384 | port->ip_tx_lowat = 1; |
1382 | 1385 | ||
1383 | set_rx_timeout(port, port->ip_rx_timeout); | 1386 | set_rx_timeout(port, 2); |
1384 | 1387 | ||
1385 | return 0; | 1388 | return 0; |
1386 | } | 1389 | } |
@@ -1685,8 +1688,8 @@ ioc4_change_speed(struct uart_port *the_port, | |||
1685 | { | 1688 | { |
1686 | struct ioc4_port *port = get_ioc4_port(the_port); | 1689 | struct ioc4_port *port = get_ioc4_port(the_port); |
1687 | int baud, bits; | 1690 | int baud, bits; |
1688 | unsigned cflag, cval; | 1691 | unsigned cflag; |
1689 | int new_parity = 0, new_parity_enable = 0, new_stop = 1, new_data = 8; | 1692 | int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8; |
1690 | struct uart_info *info = the_port->info; | 1693 | struct uart_info *info = the_port->info; |
1691 | 1694 | ||
1692 | cflag = new_termios->c_cflag; | 1695 | cflag = new_termios->c_cflag; |
@@ -1694,48 +1697,35 @@ ioc4_change_speed(struct uart_port *the_port, | |||
1694 | switch (cflag & CSIZE) { | 1697 | switch (cflag & CSIZE) { |
1695 | case CS5: | 1698 | case CS5: |
1696 | new_data = 5; | 1699 | new_data = 5; |
1697 | cval = 0x00; | ||
1698 | bits = 7; | 1700 | bits = 7; |
1699 | break; | 1701 | break; |
1700 | case CS6: | 1702 | case CS6: |
1701 | new_data = 6; | 1703 | new_data = 6; |
1702 | cval = 0x01; | ||
1703 | bits = 8; | 1704 | bits = 8; |
1704 | break; | 1705 | break; |
1705 | case CS7: | 1706 | case CS7: |
1706 | new_data = 7; | 1707 | new_data = 7; |
1707 | cval = 0x02; | ||
1708 | bits = 9; | 1708 | bits = 9; |
1709 | break; | 1709 | break; |
1710 | case CS8: | 1710 | case CS8: |
1711 | new_data = 8; | 1711 | new_data = 8; |
1712 | cval = 0x03; | ||
1713 | bits = 10; | 1712 | bits = 10; |
1714 | break; | 1713 | break; |
1715 | default: | 1714 | default: |
1716 | /* cuz we always need a default ... */ | 1715 | /* cuz we always need a default ... */ |
1717 | new_data = 5; | 1716 | new_data = 5; |
1718 | cval = 0x00; | ||
1719 | bits = 7; | 1717 | bits = 7; |
1720 | break; | 1718 | break; |
1721 | } | 1719 | } |
1722 | if (cflag & CSTOPB) { | 1720 | if (cflag & CSTOPB) { |
1723 | cval |= 0x04; | ||
1724 | bits++; | 1721 | bits++; |
1725 | new_stop = 1; | 1722 | new_stop = 1; |
1726 | } | 1723 | } |
1727 | if (cflag & PARENB) { | 1724 | if (cflag & PARENB) { |
1728 | cval |= UART_LCR_PARITY; | ||
1729 | bits++; | 1725 | bits++; |
1730 | new_parity_enable = 1; | 1726 | new_parity_enable = 1; |
1731 | } | 1727 | if (cflag & PARODD) |
1732 | if (cflag & PARODD) { | 1728 | new_parity = 1; |
1733 | cval |= UART_LCR_EPAR; | ||
1734 | new_parity = 1; | ||
1735 | } | ||
1736 | if (cflag & IGNPAR) { | ||
1737 | cval &= ~UART_LCR_PARITY; | ||
1738 | new_parity_enable = 0; | ||
1739 | } | 1729 | } |
1740 | baud = uart_get_baud_rate(the_port, new_termios, old_termios, | 1730 | baud = uart_get_baud_rate(the_port, new_termios, old_termios, |
1741 | MIN_BAUD_SUPPORTED, MAX_BAUD_SUPPORTED); | 1731 | MIN_BAUD_SUPPORTED, MAX_BAUD_SUPPORTED); |
@@ -1765,10 +1755,15 @@ ioc4_change_speed(struct uart_port *the_port, | |||
1765 | the_port->ignore_status_mask &= ~N_DATA_READY; | 1755 | the_port->ignore_status_mask &= ~N_DATA_READY; |
1766 | } | 1756 | } |
1767 | 1757 | ||
1768 | if (cflag & CRTSCTS) | 1758 | if (cflag & CRTSCTS) { |
1769 | info->flags |= ASYNC_CTS_FLOW; | 1759 | info->flags |= ASYNC_CTS_FLOW; |
1770 | else | 1760 | port->ip_sscr |= IOC4_SSCR_HFC_EN; |
1761 | } | ||
1762 | else { | ||
1771 | info->flags &= ~ASYNC_CTS_FLOW; | 1763 | info->flags &= ~ASYNC_CTS_FLOW; |
1764 | port->ip_sscr &= ~IOC4_SSCR_HFC_EN; | ||
1765 | } | ||
1766 | writel(port->ip_sscr, &port->ip_serial_regs->sscr); | ||
1772 | 1767 | ||
1773 | /* Set the configuration and proper notification call */ | 1768 | /* Set the configuration and proper notification call */ |
1774 | DPRINT_CONFIG(("%s : port 0x%p cflag 0%o " | 1769 | DPRINT_CONFIG(("%s : port 0x%p cflag 0%o " |
@@ -1825,12 +1820,6 @@ static inline int ic4_startup_local(struct uart_port *the_port) | |||
1825 | /* set the speed of the serial port */ | 1820 | /* set the speed of the serial port */ |
1826 | ioc4_change_speed(the_port, info->tty->termios, (struct termios *)0); | 1821 | ioc4_change_speed(the_port, info->tty->termios, (struct termios *)0); |
1827 | 1822 | ||
1828 | /* enable hardware flow control - after ioc4_change_speed because | ||
1829 | * ASYNC_CTS_FLOW is set there */ | ||
1830 | if (info->flags & ASYNC_CTS_FLOW) { | ||
1831 | port->ip_sscr |= IOC4_SSCR_HFC_EN; | ||
1832 | writel(port->ip_sscr, &port->ip_serial_regs->sscr); | ||
1833 | } | ||
1834 | info->flags |= UIF_INITIALIZED; | 1823 | info->flags |= UIF_INITIALIZED; |
1835 | return 0; | 1824 | return 0; |
1836 | } | 1825 | } |
@@ -1847,7 +1836,6 @@ static void ioc4_cb_output_lowat(struct ioc4_port *port) | |||
1847 | } | 1836 | } |
1848 | } | 1837 | } |
1849 | 1838 | ||
1850 | |||
1851 | /** | 1839 | /** |
1852 | * handle_intr - service any interrupts for the given port - 2nd level | 1840 | * handle_intr - service any interrupts for the given port - 2nd level |
1853 | * called via sd_intr | 1841 | * called via sd_intr |