commit f02741f1470c9ecd8a2d0335a0cc5f6f90d4e327
Author: Bjorn Helgaas <bjorn@dc7800.home>
Date:   Wed Sep 3 21:25:04 2008 -0600

diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index c2f2393..c341c1e 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -737,6 +737,91 @@ static void __devexit pci_ite887x_exit(struct pci_dev *dev)
 	release_region(ioport, ITE_887x_IOSIZE);
 }
 
+#define ITE_887x_IRR0  0
+#define ITE_887x_IRR1  1
+#define ITE_887x_IRR2  2
+#define ITE_887x_IMR0  4
+#define ITE_887x_IMR1  5
+#define ITE_887x_IMR2  6
+#define ITE_887x_IER0  8
+#define ITE_887x_IER1  9
+#define ITE_887x_IER2  10
+#define ITE_887x_ITR0  12
+#define ITE_887x_ITR1  13
+#define ITE_887x_ITR2  14
+
+static int pci_syba_ite887x_init(struct pci_dev *dev)
+{
+	/* inta_addr are the configuration addresses of the ITE */
+	static const short inta_addr[] = { 0x2a0, 0x2c0, 0x220, 0x240, 0x1e0,
+							0x200, 0x280, 0 };
+	int ret, i, type;
+	struct resource *iobase = NULL;
+	u32 miscr, uartbar, ioport;
+	int iob;
+
+	/* search for the base-ioport */
+	i = 0;
+	while (inta_addr[i] && iobase == NULL) {
+		dev_info(&dev->dev, "check %#x\n", inta_addr[i]);
+		iobase = request_region(inta_addr[i], ITE_887x_IOSIZE,
+								"ite887x");
+		if (iobase != NULL) {
+			/* write POSIO0R - speed | size | ioport */
+			pci_write_config_dword(dev, ITE_887x_POSIO0,
+				ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED |
+				ITE_887x_POSIO_IOSIZE_32 | inta_addr[i]);
+			/* write INTCBAR - ioport */
+			pci_write_config_dword(dev, ITE_887x_INTCBAR,
+								inta_addr[i]);
+			ret = inb(inta_addr[i]);
+			dev_info(&dev->dev, "got %#x\n", ret);
+			if (ret != 0xff) {
+				/* ioport connected */
+				break;
+			}
+			release_region(iobase->start, ITE_887x_IOSIZE);
+			iobase = NULL;
+		}
+		i++;
+	}
+
+	if (!inta_addr[i]) {
+		dev_err(&dev->dev, "can't find iobase\n");
+		return -ENODEV;
+	}
+	iob = inta_addr[i];
+	dev_info(&dev->dev, "syba at 0x%p\n", iob);
+
+       /* DEBUG */
+	dev_info(&dev->dev, "ite887x: io base at %#x\n", iob);
+	dev_info(&dev->dev, "ite887x: IRR0=%02x IMR0=%02x IER0=%02x\n",
+               inb(iob + ITE_887x_IRR0), inb(iob + ITE_887x_IMR0), inb(iob + ITE_887x_IER0));
+	dev_info(&dev->dev, "ite887x: IRR1=%02x IMR1=%02x IER1=%02x\n",
+               inb(iob + ITE_887x_IRR1), inb(iob + ITE_887x_IMR1), inb(iob + ITE_887x_IER1));
+	dev_info(&dev->dev, "ite887x: IRR2=%02x IMR2=%02x IER2=%02x\n",
+               inb(iob + ITE_887x_IRR2), inb(iob + ITE_887x_IMR2), inb(iob + ITE_887x_IER2));
+
+       /* Clear s/w interrupt genaration register (just in case) */
+       outb(0, iob + ITE_887x_IER0);
+       outb(0, iob + ITE_887x_IER1);
+       outb(0, iob + ITE_887x_IER2);
+
+       /* Clear IRQ latches */
+       outb(0, iob + ITE_887x_IRR0);
+       outb(0, iob + ITE_887x_IRR1);
+       outb(0, iob + ITE_887x_IRR2);
+
+       /* Mask interrupts from on-chip devices (unused on this card) */
+       outb(0xf, iob + ITE_887x_IMR2);
+
+       /* Set external IRQ mode to level-triggered */
+       outb(0xff, iob + ITE_887x_IER0);
+       outb(0xff, iob + ITE_887x_IER1);
+
+	return 8;
+}
+
 static int
 pci_default_setup(struct serial_private *priv, struct pciserial_board *board,
 		  struct uart_port *port, int idx)
@@ -835,6 +920,18 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
 		.exit		= __devexit_p(pci_ite887x_exit),
 	},
 	/*
+	 * Syba
+	 */
+	{
+		.vendor		= PCI_VENDOR_ID_PLX,
+		.device		= 0x9016,
+		.subvendor	= 0x544e,
+		.subdevice	= 0x0008,
+		.init		= pci_syba_ite887x_init,
+		.setup		= pci_default_setup,
+	/*	.exit		= __devexit_p(pci_ite887x_exit), */
+	},
+	/*
 	 * Panacom
 	 */
 	{
@@ -2581,6 +2678,11 @@ static struct pci_device_id serial_pci_tbl[] = {
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_b3_8_115200 },
 
+	/* Syba PCI8871-PR8 8-port serial card */
+	{	PCI_VENDOR_ID_PLX, 0x9016,
+		0x544e, 0x0008, 0, 0,
+		pbn_b0_8_115200 },
+
 	/*
 	 * Exar Corp. XR17C15[248] Dual/Quad/Octal UART
 	 */
