diff options
author | Jiri Slaby <jirislaby@gmail.com> | 2007-05-08 03:37:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:15:25 -0400 |
commit | 3137553d3f78f12a077459ee59e4b17f8db9f0cf (patch) | |
tree | 3cdcf515a191f5449030d40ab9668101f817fc81 /drivers/char/cyclades.c | |
parent | dd025c0c7a047b1be7dfaa4061368b4783d89ebb (diff) |
Char: cyclades, probe cleanup
- add fail paths
- merge 3 similar initializations into one (Z, Ze, Y)
[akpm@linux-foundation.org: build fix]
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/cyclades.c')
-rw-r--r-- | drivers/char/cyclades.c | 468 |
1 files changed, 198 insertions, 270 deletions
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 7fe4bb60f690..060011134aa0 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -4455,6 +4455,7 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo) | |||
4455 | cinfo->ports = kzalloc(sizeof(*cinfo->ports) * nports, GFP_KERNEL); | 4455 | cinfo->ports = kzalloc(sizeof(*cinfo->ports) * nports, GFP_KERNEL); |
4456 | if (cinfo->ports == NULL) { | 4456 | if (cinfo->ports == NULL) { |
4457 | printk(KERN_ERR "Cyclades: cannot allocate ports\n"); | 4457 | printk(KERN_ERR "Cyclades: cannot allocate ports\n"); |
4458 | cinfo->nports = 0; | ||
4458 | return -ENOMEM; | 4459 | return -ENOMEM; |
4459 | } | 4460 | } |
4460 | 4461 | ||
@@ -4647,9 +4648,15 @@ static int __init cy_detect_isa(void) | |||
4647 | 4648 | ||
4648 | /* probe for CD1400... */ | 4649 | /* probe for CD1400... */ |
4649 | cy_isa_address = ioremap(isa_address, CyISA_Ywin); | 4650 | cy_isa_address = ioremap(isa_address, CyISA_Ywin); |
4651 | if (cy_isa_address == NULL) { | ||
4652 | printk(KERN_ERR "Cyclom-Y/ISA: can't remap base " | ||
4653 | "address\n"); | ||
4654 | continue; | ||
4655 | } | ||
4650 | cy_isa_nchan = CyPORTS_PER_CHIP * | 4656 | cy_isa_nchan = CyPORTS_PER_CHIP * |
4651 | cyy_init_card(cy_isa_address, 0); | 4657 | cyy_init_card(cy_isa_address, 0); |
4652 | if (cy_isa_nchan == 0) { | 4658 | if (cy_isa_nchan == 0) { |
4659 | iounmap(cy_isa_address); | ||
4653 | continue; | 4660 | continue; |
4654 | } | 4661 | } |
4655 | #ifdef MODULE | 4662 | #ifdef MODULE |
@@ -4663,6 +4670,7 @@ static int __init cy_detect_isa(void) | |||
4663 | printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but the " | 4670 | printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but the " |
4664 | "IRQ could not be detected.\n", | 4671 | "IRQ could not be detected.\n", |
4665 | (unsigned long)cy_isa_address); | 4672 | (unsigned long)cy_isa_address); |
4673 | iounmap(cy_isa_address); | ||
4666 | continue; | 4674 | continue; |
4667 | } | 4675 | } |
4668 | 4676 | ||
@@ -4671,6 +4679,7 @@ static int __init cy_detect_isa(void) | |||
4671 | "more channels are available. Change NR_PORTS " | 4679 | "more channels are available. Change NR_PORTS " |
4672 | "in cyclades.c and recompile kernel.\n", | 4680 | "in cyclades.c and recompile kernel.\n", |
4673 | (unsigned long)cy_isa_address); | 4681 | (unsigned long)cy_isa_address); |
4682 | iounmap(cy_isa_address); | ||
4674 | return nboard; | 4683 | return nboard; |
4675 | } | 4684 | } |
4676 | /* fill the next cy_card structure available */ | 4685 | /* fill the next cy_card structure available */ |
@@ -4683,6 +4692,7 @@ static int __init cy_detect_isa(void) | |||
4683 | "more cards can be used. Change NR_CARDS in " | 4692 | "more cards can be used. Change NR_CARDS in " |
4684 | "cyclades.c and recompile kernel.\n", | 4693 | "cyclades.c and recompile kernel.\n", |
4685 | (unsigned long)cy_isa_address); | 4694 | (unsigned long)cy_isa_address); |
4695 | iounmap(cy_isa_address); | ||
4686 | return nboard; | 4696 | return nboard; |
4687 | } | 4697 | } |
4688 | 4698 | ||
@@ -4692,6 +4702,7 @@ static int __init cy_detect_isa(void) | |||
4692 | printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but " | 4702 | printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but " |
4693 | "could not allocate IRQ#%d.\n", | 4703 | "could not allocate IRQ#%d.\n", |
4694 | (unsigned long)cy_isa_address, cy_isa_irq); | 4704 | (unsigned long)cy_isa_address, cy_isa_irq); |
4705 | iounmap(cy_isa_address); | ||
4695 | return nboard; | 4706 | return nboard; |
4696 | } | 4707 | } |
4697 | 4708 | ||
@@ -4702,7 +4713,12 @@ static int __init cy_detect_isa(void) | |||
4702 | cy_card[j].bus_index = 0; | 4713 | cy_card[j].bus_index = 0; |
4703 | cy_card[j].first_line = cy_next_channel; | 4714 | cy_card[j].first_line = cy_next_channel; |
4704 | cy_card[j].num_chips = cy_isa_nchan / 4; | 4715 | cy_card[j].num_chips = cy_isa_nchan / 4; |
4705 | cy_init_card(&cy_card[j]); | 4716 | if (cy_init_card(&cy_card[j])) { |
4717 | cy_card[j].base_addr = NULL; | ||
4718 | free_irq(cy_isa_irq, &cy_card[j]); | ||
4719 | iounmap(cy_isa_address); | ||
4720 | continue; | ||
4721 | } | ||
4706 | nboard++; | 4722 | nboard++; |
4707 | 4723 | ||
4708 | printk(KERN_INFO "Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d found: " | 4724 | printk(KERN_INFO "Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d found: " |
@@ -4736,333 +4752,245 @@ static void __devinit plx_init(void __iomem * addr, __u32 initctl) | |||
4736 | cy_writel(addr + initctl, readl(addr + initctl) & ~0x20000000); | 4752 | cy_writel(addr + initctl, readl(addr + initctl) & ~0x20000000); |
4737 | } | 4753 | } |
4738 | 4754 | ||
4739 | static int __devinit cy_init_Ze(struct RUNTIME_9060 __iomem *cy_pci_addr0, | ||
4740 | int cy_pci_irq, struct pci_dev *pdev) | ||
4741 | { | ||
4742 | void __iomem *cy_pci_addr2; | ||
4743 | unsigned int j; | ||
4744 | unsigned short cy_pci_nchan; | ||
4745 | |||
4746 | cy_pci_addr2 = pci_iomap(pdev, 2, CyPCI_Ze_win); | ||
4747 | |||
4748 | readl(&cy_pci_addr0->mail_box_0); | ||
4749 | dev_dbg(&pdev->dev, "new Cyclades-Z board. FPGA not loaded\n"); | ||
4750 | |||
4751 | /* This must be the new Cyclades-Ze/PCI. */ | ||
4752 | cy_pci_nchan = ZE_V1_NPORTS; | ||
4753 | |||
4754 | if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) { | ||
4755 | dev_err(&pdev->dev, "Cyclades-Ze/PCI found, but no channels " | ||
4756 | "are available.\nChange NR_PORTS in cyclades.c " | ||
4757 | "and recompile kernel.\n"); | ||
4758 | return -EIO; | ||
4759 | } | ||
4760 | |||
4761 | /* fill the next cy_card structure available */ | ||
4762 | for (j = 0; j < NR_CARDS; j++) { | ||
4763 | if (cy_card[j].base_addr == NULL) | ||
4764 | break; | ||
4765 | } | ||
4766 | if (j == NR_CARDS) { /* no more cy_cards available */ | ||
4767 | dev_err(&pdev->dev, "Cyclades-Ze/PCI found, but no more " | ||
4768 | "cards can be used.\nChange NR_CARDS in " | ||
4769 | "cyclades.c and recompile kernel.\n"); | ||
4770 | return -EIO; | ||
4771 | } | ||
4772 | #ifdef CONFIG_CYZ_INTR | ||
4773 | /* allocate IRQ only if board has an IRQ */ | ||
4774 | if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) { | ||
4775 | if (request_irq(cy_pci_irq, cyz_interrupt, | ||
4776 | IRQF_SHARED, "Cyclades-Z", | ||
4777 | &cy_card[j])) { | ||
4778 | dev_err(&pdev->dev, "could not allocate IRQ.\n"); | ||
4779 | return -EIO; | ||
4780 | } | ||
4781 | } | ||
4782 | #endif /* CONFIG_CYZ_INTR */ | ||
4783 | |||
4784 | /* set cy_card */ | ||
4785 | cy_card[j].base_addr = cy_pci_addr2; | ||
4786 | cy_card[j].ctl_addr = cy_pci_addr0; | ||
4787 | cy_card[j].irq = cy_pci_irq; | ||
4788 | cy_card[j].bus_index = 1; | ||
4789 | cy_card[j].first_line = cy_next_channel; | ||
4790 | cy_card[j].num_chips = -1; | ||
4791 | cy_init_card(&cy_card[j]); | ||
4792 | pci_set_drvdata(pdev, &cy_card[j]); | ||
4793 | |||
4794 | dev_info(&pdev->dev, "Cyclades-Ze/PCI #%d found: %d channels starting " | ||
4795 | "from port %d.\n", j + 1, cy_pci_nchan, cy_next_channel); | ||
4796 | |||
4797 | for (j = cy_next_channel; j < cy_next_channel + cy_pci_nchan; j++) | ||
4798 | tty_register_device(cy_serial_driver, j, &pdev->dev); | ||
4799 | cy_next_channel += cy_pci_nchan; | ||
4800 | |||
4801 | return 0; | ||
4802 | } | ||
4803 | |||
4804 | static int __devinit cy_pci_probe(struct pci_dev *pdev, | 4755 | static int __devinit cy_pci_probe(struct pci_dev *pdev, |
4805 | const struct pci_device_id *ent) | 4756 | const struct pci_device_id *ent) |
4806 | { | 4757 | { |
4807 | unsigned char cyy_rev_id; | 4758 | void __iomem *addr0 = NULL, *addr2 = NULL; |
4808 | int cy_pci_irq; | 4759 | char *card_name = NULL; |
4809 | __u32 mailbox; | 4760 | u32 mailbox; |
4810 | void __iomem *cy_pci_addr0, *cy_pci_addr2; | 4761 | unsigned int device_id, nchan = 0, card_no, i; |
4811 | unsigned int device_id; | 4762 | unsigned char plx_ver; |
4812 | unsigned short j, cy_pci_nchan, plx_ver; | 4763 | int retval, irq; |
4813 | int retval; | ||
4814 | 4764 | ||
4815 | retval = pci_enable_device(pdev); | 4765 | retval = pci_enable_device(pdev); |
4816 | if (retval) { | 4766 | if (retval) { |
4817 | dev_err(&pdev->dev, "cannot enable device\n"); | 4767 | dev_err(&pdev->dev, "cannot enable device\n"); |
4818 | return retval; | 4768 | goto err; |
4819 | } | 4769 | } |
4820 | 4770 | ||
4821 | /* read PCI configuration area */ | 4771 | /* read PCI configuration area */ |
4822 | cy_pci_irq = pdev->irq; | 4772 | irq = pdev->irq; |
4823 | pci_read_config_byte(pdev, PCI_REVISION_ID, &cyy_rev_id); | ||
4824 | |||
4825 | device_id = pdev->device & ~PCI_DEVICE_ID_MASK; | 4773 | device_id = pdev->device & ~PCI_DEVICE_ID_MASK; |
4826 | 4774 | ||
4775 | #if defined(__alpha__) | ||
4776 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */ | ||
4777 | dev_err(&pdev->dev, "Cyclom-Y/PCI not supported for low " | ||
4778 | "addresses on Alpha systems.\n"); | ||
4779 | retval = -EIO; | ||
4780 | goto err_dis; | ||
4781 | } | ||
4782 | #endif | ||
4783 | if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) { | ||
4784 | dev_err(&pdev->dev, "Cyclades-Z/PCI not supported for low " | ||
4785 | "addresses\n"); | ||
4786 | retval = -EIO; | ||
4787 | goto err_dis; | ||
4788 | } | ||
4789 | |||
4790 | if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { | ||
4791 | dev_warn(&pdev->dev, "PCI I/O bit incorrectly set. Ignoring " | ||
4792 | "it...\n"); | ||
4793 | pdev->resource[2].flags &= ~IORESOURCE_IO; | ||
4794 | } | ||
4795 | |||
4796 | retval = pci_request_regions(pdev, "cyclades"); | ||
4797 | if (retval) { | ||
4798 | dev_err(&pdev->dev, "failed to reserve resources\n"); | ||
4799 | goto err_dis; | ||
4800 | } | ||
4801 | |||
4802 | retval = -EIO; | ||
4827 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || | 4803 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || |
4828 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { | 4804 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { |
4829 | dev_dbg(&pdev->dev, "Cyclom-Y/PCI found\n"); | 4805 | card_name = "Cyclom-Y"; |
4830 | |||
4831 | if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { | ||
4832 | dev_warn(&pdev->dev, "PCI I/O bit incorrectly " | ||
4833 | "set. Ignoring it...\n"); | ||
4834 | pdev->resource[2].flags &= ~IORESOURCE_IO; | ||
4835 | } | ||
4836 | 4806 | ||
4837 | /* Although we don't use this I/O region, we should | 4807 | addr0 = pci_iomap(pdev, 0, CyPCI_Yctl); |
4838 | request it from the kernel anyway, to avoid problems | 4808 | if (addr0 == NULL) { |
4839 | with other drivers accessing it. */ | 4809 | dev_err(&pdev->dev, "can't remap ctl region\n"); |
4840 | retval = pci_request_regions(pdev, "Cyclom-Y"); | 4810 | goto err_reg; |
4841 | if (retval) { | ||
4842 | dev_err(&pdev->dev, "failed to reserve resources\n"); | ||
4843 | return retval; | ||
4844 | } | 4811 | } |
4845 | #if defined(__alpha__) | 4812 | addr2 = pci_iomap(pdev, 2, CyPCI_Ywin); |
4846 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */ | 4813 | if (addr2 == NULL) { |
4847 | dev_err(&pdev->dev, "Cyclom-Y/PCI not supported for " | 4814 | dev_err(&pdev->dev, "can't remap base region\n"); |
4848 | "low addresses on Alpha systems.\n"); | 4815 | goto err_unmap; |
4849 | return -EIO; | ||
4850 | } | 4816 | } |
4851 | #endif | ||
4852 | cy_pci_addr0 = pci_iomap(pdev, 0, CyPCI_Yctl); | ||
4853 | cy_pci_addr2 = pci_iomap(pdev, 2, CyPCI_Ywin); | ||
4854 | |||
4855 | dev_dbg(&pdev->dev, "Cyclom-Y/PCI: relocate winaddr=0x%p " | ||
4856 | "ctladdr=0x%p\n", cy_pci_addr2, cy_pci_addr0); | ||
4857 | 4817 | ||
4858 | cy_pci_nchan = (unsigned short)(CyPORTS_PER_CHIP * | 4818 | nchan = CyPORTS_PER_CHIP * cyy_init_card(addr2, 1); |
4859 | cyy_init_card(cy_pci_addr2, 1)); | 4819 | if (nchan == 0) { |
4860 | if (cy_pci_nchan == 0) { | ||
4861 | dev_err(&pdev->dev, "Cyclom-Y PCI host card with no " | 4820 | dev_err(&pdev->dev, "Cyclom-Y PCI host card with no " |
4862 | "Serial-Modules\n"); | 4821 | "Serial-Modules\n"); |
4863 | return -EIO; | 4822 | return -EIO; |
4864 | } | 4823 | } |
4865 | if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) { | ||
4866 | dev_err(&pdev->dev, "Cyclom-Y/PCI found, but no " | ||
4867 | "channels are available. Change NR_PORTS in " | ||
4868 | "cyclades.c and recompile kernel.\n"); | ||
4869 | return -EIO; | ||
4870 | } | ||
4871 | /* fill the next cy_card structure available */ | ||
4872 | for (j = 0; j < NR_CARDS; j++) { | ||
4873 | if (cy_card[j].base_addr == NULL) | ||
4874 | break; | ||
4875 | } | ||
4876 | if (j == NR_CARDS) { /* no more cy_cards available */ | ||
4877 | dev_err(&pdev->dev, "Cyclom-Y/PCI found, but no more " | ||
4878 | "cards can be used. Change NR_CARDS in " | ||
4879 | "cyclades.c and recompile kernel.\n"); | ||
4880 | return -EIO; | ||
4881 | } | ||
4882 | |||
4883 | /* allocate IRQ */ | ||
4884 | retval = request_irq(cy_pci_irq, cyy_interrupt, | ||
4885 | IRQF_SHARED, "Cyclom-Y", &cy_card[j]); | ||
4886 | if (retval) { | ||
4887 | dev_err(&pdev->dev, "could not allocate IRQ\n"); | ||
4888 | return retval; | ||
4889 | } | ||
4890 | |||
4891 | /* set cy_card */ | ||
4892 | cy_card[j].base_addr = cy_pci_addr2; | ||
4893 | cy_card[j].ctl_addr = cy_pci_addr0; | ||
4894 | cy_card[j].irq = cy_pci_irq; | ||
4895 | cy_card[j].bus_index = 1; | ||
4896 | cy_card[j].first_line = cy_next_channel; | ||
4897 | cy_card[j].num_chips = cy_pci_nchan / 4; | ||
4898 | cy_init_card(&cy_card[j]); | ||
4899 | pci_set_drvdata(pdev, &cy_card[j]); | ||
4900 | |||
4901 | /* enable interrupts in the PCI interface */ | ||
4902 | plx_ver = readb(cy_pci_addr2 + CyPLX_VER) & 0x0f; | ||
4903 | switch (plx_ver) { | ||
4904 | case PLX_9050: | ||
4905 | |||
4906 | cy_writeb(cy_pci_addr0 + 0x4c, 0x43); | ||
4907 | break; | ||
4908 | |||
4909 | case PLX_9060: | ||
4910 | case PLX_9080: | ||
4911 | default: /* Old boards, use PLX_9060 */ | ||
4912 | |||
4913 | plx_init(cy_pci_addr0, 0x6c); | ||
4914 | /* For some yet unknown reason, once the PLX9060 reloads | ||
4915 | the EEPROM, the IRQ is lost and, thus, we have to | ||
4916 | re-write it to the PCI config. registers. | ||
4917 | This will remain here until we find a permanent | ||
4918 | fix. */ | ||
4919 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, | ||
4920 | cy_pci_irq); | ||
4921 | |||
4922 | cy_writew(cy_pci_addr0 + 0x68, | ||
4923 | readw(cy_pci_addr0 + 0x68) | 0x0900); | ||
4924 | break; | ||
4925 | } | ||
4926 | |||
4927 | dev_info(&pdev->dev, "Cyclom-Y/PCI #%d found: %d channels " | ||
4928 | "starting from port %d.\n", j + 1, cy_pci_nchan, | ||
4929 | cy_next_channel); | ||
4930 | |||
4931 | for (j = cy_next_channel; | ||
4932 | j < cy_next_channel + cy_pci_nchan; j++) | ||
4933 | tty_register_device(cy_serial_driver, j, &pdev->dev); | ||
4934 | |||
4935 | cy_next_channel += cy_pci_nchan; | ||
4936 | } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) { | ||
4937 | dev_err(&pdev->dev, "Cyclades-Z/PCI not supported for " | ||
4938 | "low addresses\n"); | ||
4939 | return -EIO; | ||
4940 | } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) { | 4824 | } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) { |
4941 | dev_dbg(&pdev->dev, "Cyclades-Z/PCI found\n"); | 4825 | struct RUNTIME_9060 __iomem *ctl_addr; |
4942 | 4826 | ||
4943 | cy_pci_addr0 = pci_iomap(pdev, 0, CyPCI_Zctl); | 4827 | ctl_addr = addr0 = pci_iomap(pdev, 0, CyPCI_Zctl); |
4828 | if (addr0 == NULL) { | ||
4829 | dev_err(&pdev->dev, "can't remap ctl region\n"); | ||
4830 | goto err_reg; | ||
4831 | } | ||
4944 | 4832 | ||
4945 | /* Disable interrupts on the PLX before resetting it */ | 4833 | /* Disable interrupts on the PLX before resetting it */ |
4946 | cy_writew(cy_pci_addr0 + 0x68, | 4834 | cy_writew(addr0 + 0x68, |
4947 | readw(cy_pci_addr0 + 0x68) & ~0x0900); | 4835 | readw(addr0 + 0x68) & ~0x0900); |
4948 | 4836 | ||
4949 | plx_init(cy_pci_addr0, 0x6c); | 4837 | plx_init(addr0, 0x6c); |
4950 | /* For some yet unknown reason, once the PLX9060 reloads | 4838 | /* For some yet unknown reason, once the PLX9060 reloads |
4951 | the EEPROM, the IRQ is lost and, thus, we have to | 4839 | the EEPROM, the IRQ is lost and, thus, we have to |
4952 | re-write it to the PCI config. registers. | 4840 | re-write it to the PCI config. registers. |
4953 | This will remain here until we find a permanent | 4841 | This will remain here until we find a permanent |
4954 | fix. */ | 4842 | fix. */ |
4955 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, cy_pci_irq); | 4843 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq); |
4956 | 4844 | ||
4957 | mailbox = (__u32)readl(&((struct RUNTIME_9060 __iomem *) | 4845 | mailbox = (u32)readl(&ctl_addr->mail_box_0); |
4958 | cy_pci_addr0)->mail_box_0); | ||
4959 | 4846 | ||
4960 | if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { | 4847 | addr2 = pci_iomap(pdev, 2, mailbox == ZE_V1 ? |
4961 | dev_warn(&pdev->dev, "PCI I/O bit incorrectly " | 4848 | CyPCI_Ze_win : CyPCI_Zwin); |
4962 | "set. Ignoring it...\n"); | 4849 | if (addr2 == NULL) { |
4963 | pdev->resource[2].flags &= ~IORESOURCE_IO; | 4850 | dev_err(&pdev->dev, "can't remap base region\n"); |
4964 | } | 4851 | goto err_unmap; |
4965 | |||
4966 | /* Although we don't use this I/O region, we should | ||
4967 | request it from the kernel anyway, to avoid problems | ||
4968 | with other drivers accessing it. */ | ||
4969 | retval = pci_request_regions(pdev, "Cyclades-Z"); | ||
4970 | if (retval) { | ||
4971 | dev_err(&pdev->dev, "failed to reserve resources\n"); | ||
4972 | return retval; | ||
4973 | } | 4852 | } |
4974 | 4853 | ||
4975 | if (mailbox == ZE_V1) { | 4854 | if (mailbox == ZE_V1) { |
4976 | retval = cy_init_Ze(cy_pci_addr0, cy_pci_irq, pdev); | 4855 | card_name = "Cyclades-Ze"; |
4977 | return retval; | 4856 | |
4857 | readl(&ctl_addr->mail_box_0); | ||
4858 | nchan = ZE_V1_NPORTS; | ||
4978 | } else { | 4859 | } else { |
4979 | cy_pci_addr2 = pci_iomap(pdev, 2, CyPCI_Zwin); | 4860 | card_name = "Cyclades-8Zo"; |
4980 | } | ||
4981 | 4861 | ||
4982 | dev_dbg(&pdev->dev, "Cyclades-Z/PCI: relocate winaddr=0x%p " | ||
4983 | "ctladdr=0x%p\n", cy_pci_addr2, cy_pci_addr0); | ||
4984 | #ifdef CY_PCI_DEBUG | 4862 | #ifdef CY_PCI_DEBUG |
4985 | if (mailbox == ZO_V1) { | 4863 | if (mailbox == ZO_V1) { |
4986 | cy_writel(&((struct RUNTIME_9060 *) | 4864 | cy_writel(&ctl_addr->loc_addr_base, WIN_CREG); |
4987 | (cy_pci_addr0))->loc_addr_base, | 4865 | dev_info(&pdev->dev, "Cyclades-8Zo/PCI: FPGA " |
4988 | WIN_CREG); | 4866 | "id %lx, ver %lx\n", (ulong)(0xff & |
4989 | dev_info(&pdev->dev, "Cyclades-8Zo/PCI: FPGA id %lx, " | 4867 | readl(&((struct CUSTOM_REG *)addr2)-> |
4990 | "ver %lx\n", (ulong)(0xff & | 4868 | fpga_id)), (ulong)(0xff & |
4991 | readl(&((struct CUSTOM_REG *) | 4869 | readl(&((struct CUSTOM_REG *)addr2)-> |
4992 | cy_pci_addr2)->fpga_id)), | 4870 | fpga_version))); |
4993 | (ulong)(0xff & readl(&((struct CUSTOM_REG *) | 4871 | cy_writel(&ctl_addr->loc_addr_base, WIN_RAM); |
4994 | cy_pci_addr2)->fpga_version))); | 4872 | } else { |
4995 | cy_writel(&((struct RUNTIME_9060 *) | 4873 | dev_info(&pdev->dev, "Cyclades-Z/PCI: New " |
4996 | cy_pci_addr0)->loc_addr_base, WIN_RAM); | 4874 | "Cyclades-Z board. FPGA not loaded\n"); |
4997 | } else { | 4875 | } |
4998 | dev_info(&pdev->dev, "Cyclades-Z/PCI: New Cyclades-Z " | ||
4999 | "board. FPGA not loaded\n"); | ||
5000 | } | ||
5001 | #endif | 4876 | #endif |
5002 | /* The following clears the firmware id word. This | 4877 | /* The following clears the firmware id word. This |
5003 | ensures that the driver will not attempt to talk to | 4878 | ensures that the driver will not attempt to talk to |
5004 | the board until it has been properly initialized. | 4879 | the board until it has been properly initialized. |
5005 | */ | 4880 | */ |
5006 | if ((mailbox == ZO_V1) || (mailbox == ZO_V2)) | 4881 | if ((mailbox == ZO_V1) || (mailbox == ZO_V2)) |
5007 | cy_writel(cy_pci_addr2 + ID_ADDRESS, 0L); | 4882 | cy_writel(addr2 + ID_ADDRESS, 0L); |
5008 | |||
5009 | /* This must be a Cyclades-8Zo/PCI. The extendable | ||
5010 | version will have a different device_id and will | ||
5011 | be allocated its maximum number of ports. */ | ||
5012 | cy_pci_nchan = 8; | ||
5013 | |||
5014 | if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) { | ||
5015 | dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no " | ||
5016 | "channels are available. Change NR_PORTS in " | ||
5017 | "cyclades.c and recompile kernel.\n"); | ||
5018 | return -EIO; | ||
5019 | } | ||
5020 | 4883 | ||
5021 | /* fill the next cy_card structure available */ | 4884 | /* This must be a Cyclades-8Zo/PCI. The extendable |
5022 | for (j = 0; j < NR_CARDS; j++) { | 4885 | version will have a different device_id and will |
5023 | if (cy_card[j].base_addr == NULL) | 4886 | be allocated its maximum number of ports. */ |
5024 | break; | 4887 | nchan = 8; |
5025 | } | 4888 | } |
5026 | if (j == NR_CARDS) { /* no more cy_cards available */ | 4889 | } |
5027 | dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no " | 4890 | |
5028 | "more cards can be used. Change NR_CARDS in " | 4891 | if ((cy_next_channel + nchan) > NR_PORTS) { |
5029 | "cyclades.c and recompile kernel.\n"); | 4892 | dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no " |
5030 | return -EIO; | 4893 | "channels are available. Change NR_PORTS in " |
4894 | "cyclades.c and recompile kernel.\n"); | ||
4895 | goto err_unmap; | ||
4896 | } | ||
4897 | /* fill the next cy_card structure available */ | ||
4898 | for (card_no = 0; card_no < NR_CARDS; card_no++) { | ||
4899 | if (cy_card[card_no].base_addr == NULL) | ||
4900 | break; | ||
4901 | } | ||
4902 | if (card_no == NR_CARDS) { /* no more cy_cards available */ | ||
4903 | dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no " | ||
4904 | "more cards can be used. Change NR_CARDS in " | ||
4905 | "cyclades.c and recompile kernel.\n"); | ||
4906 | goto err_unmap; | ||
4907 | } | ||
4908 | |||
4909 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || | ||
4910 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { | ||
4911 | /* allocate IRQ */ | ||
4912 | retval = request_irq(irq, cyy_interrupt, | ||
4913 | IRQF_SHARED, "Cyclom-Y", &cy_card[card_no]); | ||
4914 | if (retval) { | ||
4915 | dev_err(&pdev->dev, "could not allocate IRQ\n"); | ||
4916 | goto err_unmap; | ||
5031 | } | 4917 | } |
4918 | cy_card[card_no].num_chips = nchan / 4; | ||
4919 | } else { | ||
5032 | #ifdef CONFIG_CYZ_INTR | 4920 | #ifdef CONFIG_CYZ_INTR |
5033 | /* allocate IRQ only if board has an IRQ */ | 4921 | /* allocate IRQ only if board has an IRQ */ |
5034 | if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) { | 4922 | if (irq != 0 && irq != 255) { |
5035 | retval = request_irq(cy_pci_irq, cyz_interrupt, | 4923 | retval = request_irq(irq, cyz_interrupt, |
5036 | IRQF_SHARED, "Cyclades-Z", | 4924 | IRQF_SHARED, "Cyclades-Z", |
5037 | &cy_card[j]); | 4925 | &cy_card[card_no]); |
5038 | if (retval) { | 4926 | if (retval) { |
5039 | dev_err(&pdev->dev, "could not allocate IRQ\n"); | 4927 | dev_err(&pdev->dev, "could not allocate IRQ\n"); |
5040 | return retval; | 4928 | goto err_unmap; |
5041 | } | 4929 | } |
5042 | } | 4930 | } |
5043 | #endif /* CONFIG_CYZ_INTR */ | 4931 | #endif /* CONFIG_CYZ_INTR */ |
4932 | cy_card[card_no].num_chips = -1; | ||
4933 | } | ||
5044 | 4934 | ||
5045 | /* set cy_card */ | 4935 | /* set cy_card */ |
5046 | cy_card[j].base_addr = cy_pci_addr2; | 4936 | cy_card[card_no].base_addr = addr2; |
5047 | cy_card[j].ctl_addr = cy_pci_addr0; | 4937 | cy_card[card_no].ctl_addr = addr0; |
5048 | cy_card[j].irq = cy_pci_irq; | 4938 | cy_card[card_no].irq = irq; |
5049 | cy_card[j].bus_index = 1; | 4939 | cy_card[card_no].bus_index = 1; |
5050 | cy_card[j].first_line = cy_next_channel; | 4940 | cy_card[card_no].first_line = cy_next_channel; |
5051 | cy_card[j].num_chips = -1; | 4941 | retval = cy_init_card(&cy_card[card_no]); |
5052 | cy_init_card(&cy_card[j]); | 4942 | if (retval) |
5053 | pci_set_drvdata(pdev, &cy_card[j]); | 4943 | goto err_null; |
5054 | 4944 | ||
5055 | dev_info(&pdev->dev, "Cyclades-8Zo/PCI #%d found: %d channels " | 4945 | pci_set_drvdata(pdev, &cy_card[card_no]); |
5056 | "starting from port %d.\n", j + 1, cy_pci_nchan, | ||
5057 | cy_next_channel); | ||
5058 | 4946 | ||
5059 | for (j = cy_next_channel; | 4947 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || |
5060 | j < cy_next_channel + cy_pci_nchan; j++) | 4948 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { |
5061 | tty_register_device(cy_serial_driver, j, &pdev->dev); | 4949 | /* enable interrupts in the PCI interface */ |
5062 | cy_next_channel += cy_pci_nchan; | 4950 | plx_ver = readb(addr2 + CyPLX_VER) & 0x0f; |
4951 | switch (plx_ver) { | ||
4952 | case PLX_9050: | ||
4953 | |||
4954 | cy_writeb(addr0 + 0x4c, 0x43); | ||
4955 | break; | ||
4956 | |||
4957 | case PLX_9060: | ||
4958 | case PLX_9080: | ||
4959 | default: /* Old boards, use PLX_9060 */ | ||
4960 | |||
4961 | plx_init(addr0, 0x6c); | ||
4962 | /* For some yet unknown reason, once the PLX9060 reloads | ||
4963 | the EEPROM, the IRQ is lost and, thus, we have to | ||
4964 | re-write it to the PCI config. registers. | ||
4965 | This will remain here until we find a permanent | ||
4966 | fix. */ | ||
4967 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq); | ||
4968 | |||
4969 | cy_writew(addr0 + 0x68, readw(addr0 + 0x68) | 0x0900); | ||
4970 | break; | ||
4971 | } | ||
5063 | } | 4972 | } |
5064 | 4973 | ||
4974 | dev_info(&pdev->dev, "%s/PCI #%d found: %d channels starting from " | ||
4975 | "port %d.\n", card_name, card_no + 1, nchan, cy_next_channel); | ||
4976 | for (i = cy_next_channel; i < cy_next_channel + nchan; i++) | ||
4977 | tty_register_device(cy_serial_driver, i, &pdev->dev); | ||
4978 | cy_next_channel += nchan; | ||
4979 | |||
5065 | return 0; | 4980 | return 0; |
4981 | err_null: | ||
4982 | cy_card[card_no].base_addr = NULL; | ||
4983 | free_irq(irq, &cy_card[card_no]); | ||
4984 | err_unmap: | ||
4985 | pci_iounmap(pdev, addr0); | ||
4986 | if (addr2) | ||
4987 | pci_iounmap(pdev, addr2); | ||
4988 | err_reg: | ||
4989 | pci_release_regions(pdev); | ||
4990 | err_dis: | ||
4991 | pci_disable_device(pdev); | ||
4992 | err: | ||
4993 | return retval; | ||
5066 | } | 4994 | } |
5067 | 4995 | ||
5068 | static void __devexit cy_pci_remove(struct pci_dev *pdev) | 4996 | static void __devexit cy_pci_remove(struct pci_dev *pdev) |