aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2009-06-11 07:34:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-11 11:50:57 -0400
commit963118eef9e6706e2b5356309fb0cdd9c9eba81d (patch)
tree1c16bc97bf515cf641d17478f7e335f45ba51e24 /drivers
parent08a951e1693e324bd035b194002a82b9057fd9c5 (diff)
tty: cyclades, fix nports handling
Set up ports right after FW load so that we won't allocate maximal (64) ports when we use few. Also remove reading of nports in irq context, since we know it from initialisation now. This also fixes a tty ports unregistration on some fail paths and for Ze which registered 64 and unregistered real port count. Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/cyclades.c58
1 files changed, 17 insertions, 41 deletions
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index c9a503f4724a..6adbc9759661 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -604,7 +604,6 @@
604 604
605#define NR_PORTS 256 605#define NR_PORTS 256
606 606
607#define ZE_V1_NPORTS 64
608#define ZO_V1 0 607#define ZO_V1 0
609#define ZO_V2 1 608#define ZO_V2 1
610#define ZE_V1 2 609#define ZE_V1 2
@@ -1777,7 +1776,6 @@ static void cyz_poll(unsigned long arg)
1777 struct tty_struct *tty; 1776 struct tty_struct *tty;
1778 struct FIRM_ID __iomem *firm_id; 1777 struct FIRM_ID __iomem *firm_id;
1779 struct ZFW_CTRL __iomem *zfw_ctrl; 1778 struct ZFW_CTRL __iomem *zfw_ctrl;
1780 struct BOARD_CTRL __iomem *board_ctrl;
1781 struct BUF_CTRL __iomem *buf_ctrl; 1779 struct BUF_CTRL __iomem *buf_ctrl;
1782 unsigned long expires = jiffies + HZ; 1780 unsigned long expires = jiffies + HZ;
1783 unsigned int port, card; 1781 unsigned int port, card;
@@ -1793,11 +1791,9 @@ static void cyz_poll(unsigned long arg)
1793 firm_id = cinfo->base_addr + ID_ADDRESS; 1791 firm_id = cinfo->base_addr + ID_ADDRESS;
1794 zfw_ctrl = cinfo->base_addr + 1792 zfw_ctrl = cinfo->base_addr +
1795 (readl(&firm_id->zfwctrl_addr) & 0xfffff); 1793 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
1796 board_ctrl = &(zfw_ctrl->board_ctrl);
1797 1794
1798 /* Skip first polling cycle to avoid racing conditions with the FW */ 1795 /* Skip first polling cycle to avoid racing conditions with the FW */
1799 if (!cinfo->intr_enabled) { 1796 if (!cinfo->intr_enabled) {
1800 cinfo->nports = (int)readl(&board_ctrl->n_channel);
1801 cinfo->intr_enabled = 1; 1797 cinfo->intr_enabled = 1;
1802 continue; 1798 continue;
1803 } 1799 }
@@ -2413,16 +2409,8 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
2413 interrupts should be enabled as soon as the first open 2409 interrupts should be enabled as soon as the first open
2414 happens to one of its ports. */ 2410 happens to one of its ports. */
2415 if (!cinfo->intr_enabled) { 2411 if (!cinfo->intr_enabled) {
2416 struct ZFW_CTRL __iomem *zfw_ctrl;
2417 struct BOARD_CTRL __iomem *board_ctrl;
2418 u16 intr; 2412 u16 intr;
2419 2413
2420 zfw_ctrl = cinfo->base_addr +
2421 (readl(&firm_id->zfwctrl_addr) &
2422 0xfffff);
2423
2424 board_ctrl = &zfw_ctrl->board_ctrl;
2425
2426 /* Enable interrupts on the PLX chip */ 2414 /* Enable interrupts on the PLX chip */
2427 intr = readw(&cinfo->ctl_addr.p9060-> 2415 intr = readw(&cinfo->ctl_addr.p9060->
2428 intr_ctrl_stat) | 0x0900; 2416 intr_ctrl_stat) | 0x0900;
@@ -2435,8 +2423,6 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
2435 printk(KERN_ERR "cyc:IRQ enable retval " 2423 printk(KERN_ERR "cyc:IRQ enable retval "
2436 "was %x\n", retval); 2424 "was %x\n", retval);
2437 } 2425 }
2438 cinfo->nports =
2439 (int)readl(&board_ctrl->n_channel);
2440 cinfo->intr_enabled = 1; 2426 cinfo->intr_enabled = 1;
2441 } 2427 }
2442 } 2428 }
@@ -4340,30 +4326,20 @@ static void cy_hangup(struct tty_struct *tty)
4340static int __devinit cy_init_card(struct cyclades_card *cinfo) 4326static int __devinit cy_init_card(struct cyclades_card *cinfo)
4341{ 4327{
4342 struct cyclades_port *info; 4328 struct cyclades_port *info;
4343 unsigned int nports, port; 4329 unsigned int port;
4344 unsigned short chip_number; 4330 unsigned short chip_number;
4345 int uninitialized_var(index);
4346 4331
4347 spin_lock_init(&cinfo->card_lock); 4332 spin_lock_init(&cinfo->card_lock);
4333 cinfo->intr_enabled = 0;
4348 4334
4349 if (cy_is_Z(cinfo)) { /* Cyclades-Z */ 4335 cinfo->ports = kcalloc(cinfo->nports, sizeof(*cinfo->ports),
4350 nports = (cinfo->hw_ver == ZE_V1) ? ZE_V1_NPORTS : 8; 4336 GFP_KERNEL);
4351 cinfo->intr_enabled = 0;
4352 cinfo->nports = 0; /* Will be correctly set later, after
4353 Z FW is loaded */
4354 } else {
4355 index = cinfo->bus_index;
4356 nports = cinfo->nports = CyPORTS_PER_CHIP * cinfo->num_chips;
4357 }
4358
4359 cinfo->ports = kzalloc(sizeof(*cinfo->ports) * nports, GFP_KERNEL);
4360 if (cinfo->ports == NULL) { 4337 if (cinfo->ports == NULL) {
4361 printk(KERN_ERR "Cyclades: cannot allocate ports\n"); 4338 printk(KERN_ERR "Cyclades: cannot allocate ports\n");
4362 cinfo->nports = 0;
4363 return -ENOMEM; 4339 return -ENOMEM;
4364 } 4340 }
4365 4341
4366 for (port = cinfo->first_line; port < cinfo->first_line + nports; 4342 for (port = cinfo->first_line; port < cinfo->first_line + cinfo->nports;
4367 port++) { 4343 port++) {
4368 info = &cinfo->ports[port - cinfo->first_line]; 4344 info = &cinfo->ports[port - cinfo->first_line];
4369 tty_port_init(&info->port); 4345 tty_port_init(&info->port);
@@ -4388,6 +4364,7 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
4388 cyz_rx_restart, (unsigned long)info); 4364 cyz_rx_restart, (unsigned long)info);
4389#endif 4365#endif
4390 } else { 4366 } else {
4367 int index = cinfo->bus_index;
4391 info->type = PORT_CIRRUS; 4368 info->type = PORT_CIRRUS;
4392 info->xmit_fifo_size = CyMAX_CHAR_FIFO; 4369 info->xmit_fifo_size = CyMAX_CHAR_FIFO;
4393 info->cor1 = CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS; 4370 info->cor1 = CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS;
@@ -4615,7 +4592,8 @@ static int __init cy_detect_isa(void)
4615 cy_card[j].irq = (int)cy_isa_irq; 4592 cy_card[j].irq = (int)cy_isa_irq;
4616 cy_card[j].bus_index = 0; 4593 cy_card[j].bus_index = 0;
4617 cy_card[j].first_line = cy_next_channel; 4594 cy_card[j].first_line = cy_next_channel;
4618 cy_card[j].num_chips = cy_isa_nchan / 4; 4595 cy_card[j].num_chips = cy_isa_nchan / CyPORTS_PER_CHIP;
4596 cy_card[j].nports = cy_isa_nchan;
4619 if (cy_init_card(&cy_card[j])) { 4597 if (cy_init_card(&cy_card[j])) {
4620 cy_card[j].base_addr = NULL; 4598 cy_card[j].base_addr = NULL;
4621 free_irq(cy_isa_irq, &cy_card[j]); 4599 free_irq(cy_isa_irq, &cy_card[j]);
@@ -4771,7 +4749,7 @@ static int __devinit cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr,
4771 struct CUSTOM_REG __iomem *cust = base_addr; 4749 struct CUSTOM_REG __iomem *cust = base_addr;
4772 struct ZFW_CTRL __iomem *pt_zfwctrl; 4750 struct ZFW_CTRL __iomem *pt_zfwctrl;
4773 void __iomem *tmp; 4751 void __iomem *tmp;
4774 u32 mailbox, status; 4752 u32 mailbox, status, nchan;
4775 unsigned int i; 4753 unsigned int i;
4776 int retval; 4754 int retval;
4777 4755
@@ -4892,11 +4870,11 @@ static int __devinit cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr,
4892 base_addr + ID_ADDRESS, readl(&fid->zfwctrl_addr), 4870 base_addr + ID_ADDRESS, readl(&fid->zfwctrl_addr),
4893 base_addr + readl(&fid->zfwctrl_addr)); 4871 base_addr + readl(&fid->zfwctrl_addr));
4894 4872
4873 nchan = readl(&pt_zfwctrl->board_ctrl.n_channel);
4895 dev_info(&pdev->dev, "Cyclades-Z FW loaded: version = %x, ports = %u\n", 4874 dev_info(&pdev->dev, "Cyclades-Z FW loaded: version = %x, ports = %u\n",
4896 readl(&pt_zfwctrl->board_ctrl.fw_version), 4875 readl(&pt_zfwctrl->board_ctrl.fw_version), nchan);
4897 readl(&pt_zfwctrl->board_ctrl.n_channel));
4898 4876
4899 if (readl(&pt_zfwctrl->board_ctrl.n_channel) == 0) { 4877 if (nchan == 0) {
4900 dev_warn(&pdev->dev, "no Cyclades-Z ports were found. Please " 4878 dev_warn(&pdev->dev, "no Cyclades-Z ports were found. Please "
4901 "check the connection between the Z host card and the " 4879 "check the connection between the Z host card and the "
4902 "serial expanders.\n"); 4880 "serial expanders.\n");
@@ -4922,7 +4900,7 @@ static int __devinit cyz_load_fw(struct pci_dev *pdev, void __iomem *base_addr,
4922 cy_writel(&ctl_addr->intr_ctrl_stat, readl(&ctl_addr->intr_ctrl_stat) | 4900 cy_writel(&ctl_addr->intr_ctrl_stat, readl(&ctl_addr->intr_ctrl_stat) |
4923 0x00030800UL); 4901 0x00030800UL);
4924 4902
4925 return 0; 4903 return nchan;
4926err_rel: 4904err_rel:
4927 release_firmware(fw); 4905 release_firmware(fw);
4928err: 4906err:
@@ -5027,12 +5005,8 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
5027 5005
5028 if (mailbox == ZE_V1) { 5006 if (mailbox == ZE_V1) {
5029 card_name = "Cyclades-Ze"; 5007 card_name = "Cyclades-Ze";
5030
5031 nchan = ZE_V1_NPORTS;
5032 } else { 5008 } else {
5033 card_name = "Cyclades-8Zo"; 5009 card_name = "Cyclades-8Zo";
5034 nchan = 8;
5035
5036#ifdef CY_PCI_DEBUG 5010#ifdef CY_PCI_DEBUG
5037 if (mailbox == ZO_V1) { 5011 if (mailbox == ZO_V1) {
5038 cy_writel(&ctl_addr->loc_addr_base, WIN_CREG); 5012 cy_writel(&ctl_addr->loc_addr_base, WIN_CREG);
@@ -5057,8 +5031,9 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
5057 } 5031 }
5058 5032
5059 retval = cyz_load_fw(pdev, addr2, addr0, irq); 5033 retval = cyz_load_fw(pdev, addr2, addr0, irq);
5060 if (retval) 5034 if (retval <= 0)
5061 goto err_unmap; 5035 goto err_unmap;
5036 nchan = retval;
5062 } 5037 }
5063 5038
5064 if ((cy_next_channel + nchan) > NR_PORTS) { 5039 if ((cy_next_channel + nchan) > NR_PORTS) {
@@ -5088,7 +5063,7 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
5088 dev_err(&pdev->dev, "could not allocate IRQ\n"); 5063 dev_err(&pdev->dev, "could not allocate IRQ\n");
5089 goto err_unmap; 5064 goto err_unmap;
5090 } 5065 }
5091 cy_card[card_no].num_chips = nchan / 4; 5066 cy_card[card_no].num_chips = nchan / CyPORTS_PER_CHIP;
5092 } else { 5067 } else {
5093 cy_card[card_no].hw_ver = mailbox; 5068 cy_card[card_no].hw_ver = mailbox;
5094 cy_card[card_no].num_chips = (unsigned int)-1; 5069 cy_card[card_no].num_chips = (unsigned int)-1;
@@ -5112,6 +5087,7 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
5112 cy_card[card_no].irq = irq; 5087 cy_card[card_no].irq = irq;
5113 cy_card[card_no].bus_index = 1; 5088 cy_card[card_no].bus_index = 1;
5114 cy_card[card_no].first_line = cy_next_channel; 5089 cy_card[card_no].first_line = cy_next_channel;
5090 cy_card[card_no].nports = nchan;
5115 retval = cy_init_card(&cy_card[card_no]); 5091 retval = cy_init_card(&cy_card[card_no]);
5116 if (retval) 5092 if (retval)
5117 goto err_null; 5093 goto err_null;