aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2009-09-19 16:13:13 -0400
committerLive-CD User <linux@linux.site>2009-09-19 16:13:13 -0400
commitf0eefdc30e55e761facf645bd1be1339b21c30e6 (patch)
treefbde46003a58550c3312ce7732a23213985e81fa
parentf0737579424dd2c4e68bdd54c718455a3f42c7b5 (diff)
cyclades: avoid addresses recomputation
Don't fetch firmware address and recompute channel control on each port access. Precompute the values on init and use them later all the time. The same for board control. This simplify code and improves readability. Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/char/cyclades.c241
-rw-r--r--include/linux/cyclades.h10
2 files changed, 81 insertions, 170 deletions
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 9e0cd7020aef..7a7092ae5d39 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -814,7 +814,7 @@ static char rflow_thr[] = { /* rflow threshold */
814/* The Cyclom-Ye has placed the sequential chips in non-sequential 814/* The Cyclom-Ye has placed the sequential chips in non-sequential
815 * address order. This look-up table overcomes that problem. 815 * address order. This look-up table overcomes that problem.
816 */ 816 */
817static int cy_chip_offset[] = { 0x0000, 817static const unsigned int cy_chip_offset[] = { 0x0000,
818 0x0400, 818 0x0400,
819 0x0800, 819 0x0800,
820 0x0C00, 820 0x0C00,
@@ -1406,15 +1406,9 @@ static int
1406cyz_fetch_msg(struct cyclades_card *cinfo, 1406cyz_fetch_msg(struct cyclades_card *cinfo,
1407 __u32 *channel, __u8 *cmd, __u32 *param) 1407 __u32 *channel, __u8 *cmd, __u32 *param)
1408{ 1408{
1409 struct FIRM_ID __iomem *firm_id; 1409 struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl;
1410 struct ZFW_CTRL __iomem *zfw_ctrl;
1411 struct BOARD_CTRL __iomem *board_ctrl;
1412 unsigned long loc_doorbell; 1410 unsigned long loc_doorbell;
1413 1411
1414 firm_id = cinfo->base_addr + ID_ADDRESS;
1415 zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
1416 board_ctrl = &zfw_ctrl->board_ctrl;
1417
1418 loc_doorbell = readl(&cinfo->ctl_addr.p9060->loc_doorbell); 1412 loc_doorbell = readl(&cinfo->ctl_addr.p9060->loc_doorbell);
1419 if (loc_doorbell) { 1413 if (loc_doorbell) {
1420 *cmd = (char)(0xff & loc_doorbell); 1414 *cmd = (char)(0xff & loc_doorbell);
@@ -1430,19 +1424,13 @@ static int
1430cyz_issue_cmd(struct cyclades_card *cinfo, 1424cyz_issue_cmd(struct cyclades_card *cinfo,
1431 __u32 channel, __u8 cmd, __u32 param) 1425 __u32 channel, __u8 cmd, __u32 param)
1432{ 1426{
1433 struct FIRM_ID __iomem *firm_id; 1427 struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl;
1434 struct ZFW_CTRL __iomem *zfw_ctrl;
1435 struct BOARD_CTRL __iomem *board_ctrl;
1436 __u32 __iomem *pci_doorbell; 1428 __u32 __iomem *pci_doorbell;
1437 unsigned int index; 1429 unsigned int index;
1438 1430
1439 firm_id = cinfo->base_addr + ID_ADDRESS;
1440 if (!cyz_is_loaded(cinfo)) 1431 if (!cyz_is_loaded(cinfo))
1441 return -1; 1432 return -1;
1442 1433
1443 zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
1444 board_ctrl = &zfw_ctrl->board_ctrl;
1445
1446 index = 0; 1434 index = 0;
1447 pci_doorbell = &cinfo->ctl_addr.p9060->pci_doorbell; 1435 pci_doorbell = &cinfo->ctl_addr.p9060->pci_doorbell;
1448 while ((readl(pci_doorbell) & 0xff) != 0) { 1436 while ((readl(pci_doorbell) & 0xff) != 0) {
@@ -1457,9 +1445,9 @@ cyz_issue_cmd(struct cyclades_card *cinfo,
1457 return 0; 1445 return 0;
1458} /* cyz_issue_cmd */ 1446} /* cyz_issue_cmd */
1459 1447
1460static void cyz_handle_rx(struct cyclades_port *info, struct tty_struct *tty, 1448static void cyz_handle_rx(struct cyclades_port *info, struct tty_struct *tty)
1461 struct BUF_CTRL __iomem *buf_ctrl)
1462{ 1449{
1450 struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
1463 struct cyclades_card *cinfo = info->card; 1451 struct cyclades_card *cinfo = info->card;
1464 unsigned int char_count; 1452 unsigned int char_count;
1465 int len; 1453 int len;
@@ -1549,9 +1537,9 @@ static void cyz_handle_rx(struct cyclades_port *info, struct tty_struct *tty,
1549 } 1537 }
1550} 1538}
1551 1539
1552static void cyz_handle_tx(struct cyclades_port *info, struct tty_struct *tty, 1540static void cyz_handle_tx(struct cyclades_port *info, struct tty_struct *tty)
1553 struct BUF_CTRL __iomem *buf_ctrl)
1554{ 1541{
1542 struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
1555 struct cyclades_card *cinfo = info->card; 1543 struct cyclades_card *cinfo = info->card;
1556 u8 data; 1544 u8 data;
1557 unsigned int char_count; 1545 unsigned int char_count;
@@ -1627,21 +1615,14 @@ ztxdone:
1627 1615
1628static void cyz_handle_cmd(struct cyclades_card *cinfo) 1616static void cyz_handle_cmd(struct cyclades_card *cinfo)
1629{ 1617{
1618 struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl;
1630 struct tty_struct *tty; 1619 struct tty_struct *tty;
1631 struct cyclades_port *info; 1620 struct cyclades_port *info;
1632 static struct FIRM_ID __iomem *firm_id;
1633 static struct ZFW_CTRL __iomem *zfw_ctrl;
1634 static struct BOARD_CTRL __iomem *board_ctrl;
1635 static struct CH_CTRL __iomem *ch_ctrl;
1636 static struct BUF_CTRL __iomem *buf_ctrl;
1637 __u32 channel, param, fw_ver; 1621 __u32 channel, param, fw_ver;
1638 __u8 cmd; 1622 __u8 cmd;
1639 int special_count; 1623 int special_count;
1640 int delta_count; 1624 int delta_count;
1641 1625
1642 firm_id = cinfo->base_addr + ID_ADDRESS;
1643 zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
1644 board_ctrl = &zfw_ctrl->board_ctrl;
1645 fw_ver = readl(&board_ctrl->fw_version); 1626 fw_ver = readl(&board_ctrl->fw_version);
1646 1627
1647 while (cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1) { 1628 while (cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1) {
@@ -1652,9 +1633,6 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1652 if (tty == NULL) 1633 if (tty == NULL)
1653 continue; 1634 continue;
1654 1635
1655 ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
1656 buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
1657
1658 switch (cmd) { 1636 switch (cmd) {
1659 case C_CM_PR_ERROR: 1637 case C_CM_PR_ERROR:
1660 tty_insert_flip_char(tty, 0, TTY_PARITY); 1638 tty_insert_flip_char(tty, 0, TTY_PARITY);
@@ -1675,9 +1653,9 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1675 info->icount.dcd++; 1653 info->icount.dcd++;
1676 delta_count++; 1654 delta_count++;
1677 if (info->port.flags & ASYNC_CHECK_CD) { 1655 if (info->port.flags & ASYNC_CHECK_CD) {
1678 if ((fw_ver > 241 ? ((u_long) param) : 1656 u32 dcd = fw_ver > 241 ? param :
1679 readl(&ch_ctrl->rs_status)) & 1657 readl(&info->u.cyz.ch_ctrl->rs_status);
1680 C_RS_DCD) { 1658 if (dcd & C_RS_DCD) {
1681 wake_up_interruptible(&info->port.open_wait); 1659 wake_up_interruptible(&info->port.open_wait);
1682 } else { 1660 } else {
1683 tty_hangup(tty); 1661 tty_hangup(tty);
@@ -1712,7 +1690,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1712 printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, " 1690 printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, "
1713 "port %ld\n", info->card, channel); 1691 "port %ld\n", info->card, channel);
1714#endif 1692#endif
1715 cyz_handle_rx(info, tty, buf_ctrl); 1693 cyz_handle_rx(info, tty);
1716 break; 1694 break;
1717 case C_CM_TXBEMPTY: 1695 case C_CM_TXBEMPTY:
1718 case C_CM_TXLOWWM: 1696 case C_CM_TXLOWWM:
@@ -1722,7 +1700,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1722 printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, " 1700 printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, "
1723 "port %ld\n", info->card, channel); 1701 "port %ld\n", info->card, channel);
1724#endif 1702#endif
1725 cyz_handle_tx(info, tty, buf_ctrl); 1703 cyz_handle_tx(info, tty);
1726 break; 1704 break;
1727#endif /* CONFIG_CYZ_INTR */ 1705#endif /* CONFIG_CYZ_INTR */
1728 case C_CM_FATAL: 1706 case C_CM_FATAL:
@@ -1781,9 +1759,6 @@ static void cyz_poll(unsigned long arg)
1781{ 1759{
1782 struct cyclades_card *cinfo; 1760 struct cyclades_card *cinfo;
1783 struct cyclades_port *info; 1761 struct cyclades_port *info;
1784 struct FIRM_ID __iomem *firm_id;
1785 struct ZFW_CTRL __iomem *zfw_ctrl;
1786 struct BUF_CTRL __iomem *buf_ctrl;
1787 unsigned long expires = jiffies + HZ; 1762 unsigned long expires = jiffies + HZ;
1788 unsigned int port, card; 1763 unsigned int port, card;
1789 1764
@@ -1795,10 +1770,6 @@ static void cyz_poll(unsigned long arg)
1795 if (!cyz_is_loaded(cinfo)) 1770 if (!cyz_is_loaded(cinfo))
1796 continue; 1771 continue;
1797 1772
1798 firm_id = cinfo->base_addr + ID_ADDRESS;
1799 zfw_ctrl = cinfo->base_addr +
1800 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
1801
1802 /* Skip first polling cycle to avoid racing conditions with the FW */ 1773 /* Skip first polling cycle to avoid racing conditions with the FW */
1803 if (!cinfo->intr_enabled) { 1774 if (!cinfo->intr_enabled) {
1804 cinfo->intr_enabled = 1; 1775 cinfo->intr_enabled = 1;
@@ -1811,15 +1782,13 @@ static void cyz_poll(unsigned long arg)
1811 struct tty_struct *tty; 1782 struct tty_struct *tty;
1812 1783
1813 info = &cinfo->ports[port]; 1784 info = &cinfo->ports[port];
1814 buf_ctrl = &(zfw_ctrl->buf_ctrl[port]);
1815
1816 tty = tty_port_tty_get(&info->port); 1785 tty = tty_port_tty_get(&info->port);
1817 /* OK to pass NULL to the handle functions below. 1786 /* OK to pass NULL to the handle functions below.
1818 They need to drop the data in that case. */ 1787 They need to drop the data in that case. */
1819 1788
1820 if (!info->throttle) 1789 if (!info->throttle)
1821 cyz_handle_rx(info, tty, buf_ctrl); 1790 cyz_handle_rx(info, tty);
1822 cyz_handle_tx(info, tty, buf_ctrl); 1791 cyz_handle_tx(info, tty);
1823 tty_kref_put(tty); 1792 tty_kref_put(tty);
1824 } 1793 }
1825 /* poll every 'cyz_polling_cycle' period */ 1794 /* poll every 'cyz_polling_cycle' period */
@@ -1922,45 +1891,34 @@ static int cy_startup(struct cyclades_port *info, struct tty_struct *tty)
1922 spin_unlock_irqrestore(&card->card_lock, flags); 1891 spin_unlock_irqrestore(&card->card_lock, flags);
1923 1892
1924 } else { 1893 } else {
1925 struct FIRM_ID __iomem *firm_id; 1894 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
1926 struct ZFW_CTRL __iomem *zfw_ctrl;
1927 struct BOARD_CTRL __iomem *board_ctrl;
1928 struct CH_CTRL __iomem *ch_ctrl;
1929
1930 base_addr = card->base_addr;
1931 1895
1932 firm_id = base_addr + ID_ADDRESS;
1933 if (!cyz_is_loaded(card)) 1896 if (!cyz_is_loaded(card))
1934 return -ENODEV; 1897 return -ENODEV;
1935 1898
1936 zfw_ctrl = card->base_addr +
1937 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
1938 board_ctrl = &zfw_ctrl->board_ctrl;
1939 ch_ctrl = zfw_ctrl->ch_ctrl;
1940
1941#ifdef CY_DEBUG_OPEN 1899#ifdef CY_DEBUG_OPEN
1942 printk(KERN_DEBUG "cyc startup Z card %d, channel %d, " 1900 printk(KERN_DEBUG "cyc startup Z card %d, channel %d, "
1943 "base_addr %p\n", card, channel, base_addr); 1901 "base_addr %p\n", card, channel, card->base_addr);
1944#endif 1902#endif
1945 spin_lock_irqsave(&card->card_lock, flags); 1903 spin_lock_irqsave(&card->card_lock, flags);
1946 1904
1947 cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE); 1905 cy_writel(&ch_ctrl->op_mode, C_CH_ENABLE);
1948#ifdef Z_WAKE 1906#ifdef Z_WAKE
1949#ifdef CONFIG_CYZ_INTR 1907#ifdef CONFIG_CYZ_INTR
1950 cy_writel(&ch_ctrl[channel].intr_enable, 1908 cy_writel(&ch_ctrl->intr_enable,
1951 C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM | 1909 C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM |
1952 C_IN_RXNNDT | C_IN_IOCTLW | C_IN_MDCD); 1910 C_IN_RXNNDT | C_IN_IOCTLW | C_IN_MDCD);
1953#else 1911#else
1954 cy_writel(&ch_ctrl[channel].intr_enable, 1912 cy_writel(&ch_ctrl->intr_enable,
1955 C_IN_IOCTLW | C_IN_MDCD); 1913 C_IN_IOCTLW | C_IN_MDCD);
1956#endif /* CONFIG_CYZ_INTR */ 1914#endif /* CONFIG_CYZ_INTR */
1957#else 1915#else
1958#ifdef CONFIG_CYZ_INTR 1916#ifdef CONFIG_CYZ_INTR
1959 cy_writel(&ch_ctrl[channel].intr_enable, 1917 cy_writel(&ch_ctrl->intr_enable,
1960 C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM | 1918 C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM |
1961 C_IN_RXNNDT | C_IN_MDCD); 1919 C_IN_RXNNDT | C_IN_MDCD);
1962#else 1920#else
1963 cy_writel(&ch_ctrl[channel].intr_enable, C_IN_MDCD); 1921 cy_writel(&ch_ctrl->intr_enable, C_IN_MDCD);
1964#endif /* CONFIG_CYZ_INTR */ 1922#endif /* CONFIG_CYZ_INTR */
1965#endif /* Z_WAKE */ 1923#endif /* Z_WAKE */
1966 1924
@@ -1979,9 +1937,8 @@ static int cy_startup(struct cyclades_port *info, struct tty_struct *tty)
1979 1937
1980 /* set timeout !!! */ 1938 /* set timeout !!! */
1981 /* set RTS and DTR !!! */ 1939 /* set RTS and DTR !!! */
1982 cy_writel(&ch_ctrl[channel].rs_control, 1940 cy_writel(&ch_ctrl->rs_control, readl(&ch_ctrl->rs_control) |
1983 readl(&ch_ctrl[channel].rs_control) | C_RS_RTS | 1941 C_RS_RTS | C_RS_DTR);
1984 C_RS_DTR);
1985 retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L); 1942 retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L);
1986 if (retval != 0) { 1943 if (retval != 0) {
1987 printk(KERN_ERR "cyc:startup(3) retval on ttyC%d was " 1944 printk(KERN_ERR "cyc:startup(3) retval on ttyC%d was "
@@ -2110,27 +2067,17 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty)
2110 info->port.flags &= ~ASYNC_INITIALIZED; 2067 info->port.flags &= ~ASYNC_INITIALIZED;
2111 spin_unlock_irqrestore(&card->card_lock, flags); 2068 spin_unlock_irqrestore(&card->card_lock, flags);
2112 } else { 2069 } else {
2113 struct FIRM_ID __iomem *firm_id; 2070 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
2114 struct ZFW_CTRL __iomem *zfw_ctrl;
2115 struct BOARD_CTRL __iomem *board_ctrl;
2116 struct CH_CTRL __iomem *ch_ctrl;
2117 int retval; 2071 int retval;
2118 2072
2119 base_addr = card->base_addr;
2120#ifdef CY_DEBUG_OPEN 2073#ifdef CY_DEBUG_OPEN
2121 printk(KERN_DEBUG "cyc shutdown Z card %d, channel %d, " 2074 printk(KERN_DEBUG "cyc shutdown Z card %d, channel %d, "
2122 "base_addr %p\n", card, channel, base_addr); 2075 "base_addr %p\n", card, channel, card->base_addr);
2123#endif 2076#endif
2124 2077
2125 firm_id = base_addr + ID_ADDRESS;
2126 if (!cyz_is_loaded(card)) 2078 if (!cyz_is_loaded(card))
2127 return; 2079 return;
2128 2080
2129 zfw_ctrl = card->base_addr +
2130 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
2131 board_ctrl = &zfw_ctrl->board_ctrl;
2132 ch_ctrl = zfw_ctrl->ch_ctrl;
2133
2134 spin_lock_irqsave(&card->card_lock, flags); 2081 spin_lock_irqsave(&card->card_lock, flags);
2135 2082
2136 if (info->port.xmit_buf) { 2083 if (info->port.xmit_buf) {
@@ -2141,9 +2088,9 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty)
2141 } 2088 }
2142 2089
2143 if (tty->termios->c_cflag & HUPCL) { 2090 if (tty->termios->c_cflag & HUPCL) {
2144 cy_writel(&ch_ctrl[channel].rs_control, 2091 cy_writel(&ch_ctrl->rs_control,
2145 (__u32)(readl(&ch_ctrl[channel].rs_control) & 2092 readl(&ch_ctrl->rs_control) &
2146 ~(C_RS_RTS | C_RS_DTR))); 2093 ~(C_RS_RTS | C_RS_DTR));
2147 retval = cyz_issue_cmd(info->card, channel, 2094 retval = cyz_issue_cmd(info->card, channel,
2148 C_CM_IOCTLM, 0L); 2095 C_CM_IOCTLM, 0L);
2149 if (retval != 0) { 2096 if (retval != 0) {
@@ -2497,15 +2444,11 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
2497#ifdef Z_WAKE 2444#ifdef Z_WAKE
2498 /* Waiting for on-board buffers to be empty before closing 2445 /* Waiting for on-board buffers to be empty before closing
2499 the port */ 2446 the port */
2500 void __iomem *base_addr = card->base_addr; 2447 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
2501 struct FIRM_ID __iomem *firm_id = base_addr + ID_ADDRESS;
2502 struct ZFW_CTRL __iomem *zfw_ctrl =
2503 base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
2504 struct CH_CTRL __iomem *ch_ctrl = zfw_ctrl->ch_ctrl;
2505 int channel = info->line - card->first_line; 2448 int channel = info->line - card->first_line;
2506 int retval; 2449 int retval;
2507 2450
2508 if (readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) { 2451 if (readl(&ch_ctrl->flow_status) != C_FS_TXIDLE) {
2509 retval = cyz_issue_cmd(card, channel, C_CM_IOCTLW, 0L); 2452 retval = cyz_issue_cmd(card, channel, C_CM_IOCTLW, 0L);
2510 if (retval != 0) { 2453 if (retval != 0) {
2511 printk(KERN_DEBUG "cyc:cy_close retval on " 2454 printk(KERN_DEBUG "cyc:cy_close retval on "
@@ -2685,18 +2628,13 @@ static int cy_write_room(struct tty_struct *tty)
2685 2628
2686static int cy_chars_in_buffer(struct tty_struct *tty) 2629static int cy_chars_in_buffer(struct tty_struct *tty)
2687{ 2630{
2688 struct cyclades_card *card;
2689 struct cyclades_port *info = tty->driver_data; 2631 struct cyclades_port *info = tty->driver_data;
2690 int channel;
2691 2632
2692 if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer")) 2633 if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer"))
2693 return 0; 2634 return 0;
2694 2635
2695 card = info->card;
2696 channel = (info->line) - (card->first_line);
2697
2698#ifdef Z_EXT_CHARS_IN_BUFFER 2636#ifdef Z_EXT_CHARS_IN_BUFFER
2699 if (!cy_is_Z(card)) { 2637 if (!cy_is_Z(info->card)) {
2700#endif /* Z_EXT_CHARS_IN_BUFFER */ 2638#endif /* Z_EXT_CHARS_IN_BUFFER */
2701#ifdef CY_DEBUG_IO 2639#ifdef CY_DEBUG_IO
2702 printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n", 2640 printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n",
@@ -2705,20 +2643,11 @@ static int cy_chars_in_buffer(struct tty_struct *tty)
2705 return info->xmit_cnt; 2643 return info->xmit_cnt;
2706#ifdef Z_EXT_CHARS_IN_BUFFER 2644#ifdef Z_EXT_CHARS_IN_BUFFER
2707 } else { 2645 } else {
2708 static struct FIRM_ID *firm_id; 2646 struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
2709 static struct ZFW_CTRL *zfw_ctrl;
2710 static struct CH_CTRL *ch_ctrl;
2711 static struct BUF_CTRL *buf_ctrl;
2712 int char_count; 2647 int char_count;
2713 __u32 tx_put, tx_get, tx_bufsize; 2648 __u32 tx_put, tx_get, tx_bufsize;
2714 2649
2715 lock_kernel(); 2650 lock_kernel();
2716 firm_id = card->base_addr + ID_ADDRESS;
2717 zfw_ctrl = card->base_addr +
2718 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
2719 ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
2720 buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
2721
2722 tx_get = readl(&buf_ctrl->tx_get); 2651 tx_get = readl(&buf_ctrl->tx_get);
2723 tx_put = readl(&buf_ctrl->tx_put); 2652 tx_put = readl(&buf_ctrl->tx_put);
2724 tx_bufsize = readl(&buf_ctrl->tx_bufsize); 2653 tx_bufsize = readl(&buf_ctrl->tx_bufsize);
@@ -3019,20 +2948,13 @@ static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty)
3019 spin_unlock_irqrestore(&card->card_lock, flags); 2948 spin_unlock_irqrestore(&card->card_lock, flags);
3020 2949
3021 } else { 2950 } else {
3022 struct FIRM_ID __iomem *firm_id; 2951 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
3023 struct ZFW_CTRL __iomem *zfw_ctrl;
3024 struct CH_CTRL __iomem *ch_ctrl;
3025 __u32 sw_flow; 2952 __u32 sw_flow;
3026 int retval; 2953 int retval;
3027 2954
3028 firm_id = card->base_addr + ID_ADDRESS;
3029 if (!cyz_is_loaded(card)) 2955 if (!cyz_is_loaded(card))
3030 return; 2956 return;
3031 2957
3032 zfw_ctrl = card->base_addr +
3033 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
3034 ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
3035
3036 /* baud rate */ 2958 /* baud rate */
3037 baud = tty_get_baud_rate(tty); 2959 baud = tty_get_baud_rate(tty);
3038 if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) == 2960 if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
@@ -3268,10 +3190,6 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file)
3268 unsigned char status; 3190 unsigned char status;
3269 unsigned long lstatus; 3191 unsigned long lstatus;
3270 unsigned int result; 3192 unsigned int result;
3271 struct FIRM_ID __iomem *firm_id;
3272 struct ZFW_CTRL __iomem *zfw_ctrl;
3273 struct BOARD_CTRL __iomem *board_ctrl;
3274 struct CH_CTRL __iomem *ch_ctrl;
3275 3193
3276 if (serial_paranoia_check(info, tty->name, __func__)) 3194 if (serial_paranoia_check(info, tty->name, __func__))
3277 return -ENODEV; 3195 return -ENODEV;
@@ -3304,14 +3222,8 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file)
3304 ((status & CyDSR) ? TIOCM_DSR : 0) | 3222 ((status & CyDSR) ? TIOCM_DSR : 0) |
3305 ((status & CyCTS) ? TIOCM_CTS : 0); 3223 ((status & CyCTS) ? TIOCM_CTS : 0);
3306 } else { 3224 } else {
3307 base_addr = card->base_addr;
3308 firm_id = card->base_addr + ID_ADDRESS;
3309 if (cyz_is_loaded(card)) { 3225 if (cyz_is_loaded(card)) {
3310 zfw_ctrl = card->base_addr + 3226 lstatus = readl(&info->u.cyz.ch_ctrl->rs_status);
3311 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
3312 board_ctrl = &zfw_ctrl->board_ctrl;
3313 ch_ctrl = zfw_ctrl->ch_ctrl;
3314 lstatus = readl(&ch_ctrl[channel].rs_status);
3315 result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) | 3227 result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) |
3316 ((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) | 3228 ((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) |
3317 ((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) | 3229 ((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) |
@@ -3336,12 +3248,7 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
3336 struct cyclades_port *info = tty->driver_data; 3248 struct cyclades_port *info = tty->driver_data;
3337 struct cyclades_card *card; 3249 struct cyclades_card *card;
3338 int chip, channel, index; 3250 int chip, channel, index;
3339 void __iomem *base_addr;
3340 unsigned long flags; 3251 unsigned long flags;
3341 struct FIRM_ID __iomem *firm_id;
3342 struct ZFW_CTRL __iomem *zfw_ctrl;
3343 struct BOARD_CTRL __iomem *board_ctrl;
3344 struct CH_CTRL __iomem *ch_ctrl;
3345 int retval; 3252 int retval;
3346 3253
3347 if (serial_paranoia_check(info, tty->name, __func__)) 3254 if (serial_paranoia_check(info, tty->name, __func__))
@@ -3350,6 +3257,7 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
3350 card = info->card; 3257 card = info->card;
3351 channel = (info->line) - (card->first_line); 3258 channel = (info->line) - (card->first_line);
3352 if (!cy_is_Z(card)) { 3259 if (!cy_is_Z(card)) {
3260 void __iomem *base_addr;
3353 chip = channel >> 2; 3261 chip = channel >> 2;
3354 channel &= 0x03; 3262 channel &= 0x03;
3355 index = card->bus_index; 3263 index = card->bus_index;
@@ -3421,34 +3329,26 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
3421 spin_unlock_irqrestore(&card->card_lock, flags); 3329 spin_unlock_irqrestore(&card->card_lock, flags);
3422 } 3330 }
3423 } else { 3331 } else {
3424 base_addr = card->base_addr;
3425
3426 firm_id = card->base_addr + ID_ADDRESS;
3427 if (cyz_is_loaded(card)) { 3332 if (cyz_is_loaded(card)) {
3428 zfw_ctrl = card->base_addr + 3333 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
3429 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
3430 board_ctrl = &zfw_ctrl->board_ctrl;
3431 ch_ctrl = zfw_ctrl->ch_ctrl;
3432 3334
3433 if (set & TIOCM_RTS) { 3335 if (set & TIOCM_RTS) {
3434 spin_lock_irqsave(&card->card_lock, flags); 3336 spin_lock_irqsave(&card->card_lock, flags);
3435 cy_writel(&ch_ctrl[channel].rs_control, 3337 cy_writel(&ch_ctrl->rs_control,
3436 readl(&ch_ctrl[channel].rs_control) | 3338 readl(&ch_ctrl->rs_control) | C_RS_RTS);
3437 C_RS_RTS);
3438 spin_unlock_irqrestore(&card->card_lock, flags); 3339 spin_unlock_irqrestore(&card->card_lock, flags);
3439 } 3340 }
3440 if (clear & TIOCM_RTS) { 3341 if (clear & TIOCM_RTS) {
3441 spin_lock_irqsave(&card->card_lock, flags); 3342 spin_lock_irqsave(&card->card_lock, flags);
3442 cy_writel(&ch_ctrl[channel].rs_control, 3343 cy_writel(&ch_ctrl->rs_control,
3443 readl(&ch_ctrl[channel].rs_control) & 3344 readl(&ch_ctrl->rs_control) &
3444 ~C_RS_RTS); 3345 ~C_RS_RTS);
3445 spin_unlock_irqrestore(&card->card_lock, flags); 3346 spin_unlock_irqrestore(&card->card_lock, flags);
3446 } 3347 }
3447 if (set & TIOCM_DTR) { 3348 if (set & TIOCM_DTR) {
3448 spin_lock_irqsave(&card->card_lock, flags); 3349 spin_lock_irqsave(&card->card_lock, flags);
3449 cy_writel(&ch_ctrl[channel].rs_control, 3350 cy_writel(&ch_ctrl->rs_control,
3450 readl(&ch_ctrl[channel].rs_control) | 3351 readl(&ch_ctrl->rs_control) | C_RS_DTR);
3451 C_RS_DTR);
3452#ifdef CY_DEBUG_DTR 3352#ifdef CY_DEBUG_DTR
3453 printk(KERN_DEBUG "cyc:set_modem_info raising " 3353 printk(KERN_DEBUG "cyc:set_modem_info raising "
3454 "Z DTR\n"); 3354 "Z DTR\n");
@@ -3457,8 +3357,8 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
3457 } 3357 }
3458 if (clear & TIOCM_DTR) { 3358 if (clear & TIOCM_DTR) {
3459 spin_lock_irqsave(&card->card_lock, flags); 3359 spin_lock_irqsave(&card->card_lock, flags);
3460 cy_writel(&ch_ctrl[channel].rs_control, 3360 cy_writel(&ch_ctrl->rs_control,
3461 readl(&ch_ctrl[channel].rs_control) & 3361 readl(&ch_ctrl->rs_control) &
3462 ~C_RS_DTR); 3362 ~C_RS_DTR);
3463#ifdef CY_DEBUG_DTR 3363#ifdef CY_DEBUG_DTR
3464 printk(KERN_DEBUG "cyc:set_modem_info clearing " 3364 printk(KERN_DEBUG "cyc:set_modem_info clearing "
@@ -4171,17 +4071,8 @@ static int cyz_carrier_raised(struct tty_port *port)
4171{ 4071{
4172 struct cyclades_port *info = container_of(port, struct cyclades_port, 4072 struct cyclades_port *info = container_of(port, struct cyclades_port,
4173 port); 4073 port);
4174 struct cyclades_card *cinfo = info->card;
4175 void __iomem *base = cinfo->base_addr;
4176 struct FIRM_ID __iomem *firm_id = base + ID_ADDRESS;
4177 struct ZFW_CTRL __iomem *zfw_ctrl;
4178 struct CH_CTRL __iomem *ch_ctrl;
4179 int channel = info->line - cinfo->first_line;
4180 4074
4181 zfw_ctrl = base + (readl(&firm_id->zfwctrl_addr) & 0xfffff); 4075 return readl(&info->u.cyz.ch_ctrl->rs_status) & C_RS_DCD;
4182 ch_ctrl = zfw_ctrl->ch_ctrl;
4183
4184 return readl(&ch_ctrl[channel].rs_status) & C_RS_DCD;
4185} 4076}
4186 4077
4187static void cyz_dtr_rts(struct tty_port *port, int raise) 4078static void cyz_dtr_rts(struct tty_port *port, int raise)
@@ -4189,22 +4080,16 @@ static void cyz_dtr_rts(struct tty_port *port, int raise)
4189 struct cyclades_port *info = container_of(port, struct cyclades_port, 4080 struct cyclades_port *info = container_of(port, struct cyclades_port,
4190 port); 4081 port);
4191 struct cyclades_card *cinfo = info->card; 4082 struct cyclades_card *cinfo = info->card;
4192 void __iomem *base = cinfo->base_addr; 4083 struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
4193 struct FIRM_ID __iomem *firm_id = base + ID_ADDRESS;
4194 struct ZFW_CTRL __iomem *zfw_ctrl;
4195 struct CH_CTRL __iomem *ch_ctrl;
4196 int ret, channel = info->line - cinfo->first_line; 4084 int ret, channel = info->line - cinfo->first_line;
4197 u32 rs; 4085 u32 rs;
4198 4086
4199 zfw_ctrl = base + (readl(&firm_id->zfwctrl_addr) & 0xfffff); 4087 rs = readl(&ch_ctrl->rs_control);
4200 ch_ctrl = zfw_ctrl->ch_ctrl;
4201
4202 rs = readl(&ch_ctrl[channel].rs_control);
4203 if (raise) 4088 if (raise)
4204 rs |= C_RS_RTS | C_RS_DTR; 4089 rs |= C_RS_RTS | C_RS_DTR;
4205 else 4090 else
4206 rs &= ~(C_RS_RTS | C_RS_DTR); 4091 rs &= ~(C_RS_RTS | C_RS_DTR);
4207 cy_writel(&ch_ctrl[channel].rs_control, rs); 4092 cy_writel(&ch_ctrl->rs_control, rs);
4208 ret = cyz_issue_cmd(cinfo, channel, C_CM_IOCTLM, 0L); 4093 ret = cyz_issue_cmd(cinfo, channel, C_CM_IOCTLM, 0L);
4209 if (ret != 0) 4094 if (ret != 0)
4210 printk(KERN_ERR "%s: retval on ttyC%d was %x\n", 4095 printk(KERN_ERR "%s: retval on ttyC%d was %x\n",
@@ -4235,8 +4120,7 @@ static const struct tty_port_operations cyz_port_ops = {
4235static int __devinit cy_init_card(struct cyclades_card *cinfo) 4120static int __devinit cy_init_card(struct cyclades_card *cinfo)
4236{ 4121{
4237 struct cyclades_port *info; 4122 struct cyclades_port *info;
4238 unsigned int port; 4123 unsigned int channel, port;
4239 unsigned short chip_number;
4240 4124
4241 spin_lock_init(&cinfo->card_lock); 4125 spin_lock_init(&cinfo->card_lock);
4242 cinfo->intr_enabled = 0; 4126 cinfo->intr_enabled = 0;
@@ -4248,9 +4132,9 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
4248 return -ENOMEM; 4132 return -ENOMEM;
4249 } 4133 }
4250 4134
4251 for (port = cinfo->first_line; port < cinfo->first_line + cinfo->nports; 4135 for (channel = 0, port = cinfo->first_line; channel < cinfo->nports;
4252 port++) { 4136 channel++, port++) {
4253 info = &cinfo->ports[port - cinfo->first_line]; 4137 info = &cinfo->ports[channel];
4254 tty_port_init(&info->port); 4138 tty_port_init(&info->port);
4255 info->magic = CYCLADES_MAGIC; 4139 info->magic = CYCLADES_MAGIC;
4256 info->card = cinfo; 4140 info->card = cinfo;
@@ -4263,8 +4147,17 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
4263 init_waitqueue_head(&info->delta_msr_wait); 4147 init_waitqueue_head(&info->delta_msr_wait);
4264 4148
4265 if (cy_is_Z(cinfo)) { 4149 if (cy_is_Z(cinfo)) {
4150 struct FIRM_ID *firm_id = cinfo->base_addr + ID_ADDRESS;
4151 struct ZFW_CTRL *zfw_ctrl;
4152
4266 info->port.ops = &cyz_port_ops; 4153 info->port.ops = &cyz_port_ops;
4267 info->type = PORT_STARTECH; 4154 info->type = PORT_STARTECH;
4155
4156 zfw_ctrl = cinfo->base_addr +
4157 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
4158 info->u.cyz.ch_ctrl = &zfw_ctrl->ch_ctrl[channel];
4159 info->u.cyz.buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
4160
4268 if (cinfo->hw_ver == ZO_V1) 4161 if (cinfo->hw_ver == ZO_V1)
4269 info->xmit_fifo_size = CYZ_FIFO_SIZE; 4162 info->xmit_fifo_size = CYZ_FIFO_SIZE;
4270 else 4163 else
@@ -4274,7 +4167,9 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
4274 cyz_rx_restart, (unsigned long)info); 4167 cyz_rx_restart, (unsigned long)info);
4275#endif 4168#endif
4276 } else { 4169 } else {
4170 unsigned short chip_number;
4277 int index = cinfo->bus_index; 4171 int index = cinfo->bus_index;
4172
4278 info->port.ops = &cyy_port_ops; 4173 info->port.ops = &cyy_port_ops;
4279 info->type = PORT_CIRRUS; 4174 info->type = PORT_CIRRUS;
4280 info->xmit_fifo_size = CyMAX_CHAR_FIFO; 4175 info->xmit_fifo_size = CyMAX_CHAR_FIFO;
@@ -4282,7 +4177,7 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
4282 info->cor2 = CyETC; 4177 info->cor2 = CyETC;
4283 info->cor3 = 0x08; /* _very_ small rcv threshold */ 4178 info->cor3 = 0x08; /* _very_ small rcv threshold */
4284 4179
4285 chip_number = (port - cinfo->first_line) / 4; 4180 chip_number = channel / CyPORTS_PER_CHIP;
4286 info->chip_rev = readb(cinfo->base_addr + 4181 info->chip_rev = readb(cinfo->base_addr +
4287 (cy_chip_offset[chip_number] << index) + 4182 (cy_chip_offset[chip_number] << index) +
4288 (CyGFRCR << index)); 4183 (CyGFRCR << index));
@@ -4976,8 +4871,14 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
4976 } 4871 }
4977 cy_card[card_no].num_chips = nchan / CyPORTS_PER_CHIP; 4872 cy_card[card_no].num_chips = nchan / CyPORTS_PER_CHIP;
4978 } else { 4873 } else {
4874 struct FIRM_ID __iomem *firm_id = addr2 + ID_ADDRESS;
4875 struct ZFW_CTRL __iomem *zfw_ctrl;
4876
4877 zfw_ctrl = addr2 + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
4878
4979 cy_card[card_no].hw_ver = mailbox; 4879 cy_card[card_no].hw_ver = mailbox;
4980 cy_card[card_no].num_chips = (unsigned int)-1; 4880 cy_card[card_no].num_chips = (unsigned int)-1;
4881 cy_card[card_no].board_ctrl = &zfw_ctrl->board_ctrl;
4981#ifdef CONFIG_CYZ_INTR 4882#ifdef CONFIG_CYZ_INTR
4982 /* allocate IRQ only if board has an IRQ */ 4883 /* allocate IRQ only if board has an IRQ */
4983 if (irq != 0 && irq != 255) { 4884 if (irq != 0 && irq != 255) {
diff --git a/include/linux/cyclades.h b/include/linux/cyclades.h
index 1fbdea4f08eb..1eb87a6a2f6b 100644
--- a/include/linux/cyclades.h
+++ b/include/linux/cyclades.h
@@ -499,6 +499,7 @@ struct cyclades_card {
499 void __iomem *p9050; 499 void __iomem *p9050;
500 struct RUNTIME_9060 __iomem *p9060; 500 struct RUNTIME_9060 __iomem *p9060;
501 } ctl_addr; 501 } ctl_addr;
502 struct BOARD_CTRL __iomem *board_ctrl; /* cyz specific */
502 int irq; 503 int irq;
503 unsigned int num_chips; /* 0 if card absent, -1 if Z/PCI, else Y */ 504 unsigned int num_chips; /* 0 if card absent, -1 if Z/PCI, else Y */
504 unsigned int first_line; /* minor number of first channel on card */ 505 unsigned int first_line; /* minor number of first channel on card */
@@ -541,6 +542,15 @@ struct cyclades_port {
541 int magic; 542 int magic;
542 struct tty_port port; 543 struct tty_port port;
543 struct cyclades_card *card; 544 struct cyclades_card *card;
545 union {
546 struct {
547 int filler;
548 } cyy;
549 struct {
550 struct CH_CTRL __iomem *ch_ctrl;
551 struct BUF_CTRL __iomem *buf_ctrl;
552 } cyz;
553 } u;
544 int line; 554 int line;
545 int flags; /* defined in tty.h */ 555 int flags; /* defined in tty.h */
546 int type; /* UART type */ 556 int type; /* UART type */