diff options
Diffstat (limited to 'drivers/serial/8250_pci.c')
-rw-r--r-- | drivers/serial/8250_pci.c | 134 |
1 files changed, 78 insertions, 56 deletions
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 5450a0e5ecdb..c088146b7513 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
@@ -42,7 +42,8 @@ struct pci_serial_quirk { | |||
42 | u32 subvendor; | 42 | u32 subvendor; |
43 | u32 subdevice; | 43 | u32 subdevice; |
44 | int (*init)(struct pci_dev *dev); | 44 | int (*init)(struct pci_dev *dev); |
45 | int (*setup)(struct serial_private *, struct pciserial_board *, | 45 | int (*setup)(struct serial_private *, |
46 | const struct pciserial_board *, | ||
46 | struct uart_port *, int); | 47 | struct uart_port *, int); |
47 | void (*exit)(struct pci_dev *dev); | 48 | void (*exit)(struct pci_dev *dev); |
48 | }; | 49 | }; |
@@ -107,7 +108,7 @@ setup_port(struct serial_private *priv, struct uart_port *port, | |||
107 | * ADDI-DATA GmbH communication cards <info@addi-data.com> | 108 | * ADDI-DATA GmbH communication cards <info@addi-data.com> |
108 | */ | 109 | */ |
109 | static int addidata_apci7800_setup(struct serial_private *priv, | 110 | static int addidata_apci7800_setup(struct serial_private *priv, |
110 | struct pciserial_board *board, | 111 | const struct pciserial_board *board, |
111 | struct uart_port *port, int idx) | 112 | struct uart_port *port, int idx) |
112 | { | 113 | { |
113 | unsigned int bar = 0, offset = board->first_offset; | 114 | unsigned int bar = 0, offset = board->first_offset; |
@@ -134,7 +135,7 @@ static int addidata_apci7800_setup(struct serial_private *priv, | |||
134 | * Not that ugly ;) -- HW | 135 | * Not that ugly ;) -- HW |
135 | */ | 136 | */ |
136 | static int | 137 | static int |
137 | afavlab_setup(struct serial_private *priv, struct pciserial_board *board, | 138 | afavlab_setup(struct serial_private *priv, const struct pciserial_board *board, |
138 | struct uart_port *port, int idx) | 139 | struct uart_port *port, int idx) |
139 | { | 140 | { |
140 | unsigned int bar, offset = board->first_offset; | 141 | unsigned int bar, offset = board->first_offset; |
@@ -188,8 +189,9 @@ static int pci_hp_diva_init(struct pci_dev *dev) | |||
188 | * some serial ports are supposed to be hidden on certain models. | 189 | * some serial ports are supposed to be hidden on certain models. |
189 | */ | 190 | */ |
190 | static int | 191 | static int |
191 | pci_hp_diva_setup(struct serial_private *priv, struct pciserial_board *board, | 192 | pci_hp_diva_setup(struct serial_private *priv, |
192 | struct uart_port *port, int idx) | 193 | const struct pciserial_board *board, |
194 | struct uart_port *port, int idx) | ||
193 | { | 195 | { |
194 | unsigned int offset = board->first_offset; | 196 | unsigned int offset = board->first_offset; |
195 | unsigned int bar = FL_GET_BASE(board->flags); | 197 | unsigned int bar = FL_GET_BASE(board->flags); |
@@ -306,7 +308,7 @@ static void __devexit pci_plx9050_exit(struct pci_dev *dev) | |||
306 | 308 | ||
307 | /* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */ | 309 | /* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */ |
308 | static int | 310 | static int |
309 | sbs_setup(struct serial_private *priv, struct pciserial_board *board, | 311 | sbs_setup(struct serial_private *priv, const struct pciserial_board *board, |
310 | struct uart_port *port, int idx) | 312 | struct uart_port *port, int idx) |
311 | { | 313 | { |
312 | unsigned int bar, offset = board->first_offset; | 314 | unsigned int bar, offset = board->first_offset; |
@@ -463,7 +465,7 @@ static int pci_siig_init(struct pci_dev *dev) | |||
463 | } | 465 | } |
464 | 466 | ||
465 | static int pci_siig_setup(struct serial_private *priv, | 467 | static int pci_siig_setup(struct serial_private *priv, |
466 | struct pciserial_board *board, | 468 | const struct pciserial_board *board, |
467 | struct uart_port *port, int idx) | 469 | struct uart_port *port, int idx) |
468 | { | 470 | { |
469 | unsigned int bar = FL_GET_BASE(board->flags) + idx, offset = 0; | 471 | unsigned int bar = FL_GET_BASE(board->flags) + idx, offset = 0; |
@@ -534,7 +536,8 @@ static int pci_timedia_init(struct pci_dev *dev) | |||
534 | * Ugh, this is ugly as all hell --- TYT | 536 | * Ugh, this is ugly as all hell --- TYT |
535 | */ | 537 | */ |
536 | static int | 538 | static int |
537 | pci_timedia_setup(struct serial_private *priv, struct pciserial_board *board, | 539 | pci_timedia_setup(struct serial_private *priv, |
540 | const struct pciserial_board *board, | ||
538 | struct uart_port *port, int idx) | 541 | struct uart_port *port, int idx) |
539 | { | 542 | { |
540 | unsigned int bar = 0, offset = board->first_offset; | 543 | unsigned int bar = 0, offset = board->first_offset; |
@@ -568,7 +571,7 @@ pci_timedia_setup(struct serial_private *priv, struct pciserial_board *board, | |||
568 | */ | 571 | */ |
569 | static int | 572 | static int |
570 | titan_400l_800l_setup(struct serial_private *priv, | 573 | titan_400l_800l_setup(struct serial_private *priv, |
571 | struct pciserial_board *board, | 574 | const struct pciserial_board *board, |
572 | struct uart_port *port, int idx) | 575 | struct uart_port *port, int idx) |
573 | { | 576 | { |
574 | unsigned int bar, offset = board->first_offset; | 577 | unsigned int bar, offset = board->first_offset; |
@@ -737,8 +740,41 @@ static void __devexit pci_ite887x_exit(struct pci_dev *dev) | |||
737 | release_region(ioport, ITE_887x_IOSIZE); | 740 | release_region(ioport, ITE_887x_IOSIZE); |
738 | } | 741 | } |
739 | 742 | ||
743 | /* | ||
744 | * Oxford Semiconductor Inc. | ||
745 | * Check that device is part of the Tornado range of devices, then determine | ||
746 | * the number of ports available on the device. | ||
747 | */ | ||
748 | static int pci_oxsemi_tornado_init(struct pci_dev *dev) | ||
749 | { | ||
750 | u8 __iomem *p; | ||
751 | unsigned long deviceID; | ||
752 | unsigned int number_uarts = 0; | ||
753 | |||
754 | /* OxSemi Tornado devices are all 0xCxxx */ | ||
755 | if (dev->vendor == PCI_VENDOR_ID_OXSEMI && | ||
756 | (dev->device & 0xF000) != 0xC000) | ||
757 | return 0; | ||
758 | |||
759 | p = pci_iomap(dev, 0, 5); | ||
760 | if (p == NULL) | ||
761 | return -ENOMEM; | ||
762 | |||
763 | deviceID = ioread32(p); | ||
764 | /* Tornado device */ | ||
765 | if (deviceID == 0x07000200) { | ||
766 | number_uarts = ioread8(p + 4); | ||
767 | printk(KERN_DEBUG | ||
768 | "%d ports detected on Oxford PCI Express device\n", | ||
769 | number_uarts); | ||
770 | } | ||
771 | pci_iounmap(dev, p); | ||
772 | return number_uarts; | ||
773 | } | ||
774 | |||
740 | static int | 775 | static int |
741 | pci_default_setup(struct serial_private *priv, struct pciserial_board *board, | 776 | pci_default_setup(struct serial_private *priv, |
777 | const struct pciserial_board *board, | ||
742 | struct uart_port *port, int idx) | 778 | struct uart_port *port, int idx) |
743 | { | 779 | { |
744 | unsigned int bar, offset = board->first_offset, maxnr; | 780 | unsigned int bar, offset = board->first_offset, maxnr; |
@@ -1018,6 +1054,25 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1018 | .setup = pci_default_setup, | 1054 | .setup = pci_default_setup, |
1019 | }, | 1055 | }, |
1020 | /* | 1056 | /* |
1057 | * For Oxford Semiconductor and Mainpine | ||
1058 | */ | ||
1059 | { | ||
1060 | .vendor = PCI_VENDOR_ID_OXSEMI, | ||
1061 | .device = PCI_ANY_ID, | ||
1062 | .subvendor = PCI_ANY_ID, | ||
1063 | .subdevice = PCI_ANY_ID, | ||
1064 | .init = pci_oxsemi_tornado_init, | ||
1065 | .setup = pci_default_setup, | ||
1066 | }, | ||
1067 | { | ||
1068 | .vendor = PCI_VENDOR_ID_MAINPINE, | ||
1069 | .device = PCI_ANY_ID, | ||
1070 | .subvendor = PCI_ANY_ID, | ||
1071 | .subdevice = PCI_ANY_ID, | ||
1072 | .init = pci_oxsemi_tornado_init, | ||
1073 | .setup = pci_default_setup, | ||
1074 | }, | ||
1075 | /* | ||
1021 | * Default "match everything" terminator entry | 1076 | * Default "match everything" terminator entry |
1022 | */ | 1077 | */ |
1023 | { | 1078 | { |
@@ -1048,7 +1103,7 @@ static struct pci_serial_quirk *find_quirk(struct pci_dev *dev) | |||
1048 | } | 1103 | } |
1049 | 1104 | ||
1050 | static inline int get_pci_irq(struct pci_dev *dev, | 1105 | static inline int get_pci_irq(struct pci_dev *dev, |
1051 | struct pciserial_board *board) | 1106 | const struct pciserial_board *board) |
1052 | { | 1107 | { |
1053 | if (board->flags & FL_NOIRQ) | 1108 | if (board->flags & FL_NOIRQ) |
1054 | return 0; | 1109 | return 0; |
@@ -1843,8 +1898,8 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) | |||
1843 | } | 1898 | } |
1844 | 1899 | ||
1845 | static inline int | 1900 | static inline int |
1846 | serial_pci_matches(struct pciserial_board *board, | 1901 | serial_pci_matches(const struct pciserial_board *board, |
1847 | struct pciserial_board *guessed) | 1902 | const struct pciserial_board *guessed) |
1848 | { | 1903 | { |
1849 | return | 1904 | return |
1850 | board->num_ports == guessed->num_ports && | 1905 | board->num_ports == guessed->num_ports && |
@@ -1854,54 +1909,14 @@ serial_pci_matches(struct pciserial_board *board, | |||
1854 | board->first_offset == guessed->first_offset; | 1909 | board->first_offset == guessed->first_offset; |
1855 | } | 1910 | } |
1856 | 1911 | ||
1857 | /* | ||
1858 | * Oxford Semiconductor Inc. | ||
1859 | * Check that device is part of the Tornado range of devices, then determine | ||
1860 | * the number of ports available on the device. | ||
1861 | */ | ||
1862 | static int pci_oxsemi_tornado_init(struct pci_dev *dev, struct pciserial_board *board) | ||
1863 | { | ||
1864 | u8 __iomem *p; | ||
1865 | unsigned long deviceID; | ||
1866 | unsigned int number_uarts; | ||
1867 | |||
1868 | /* OxSemi Tornado devices are all 0xCxxx */ | ||
1869 | if (dev->vendor == PCI_VENDOR_ID_OXSEMI && | ||
1870 | (dev->device & 0xF000) != 0xC000) | ||
1871 | return 0; | ||
1872 | |||
1873 | p = pci_iomap(dev, 0, 5); | ||
1874 | if (p == NULL) | ||
1875 | return -ENOMEM; | ||
1876 | |||
1877 | deviceID = ioread32(p); | ||
1878 | /* Tornado device */ | ||
1879 | if (deviceID == 0x07000200) { | ||
1880 | number_uarts = ioread8(p + 4); | ||
1881 | board->num_ports = number_uarts; | ||
1882 | printk(KERN_DEBUG | ||
1883 | "%d ports detected on Oxford PCI Express device\n", | ||
1884 | number_uarts); | ||
1885 | } | ||
1886 | pci_iounmap(dev, p); | ||
1887 | return 0; | ||
1888 | } | ||
1889 | |||
1890 | struct serial_private * | 1912 | struct serial_private * |
1891 | pciserial_init_ports(struct pci_dev *dev, struct pciserial_board *board) | 1913 | pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board) |
1892 | { | 1914 | { |
1893 | struct uart_port serial_port; | 1915 | struct uart_port serial_port; |
1894 | struct serial_private *priv; | 1916 | struct serial_private *priv; |
1895 | struct pci_serial_quirk *quirk; | 1917 | struct pci_serial_quirk *quirk; |
1896 | int rc, nr_ports, i; | 1918 | int rc, nr_ports, i; |
1897 | 1919 | ||
1898 | /* | ||
1899 | * Find number of ports on board | ||
1900 | */ | ||
1901 | if (dev->vendor == PCI_VENDOR_ID_OXSEMI || | ||
1902 | dev->vendor == PCI_VENDOR_ID_MAINPINE) | ||
1903 | pci_oxsemi_tornado_init(dev, board); | ||
1904 | |||
1905 | nr_ports = board->num_ports; | 1920 | nr_ports = board->num_ports; |
1906 | 1921 | ||
1907 | /* | 1922 | /* |
@@ -2028,7 +2043,8 @@ static int __devinit | |||
2028 | pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) | 2043 | pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) |
2029 | { | 2044 | { |
2030 | struct serial_private *priv; | 2045 | struct serial_private *priv; |
2031 | struct pciserial_board *board, tmp; | 2046 | const struct pciserial_board *board; |
2047 | struct pciserial_board tmp; | ||
2032 | int rc; | 2048 | int rc; |
2033 | 2049 | ||
2034 | if (ent->driver_data >= ARRAY_SIZE(pci_boards)) { | 2050 | if (ent->driver_data >= ARRAY_SIZE(pci_boards)) { |
@@ -2055,7 +2071,7 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) | |||
2055 | * We matched one of our class entries. Try to | 2071 | * We matched one of our class entries. Try to |
2056 | * determine the parameters of this board. | 2072 | * determine the parameters of this board. |
2057 | */ | 2073 | */ |
2058 | rc = serial_pci_guess_board(dev, board); | 2074 | rc = serial_pci_guess_board(dev, &tmp); |
2059 | if (rc) | 2075 | if (rc) |
2060 | goto disable; | 2076 | goto disable; |
2061 | } else { | 2077 | } else { |
@@ -2271,6 +2287,9 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
2271 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM8, | 2287 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM8, |
2272 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 2288 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
2273 | pbn_b2_8_115200 }, | 2289 | pbn_b2_8_115200 }, |
2290 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_7803, | ||
2291 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
2292 | pbn_b2_8_460800 }, | ||
2274 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM8, | 2293 | { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM8, |
2275 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 2294 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
2276 | pbn_b2_8_115200 }, | 2295 | pbn_b2_8_115200 }, |
@@ -2372,6 +2391,9 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
2372 | * For now just used the hex ID 0x950a. | 2391 | * For now just used the hex ID 0x950a. |
2373 | */ | 2392 | */ |
2374 | { PCI_VENDOR_ID_OXSEMI, 0x950a, | 2393 | { PCI_VENDOR_ID_OXSEMI, 0x950a, |
2394 | PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_DUAL_SERIAL, 0, 0, | ||
2395 | pbn_b0_2_115200 }, | ||
2396 | { PCI_VENDOR_ID_OXSEMI, 0x950a, | ||
2375 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 2397 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
2376 | pbn_b0_2_1130000 }, | 2398 | pbn_b0_2_1130000 }, |
2377 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954, | 2399 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954, |