···34#undef SERIAL_DEBUG_PCI3536/*37- * Definitions for PCI support.38- */39-#define FL_BASE_MASK 0x000740-#define FL_BASE0 0x000041-#define FL_BASE1 0x000142-#define FL_BASE2 0x000243-#define FL_BASE3 0x000344-#define FL_BASE4 0x000445-#define FL_GET_BASE(x) (x & FL_BASE_MASK)46-47-/* Use successive BARs (PCI base address registers),48- else use offset into some specified BAR */49-#define FL_BASE_BARS 0x000850-51-/* do not assign an irq */52-#define FL_NOIRQ 0x008053-54-/* Use the Base address register size to cap number of ports */55-#define FL_REGION_SZ_CAP 0x010056-57-struct pci_board {58- unsigned int flags;59- unsigned int num_ports;60- unsigned int base_baud;61- unsigned int uart_offset;62- unsigned int reg_shift;63- unsigned int first_offset;64-};65-66-/*67 * init function returns:68 * > 0 - number of ports69 * = 0 - use board->num_ports···45 u32 subvendor;46 u32 subdevice;47 int (*init)(struct pci_dev *dev);48- int (*setup)(struct pci_dev *dev, struct pci_board *board,49- struct uart_port *port, int idx);50 void (*exit)(struct pci_dev *dev);51};5253#define PCI_NUM_BAR_RESOURCES 65455struct serial_private {056 unsigned int nr;57 void __iomem *remapped_bar[PCI_NUM_BAR_RESOURCES];58 struct pci_serial_quirk *quirk;···72}7374static int75-setup_port(struct pci_dev *dev, struct uart_port *port,76 int bar, int offset, int regshift)77{78- struct serial_private *priv = pci_get_drvdata(dev);79 unsigned long base, len;8081 if (bar >= PCI_NUM_BAR_RESOURCES)82 return -EINVAL;830084 if (pci_resource_flags(dev, bar) & IORESOURCE_MEM) {85- base = pci_resource_start(dev, bar);86 len = pci_resource_len(dev, bar);8788 if (!priv->remapped_bar[bar])···92 return -ENOMEM;9394 port->iotype = UPIO_MEM;095 port->mapbase = base + offset;96 port->membase = priv->remapped_bar[bar] + offset;97 port->regshift = regshift;98 } else {99- base = pci_resource_start(dev, bar) + offset;100 port->iotype = UPIO_PORT;101- port->iobase = base;000102 }103 return 0;104}···111 * Not that ugly ;) -- HW112 */113static int114-afavlab_setup(struct pci_dev *dev, struct pci_board *board,115 struct uart_port *port, int idx)116{117 unsigned int bar, offset = board->first_offset;···124 offset += (idx - 4) * board->uart_offset;125 }126127- return setup_port(dev, port, bar, offset, board->reg_shift);128}129130/*···164 * some serial ports are supposed to be hidden on certain models.165 */166static int167-pci_hp_diva_setup(struct pci_dev *dev, struct pci_board *board,168 struct uart_port *port, int idx)169{170 unsigned int offset = board->first_offset;171 unsigned int bar = FL_GET_BASE(board->flags);172173- switch (dev->subsystem_device) {174 case PCI_DEVICE_ID_HP_DIVA_MAESTRO:175 if (idx == 3)176 idx++;···187188 offset += idx * board->uart_offset;189190- return setup_port(dev, port, bar, offset, board->reg_shift);191}192193/*···282283/* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */284static int285-sbs_setup(struct pci_dev *dev, struct pci_board *board,286 struct uart_port *port, int idx)287{288 unsigned int bar, offset = board->first_offset;···298 } else /* we have only 8 ports on PMC-OCTALPRO */299 return 1;300301- return setup_port(dev, port, bar, offset, board->reg_shift);302}303304/*···364 * - 10x cards have control registers in IO and/or memory space;365 * - 20x cards have control registers in standard PCI configuration space.366 *000367 * There are also Quartet Serial cards which use Oxford Semiconductor368 * 16954 quad UART PCI chip clocked by 18.432 MHz quartz.369 *···423 return 0;424}425426-int pci_siig10x_fn(struct pci_dev *dev, int enable)427{428- int ret = 0;429- if (enable)430- ret = pci_siig10x_init(dev);431- return ret;432-}433434-int pci_siig20x_fn(struct pci_dev *dev, int enable)435-{436- int ret = 0;437- if (enable)438- ret = pci_siig20x_init(dev);439- return ret;440-}441442-EXPORT_SYMBOL(pci_siig10x_fn);443-EXPORT_SYMBOL(pci_siig20x_fn);0444445/*446 * Timedia has an explosion of boards, and to avoid the PCI table from···495 * Ugh, this is ugly as all hell --- TYT496 */497static int498-pci_timedia_setup(struct pci_dev *dev, struct pci_board *board,499 struct uart_port *port, int idx)500{501 unsigned int bar = 0, offset = board->first_offset;···521 bar = idx - 2;522 }523524- return setup_port(dev, port, bar, offset, board->reg_shift);525}526527/*528 * Some Titan cards are also a little weird529 */530static int531-titan_400l_800l_setup(struct pci_dev *dev, struct pci_board *board,0532 struct uart_port *port, int idx)533{534 unsigned int bar, offset = board->first_offset;···546 offset = (idx - 2) * board->uart_offset;547 }548549- return setup_port(dev, port, bar, offset, board->reg_shift);550}551552static int __devinit pci_xircom_init(struct pci_dev *dev)···566}567568static int569-pci_default_setup(struct pci_dev *dev, struct pci_board *board,570 struct uart_port *port, int idx)571{572 unsigned int bar, offset = board->first_offset, maxnr;···577 else578 offset += idx * board->uart_offset;579580- maxnr = (pci_resource_len(dev, bar) - board->first_offset) /581 (8 << board->reg_shift);582583 if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr)584 return 1;585586- return setup_port(dev, port, bar, offset, board->reg_shift);587}588589/* This should be in linux/pci_ids.h */···727 .setup = sbs_setup,728 .exit = __devexit_p(sbs_exit),729 },730-731 /*732 * SIIG cards.733- * It is not clear whether these could be collapsed.734 */735 {736 .vendor = PCI_VENDOR_ID_SIIG,737- .device = PCI_DEVICE_ID_SIIG_1S_10x_550,738 .subvendor = PCI_ANY_ID,739 .subdevice = PCI_ANY_ID,740- .init = pci_siig10x_init,741- .setup = pci_default_setup,742- },743- {744- .vendor = PCI_VENDOR_ID_SIIG,745- .device = PCI_DEVICE_ID_SIIG_1S_10x_650,746- .subvendor = PCI_ANY_ID,747- .subdevice = PCI_ANY_ID,748- .init = pci_siig10x_init,749- .setup = pci_default_setup,750- },751- {752- .vendor = PCI_VENDOR_ID_SIIG,753- .device = PCI_DEVICE_ID_SIIG_1S_10x_850,754- .subvendor = PCI_ANY_ID,755- .subdevice = PCI_ANY_ID,756- .init = pci_siig10x_init,757- .setup = pci_default_setup,758- },759- {760- .vendor = PCI_VENDOR_ID_SIIG,761- .device = PCI_DEVICE_ID_SIIG_2S_10x_550,762- .subvendor = PCI_ANY_ID,763- .subdevice = PCI_ANY_ID,764- .init = pci_siig10x_init,765- .setup = pci_default_setup,766- },767- {768- .vendor = PCI_VENDOR_ID_SIIG,769- .device = PCI_DEVICE_ID_SIIG_2S_10x_650,770- .subvendor = PCI_ANY_ID,771- .subdevice = PCI_ANY_ID,772- .init = pci_siig10x_init,773- .setup = pci_default_setup,774- },775- {776- .vendor = PCI_VENDOR_ID_SIIG,777- .device = PCI_DEVICE_ID_SIIG_2S_10x_850,778- .subvendor = PCI_ANY_ID,779- .subdevice = PCI_ANY_ID,780- .init = pci_siig10x_init,781- .setup = pci_default_setup,782- },783- {784- .vendor = PCI_VENDOR_ID_SIIG,785- .device = PCI_DEVICE_ID_SIIG_4S_10x_550,786- .subvendor = PCI_ANY_ID,787- .subdevice = PCI_ANY_ID,788- .init = pci_siig10x_init,789- .setup = pci_default_setup,790- },791- {792- .vendor = PCI_VENDOR_ID_SIIG,793- .device = PCI_DEVICE_ID_SIIG_4S_10x_650,794- .subvendor = PCI_ANY_ID,795- .subdevice = PCI_ANY_ID,796- .init = pci_siig10x_init,797- .setup = pci_default_setup,798- },799- {800- .vendor = PCI_VENDOR_ID_SIIG,801- .device = PCI_DEVICE_ID_SIIG_4S_10x_850,802- .subvendor = PCI_ANY_ID,803- .subdevice = PCI_ANY_ID,804- .init = pci_siig10x_init,805- .setup = pci_default_setup,806- },807- {808- .vendor = PCI_VENDOR_ID_SIIG,809- .device = PCI_DEVICE_ID_SIIG_1S_20x_550,810- .subvendor = PCI_ANY_ID,811- .subdevice = PCI_ANY_ID,812- .init = pci_siig20x_init,813- .setup = pci_default_setup,814- },815- {816- .vendor = PCI_VENDOR_ID_SIIG,817- .device = PCI_DEVICE_ID_SIIG_1S_20x_650,818- .subvendor = PCI_ANY_ID,819- .subdevice = PCI_ANY_ID,820- .init = pci_siig20x_init,821- .setup = pci_default_setup,822- },823- {824- .vendor = PCI_VENDOR_ID_SIIG,825- .device = PCI_DEVICE_ID_SIIG_1S_20x_850,826- .subvendor = PCI_ANY_ID,827- .subdevice = PCI_ANY_ID,828- .init = pci_siig20x_init,829- .setup = pci_default_setup,830- },831- {832- .vendor = PCI_VENDOR_ID_SIIG,833- .device = PCI_DEVICE_ID_SIIG_2S_20x_550,834- .subvendor = PCI_ANY_ID,835- .subdevice = PCI_ANY_ID,836- .init = pci_siig20x_init,837- .setup = pci_default_setup,838- },839- { .vendor = PCI_VENDOR_ID_SIIG,840- .device = PCI_DEVICE_ID_SIIG_2S_20x_650,841- .subvendor = PCI_ANY_ID,842- .subdevice = PCI_ANY_ID,843- .init = pci_siig20x_init,844- .setup = pci_default_setup,845- },846- {847- .vendor = PCI_VENDOR_ID_SIIG,848- .device = PCI_DEVICE_ID_SIIG_2S_20x_850,849- .subvendor = PCI_ANY_ID,850- .subdevice = PCI_ANY_ID,851- .init = pci_siig20x_init,852- .setup = pci_default_setup,853- },854- {855- .vendor = PCI_VENDOR_ID_SIIG,856- .device = PCI_DEVICE_ID_SIIG_4S_20x_550,857- .subvendor = PCI_ANY_ID,858- .subdevice = PCI_ANY_ID,859- .init = pci_siig20x_init,860- .setup = pci_default_setup,861- },862- {863- .vendor = PCI_VENDOR_ID_SIIG,864- .device = PCI_DEVICE_ID_SIIG_4S_20x_650,865- .subvendor = PCI_ANY_ID,866- .subdevice = PCI_ANY_ID,867- .init = pci_siig20x_init,868- .setup = pci_default_setup,869- },870- {871- .vendor = PCI_VENDOR_ID_SIIG,872- .device = PCI_DEVICE_ID_SIIG_4S_20x_850,873- .subvendor = PCI_ANY_ID,874- .subdevice = PCI_ANY_ID,875- .init = pci_siig20x_init,876 .setup = pci_default_setup,877 },878 /*···826}827828static _INLINE_ int829-get_pci_irq(struct pci_dev *dev, struct pci_board *board, int idx)830{831 if (board->flags & FL_NOIRQ)832 return 0;···951 * see first lines of serial_in() and serial_out() in 8250.c952*/953954-static struct pci_board pci_boards[] __devinitdata = {955 [pbn_default] = {956 .flags = FL_BASE0,957 .num_ports = 1,···1411 * serial specs. Returns 0 on success, 1 on failure.1412 */1413static int __devinit1414-serial_pci_guess_board(struct pci_dev *dev, struct pci_board *board)1415{1416 int num_iomem, num_port, first_port = -1, i;1417···1476}14771478static inline int1479-serial_pci_matches(struct pci_board *board, struct pci_board *guessed)01480{1481 return1482 board->num_ports == guessed->num_ports &&···1487 board->first_offset == guessed->first_offset;1488}1489000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001490/*1491 * Probe one serial board. Unfortunately, there is no rhyme nor reason1492 * to the arrangement of serial ports on a PCI card.···1626pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)1627{1628 struct serial_private *priv;1629- struct pci_board *board, tmp;1630- struct pci_serial_quirk *quirk;1631- int rc, nr_ports, i;16321633 if (ent->driver_data >= ARRAY_SIZE(pci_boards)) {1634 printk(KERN_ERR "pci_init_one: invalid driver_data: %ld\n",···1646 * Use a copy of the pci_board entry for this;1647 * avoid changing entries in the table.1648 */1649- memcpy(&tmp, board, sizeof(struct pci_board));1650 board = &tmp;16511652 /*···1662 * detect this boards settings with our heuristic,1663 * then we no longer need this entry.1664 */1665- memcpy(&tmp, &pci_boards[pbn_default], sizeof(struct pci_board));01666 rc = serial_pci_guess_board(dev, &tmp);1667 if (rc == 0 && serial_pci_matches(board, &tmp))1668 moan_device("Redundant entry in serial pci_table.",1669 dev);1670 }16711672- nr_ports = board->num_ports;1673-1674- /*1675- * Find an init and setup quirks.1676- */1677- quirk = find_quirk(dev);1678-1679- /*1680- * Run the new-style initialization function.1681- * The initialization function returns:1682- * <0 - error1683- * 0 - use board->num_ports1684- * >0 - number of ports1685- */1686- if (quirk->init) {1687- rc = quirk->init(dev);1688- if (rc < 0)1689- goto disable;1690- if (rc)1691- nr_ports = rc;1692 }16931694- priv = kmalloc(sizeof(struct serial_private) +1695- sizeof(unsigned int) * nr_ports,1696- GFP_KERNEL);1697- if (!priv) {1698- rc = -ENOMEM;1699- goto deinit;1700- }17011702- memset(priv, 0, sizeof(struct serial_private) +1703- sizeof(unsigned int) * nr_ports);1704-1705- priv->quirk = quirk;1706- pci_set_drvdata(dev, priv);1707-1708- for (i = 0; i < nr_ports; i++) {1709- struct uart_port serial_port;1710- memset(&serial_port, 0, sizeof(struct uart_port));1711-1712- serial_port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF |1713- UPF_SHARE_IRQ;1714- serial_port.uartclk = board->base_baud * 16;1715- serial_port.irq = get_pci_irq(dev, board, i);1716- serial_port.dev = &dev->dev;1717- if (quirk->setup(dev, board, &serial_port, i))1718- break;1719-#ifdef SERIAL_DEBUG_PCI1720- printk("Setup PCI port: port %x, irq %d, type %d\n",1721- serial_port.iobase, serial_port.irq, serial_port.iotype);1722-#endif1723-1724- priv->line[i] = serial8250_register_port(&serial_port);1725- if (priv->line[i] < 0) {1726- printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), priv->line[i]);1727- break;1728- }1729- }1730-1731- priv->nr = i;1732-1733- return 0;1734-1735- deinit:1736- if (quirk->exit)1737- quirk->exit(dev);1738 disable:1739 pci_disable_device(dev);1740 return rc;···1686static void __devexit pciserial_remove_one(struct pci_dev *dev)1687{1688 struct serial_private *priv = pci_get_drvdata(dev);1689- struct pci_serial_quirk *quirk;1690- int i;16911692 pci_set_drvdata(dev, NULL);16931694- for (i = 0; i < priv->nr; i++)1695- serial8250_unregister_port(priv->line[i]);1696-1697- for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {1698- if (priv->remapped_bar[i])1699- iounmap(priv->remapped_bar[i]);1700- priv->remapped_bar[i] = NULL;1701- }1702-1703- /*1704- * Find the exit quirks.1705- */1706- quirk = find_quirk(dev);1707- if (quirk->exit)1708- quirk->exit(dev);17091710 pci_disable_device(dev);1711-1712- kfree(priv);1713}17141715static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state)1716{1717 struct serial_private *priv = pci_get_drvdata(dev);17181719- if (priv) {1720- int i;17211722- for (i = 0; i < priv->nr; i++)1723- serial8250_suspend_port(priv->line[i]);1724- }1725 pci_save_state(dev);1726 pci_set_power_state(dev, pci_choose_state(dev, state));1727 return 0;···1714 pci_restore_state(dev);17151716 if (priv) {1717- int i;1718-1719 /*1720 * The device may have been disabled. Re-enable it.1721 */1722 pci_enable_device(dev);17231724- /*1725- * Ensure that the board is correctly configured.1726- */1727- if (priv->quirk->init)1728- priv->quirk->init(dev);1729-1730- for (i = 0; i < priv->nr; i++)1731- serial8250_resume_port(priv->line[i]);1732 }1733 return 0;1734}
···34#undef SERIAL_DEBUG_PCI3536/*00000000000000000000000000000037 * init function returns:38 * > 0 - number of ports39 * = 0 - use board->num_ports···75 u32 subvendor;76 u32 subdevice;77 int (*init)(struct pci_dev *dev);78+ int (*setup)(struct serial_private *, struct pciserial_board *,79+ struct uart_port *, int);80 void (*exit)(struct pci_dev *dev);81};8283#define PCI_NUM_BAR_RESOURCES 68485struct serial_private {86+ struct pci_dev *dev;87 unsigned int nr;88 void __iomem *remapped_bar[PCI_NUM_BAR_RESOURCES];89 struct pci_serial_quirk *quirk;···101}102103static int104+setup_port(struct serial_private *priv, struct uart_port *port,105 int bar, int offset, int regshift)106{107+ struct pci_dev *dev = priv->dev;108 unsigned long base, len;109110 if (bar >= PCI_NUM_BAR_RESOURCES)111 return -EINVAL;112113+ base = pci_resource_start(dev, bar);114+115 if (pci_resource_flags(dev, bar) & IORESOURCE_MEM) {0116 len = pci_resource_len(dev, bar);117118 if (!priv->remapped_bar[bar])···120 return -ENOMEM;121122 port->iotype = UPIO_MEM;123+ port->iobase = 0;124 port->mapbase = base + offset;125 port->membase = priv->remapped_bar[bar] + offset;126 port->regshift = regshift;127 } else {0128 port->iotype = UPIO_PORT;129+ port->iobase = base + offset;130+ port->mapbase = 0;131+ port->membase = NULL;132+ port->regshift = 0;133 }134 return 0;135}···136 * Not that ugly ;) -- HW137 */138static int139+afavlab_setup(struct serial_private *priv, struct pciserial_board *board,140 struct uart_port *port, int idx)141{142 unsigned int bar, offset = board->first_offset;···149 offset += (idx - 4) * board->uart_offset;150 }151152+ return setup_port(priv, port, bar, offset, board->reg_shift);153}154155/*···189 * some serial ports are supposed to be hidden on certain models.190 */191static int192+pci_hp_diva_setup(struct serial_private *priv, struct pciserial_board *board,193 struct uart_port *port, int idx)194{195 unsigned int offset = board->first_offset;196 unsigned int bar = FL_GET_BASE(board->flags);197198+ switch (priv->dev->subsystem_device) {199 case PCI_DEVICE_ID_HP_DIVA_MAESTRO:200 if (idx == 3)201 idx++;···212213 offset += idx * board->uart_offset;214215+ return setup_port(priv, port, bar, offset, board->reg_shift);216}217218/*···307308/* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */309static int310+sbs_setup(struct serial_private *priv, struct pciserial_board *board,311 struct uart_port *port, int idx)312{313 unsigned int bar, offset = board->first_offset;···323 } else /* we have only 8 ports on PMC-OCTALPRO */324 return 1;325326+ return setup_port(priv, port, bar, offset, board->reg_shift);327}328329/*···389 * - 10x cards have control registers in IO and/or memory space;390 * - 20x cards have control registers in standard PCI configuration space.391 *392+ * Note: all 10x cards have PCI device ids 0x10..393+ * all 20x cards have PCI device ids 0x20..394+ *395 * There are also Quartet Serial cards which use Oxford Semiconductor396 * 16954 quad UART PCI chip clocked by 18.432 MHz quartz.397 *···445 return 0;446}447448+static int pci_siig_init(struct pci_dev *dev)449{450+ unsigned int type = dev->device & 0xff00;0000451452+ if (type == 0x1000)453+ return pci_siig10x_init(dev);454+ else if (type == 0x2000)455+ return pci_siig20x_init(dev);000456457+ moan_device("Unknown SIIG card", dev);458+ return -ENODEV;459+}460461/*462 * Timedia has an explosion of boards, and to avoid the PCI table from···523 * Ugh, this is ugly as all hell --- TYT524 */525static int526+pci_timedia_setup(struct serial_private *priv, struct pciserial_board *board,527 struct uart_port *port, int idx)528{529 unsigned int bar = 0, offset = board->first_offset;···549 bar = idx - 2;550 }551552+ return setup_port(priv, port, bar, offset, board->reg_shift);553}554555/*556 * Some Titan cards are also a little weird557 */558static int559+titan_400l_800l_setup(struct serial_private *priv,560+ struct pciserial_board *board,561 struct uart_port *port, int idx)562{563 unsigned int bar, offset = board->first_offset;···573 offset = (idx - 2) * board->uart_offset;574 }575576+ return setup_port(priv, port, bar, offset, board->reg_shift);577}578579static int __devinit pci_xircom_init(struct pci_dev *dev)···593}594595static int596+pci_default_setup(struct serial_private *priv, struct pciserial_board *board,597 struct uart_port *port, int idx)598{599 unsigned int bar, offset = board->first_offset, maxnr;···604 else605 offset += idx * board->uart_offset;606607+ maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) /608 (8 << board->reg_shift);609610 if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr)611 return 1;612613+ return setup_port(priv, port, bar, offset, board->reg_shift);614}615616/* This should be in linux/pci_ids.h */···754 .setup = sbs_setup,755 .exit = __devexit_p(sbs_exit),756 },0757 /*758 * SIIG cards.0759 */760 {761 .vendor = PCI_VENDOR_ID_SIIG,762+ .device = PCI_ANY_ID,763 .subvendor = PCI_ANY_ID,764 .subdevice = PCI_ANY_ID,765+ .init = pci_siig_init,000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000766 .setup = pci_default_setup,767 },768 /*···990}991992static _INLINE_ int993+get_pci_irq(struct pci_dev *dev, struct pciserial_board *board)994{995 if (board->flags & FL_NOIRQ)996 return 0;···1115 * see first lines of serial_in() and serial_out() in 8250.c1116*/11171118+static struct pciserial_board pci_boards[] __devinitdata = {1119 [pbn_default] = {1120 .flags = FL_BASE0,1121 .num_ports = 1,···1575 * serial specs. Returns 0 on success, 1 on failure.1576 */1577static int __devinit1578+serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)1579{1580 int num_iomem, num_port, first_port = -1, i;1581···1640}16411642static inline int1643+serial_pci_matches(struct pciserial_board *board,1644+ struct pciserial_board *guessed)1645{1646 return1647 board->num_ports == guessed->num_ports &&···1650 board->first_offset == guessed->first_offset;1651}16521653+struct serial_private *1654+pciserial_init_ports(struct pci_dev *dev, struct pciserial_board *board)1655+{1656+ struct uart_port serial_port;1657+ struct serial_private *priv;1658+ struct pci_serial_quirk *quirk;1659+ int rc, nr_ports, i;1660+1661+ nr_ports = board->num_ports;1662+1663+ /*1664+ * Find an init and setup quirks.1665+ */1666+ quirk = find_quirk(dev);1667+1668+ /*1669+ * Run the new-style initialization function.1670+ * The initialization function returns:1671+ * <0 - error1672+ * 0 - use board->num_ports1673+ * >0 - number of ports1674+ */1675+ if (quirk->init) {1676+ rc = quirk->init(dev);1677+ if (rc < 0) {1678+ priv = ERR_PTR(rc);1679+ goto err_out;1680+ }1681+ if (rc)1682+ nr_ports = rc;1683+ }1684+1685+ priv = kmalloc(sizeof(struct serial_private) +1686+ sizeof(unsigned int) * nr_ports,1687+ GFP_KERNEL);1688+ if (!priv) {1689+ priv = ERR_PTR(-ENOMEM);1690+ goto err_deinit;1691+ }1692+1693+ memset(priv, 0, sizeof(struct serial_private) +1694+ sizeof(unsigned int) * nr_ports);1695+1696+ priv->dev = dev;1697+ priv->quirk = quirk;1698+1699+ memset(&serial_port, 0, sizeof(struct uart_port));1700+ serial_port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;1701+ serial_port.uartclk = board->base_baud * 16;1702+ serial_port.irq = get_pci_irq(dev, board);1703+ serial_port.dev = &dev->dev;1704+1705+ for (i = 0; i < nr_ports; i++) {1706+ if (quirk->setup(priv, board, &serial_port, i))1707+ break;1708+1709+#ifdef SERIAL_DEBUG_PCI1710+ printk("Setup PCI port: port %x, irq %d, type %d\n",1711+ serial_port.iobase, serial_port.irq, serial_port.iotype);1712+#endif1713+1714+ priv->line[i] = serial8250_register_port(&serial_port);1715+ if (priv->line[i] < 0) {1716+ printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), priv->line[i]);1717+ break;1718+ }1719+ }1720+1721+ priv->nr = i;1722+1723+ return priv;1724+1725+ err_deinit:1726+ if (quirk->exit)1727+ quirk->exit(dev);1728+ err_out:1729+ return priv;1730+}1731+EXPORT_SYMBOL_GPL(pciserial_init_ports);1732+1733+void pciserial_remove_ports(struct serial_private *priv)1734+{1735+ struct pci_serial_quirk *quirk;1736+ int i;1737+1738+ for (i = 0; i < priv->nr; i++)1739+ serial8250_unregister_port(priv->line[i]);1740+1741+ for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {1742+ if (priv->remapped_bar[i])1743+ iounmap(priv->remapped_bar[i]);1744+ priv->remapped_bar[i] = NULL;1745+ }1746+1747+ /*1748+ * Find the exit quirks.1749+ */1750+ quirk = find_quirk(priv->dev);1751+ if (quirk->exit)1752+ quirk->exit(priv->dev);1753+1754+ kfree(priv);1755+}1756+EXPORT_SYMBOL_GPL(pciserial_remove_ports);1757+1758+void pciserial_suspend_ports(struct serial_private *priv)1759+{1760+ int i;1761+1762+ for (i = 0; i < priv->nr; i++)1763+ if (priv->line[i] >= 0)1764+ serial8250_suspend_port(priv->line[i]);1765+}1766+EXPORT_SYMBOL_GPL(pciserial_suspend_ports);1767+1768+void pciserial_resume_ports(struct serial_private *priv)1769+{1770+ int i;1771+1772+ /*1773+ * Ensure that the board is correctly configured.1774+ */1775+ if (priv->quirk->init)1776+ priv->quirk->init(priv->dev);1777+1778+ for (i = 0; i < priv->nr; i++)1779+ if (priv->line[i] >= 0)1780+ serial8250_resume_port(priv->line[i]);1781+}1782+EXPORT_SYMBOL_GPL(pciserial_resume_ports);1783+1784/*1785 * Probe one serial board. Unfortunately, there is no rhyme nor reason1786 * to the arrangement of serial ports on a PCI card.···1658pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)1659{1660 struct serial_private *priv;1661+ struct pciserial_board *board, tmp;1662+ int rc;016631664 if (ent->driver_data >= ARRAY_SIZE(pci_boards)) {1665 printk(KERN_ERR "pci_init_one: invalid driver_data: %ld\n",···1679 * Use a copy of the pci_board entry for this;1680 * avoid changing entries in the table.1681 */1682+ memcpy(&tmp, board, sizeof(struct pciserial_board));1683 board = &tmp;16841685 /*···1695 * detect this boards settings with our heuristic,1696 * then we no longer need this entry.1697 */1698+ memcpy(&tmp, &pci_boards[pbn_default],1699+ sizeof(struct pciserial_board));1700 rc = serial_pci_guess_board(dev, &tmp);1701 if (rc == 0 && serial_pci_matches(board, &tmp))1702 moan_device("Redundant entry in serial pci_table.",1703 dev);1704 }17051706+ priv = pciserial_init_ports(dev, board);1707+ if (!IS_ERR(priv)) {1708+ pci_set_drvdata(dev, priv);1709+ return 0;00000000000000001710 }17111712+ rc = PTR_ERR(priv);00000017130000000000000000000000000000000000001714 disable:1715 pci_disable_device(dev);1716 return rc;···1776static void __devexit pciserial_remove_one(struct pci_dev *dev)1777{1778 struct serial_private *priv = pci_get_drvdata(dev);0017791780 pci_set_drvdata(dev, NULL);17811782+ pciserial_remove_ports(priv);0000000000000017831784 pci_disable_device(dev);001785}17861787static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state)1788{1789 struct serial_private *priv = pci_get_drvdata(dev);17901791+ if (priv)1792+ pciserial_suspend_ports(priv);17930001794 pci_save_state(dev);1795 pci_set_power_state(dev, pci_choose_state(dev, state));1796 return 0;···1825 pci_restore_state(dev);18261827 if (priv) {001828 /*1829 * The device may have been disabled. Re-enable it.1830 */1831 pci_enable_device(dev);18321833+ pciserial_resume_ports(priv);00000001834 }1835 return 0;1836}
+37-2
include/linux/8250_pci.h
···1-int pci_siig10x_fn(struct pci_dev *dev, int enable);2-int pci_siig20x_fn(struct pci_dev *dev, int enable);00000000000000000000000000000000000
···1+/*2+ * Definitions for PCI support.3+ */4+#define FL_BASE_MASK 0x00075+#define FL_BASE0 0x00006+#define FL_BASE1 0x00017+#define FL_BASE2 0x00028+#define FL_BASE3 0x00039+#define FL_BASE4 0x000410+#define FL_GET_BASE(x) (x & FL_BASE_MASK)11+12+/* Use successive BARs (PCI base address registers),13+ else use offset into some specified BAR */14+#define FL_BASE_BARS 0x000815+16+/* do not assign an irq */17+#define FL_NOIRQ 0x008018+19+/* Use the Base address register size to cap number of ports */20+#define FL_REGION_SZ_CAP 0x010021+22+struct pciserial_board {23+ unsigned int flags;24+ unsigned int num_ports;25+ unsigned int base_baud;26+ unsigned int uart_offset;27+ unsigned int reg_shift;28+ unsigned int first_offset;29+};30+31+struct serial_private;32+33+struct serial_private *34+pciserial_init_ports(struct pci_dev *dev, struct pciserial_board *board);35+void pciserial_remove_ports(struct serial_private *priv);36+void pciserial_suspend_ports(struct serial_private *priv);37+void pciserial_resume_ports(struct serial_private *priv);
-40
include/linux/serialP.h
···140#define ALPHA_KLUDGE_MCR 0141#endif142143-/*144- * Definitions for PCI support.145- */146-#define SPCI_FL_BASE_MASK 0x0007147-#define SPCI_FL_BASE0 0x0000148-#define SPCI_FL_BASE1 0x0001149-#define SPCI_FL_BASE2 0x0002150-#define SPCI_FL_BASE3 0x0003151-#define SPCI_FL_BASE4 0x0004152-#define SPCI_FL_GET_BASE(x) (x & SPCI_FL_BASE_MASK)153-154-#define SPCI_FL_IRQ_MASK (0x0007 << 4)155-#define SPCI_FL_IRQBASE0 (0x0000 << 4)156-#define SPCI_FL_IRQBASE1 (0x0001 << 4)157-#define SPCI_FL_IRQBASE2 (0x0002 << 4)158-#define SPCI_FL_IRQBASE3 (0x0003 << 4)159-#define SPCI_FL_IRQBASE4 (0x0004 << 4)160-#define SPCI_FL_GET_IRQBASE(x) ((x & SPCI_FL_IRQ_MASK) >> 4)161-162-/* Use successive BARs (PCI base address registers), 163- else use offset into some specified BAR */164-#define SPCI_FL_BASE_TABLE 0x0100165-166-/* Use successive entries in the irq resource table */167-#define SPCI_FL_IRQ_TABLE 0x0200168-169-/* Use the irq resource table instead of dev->irq */170-#define SPCI_FL_IRQRESOURCE 0x0400171-172-/* Use the Base address register size to cap number of ports */173-#define SPCI_FL_REGION_SZ_CAP 0x0800174-175-/* Do not use irq sharing for this device */176-#define SPCI_FL_NO_SHIRQ 0x1000177-178-/* This is a PNP device */179-#define SPCI_FL_ISPNP 0x2000180-181-#define SPCI_FL_PNPDEFAULT (SPCI_FL_IRQRESOURCE|SPCI_FL_ISPNP)182-183#endif /* _LINUX_SERIAL_H */