aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorPeter Hung <hpeter@gmail.com>2014-11-19 00:22:27 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-11-25 20:06:39 -0500
commitcb8ee9f08c4abfd8744eabffc467c06795c835d9 (patch)
tree827e0e0dec89521d40bf3f540401e2773c434779 /drivers/tty
parent2b310ec7934f69c6e9a49dd675f413e112b82e5c (diff)
serial: Fix io address assign flow with Fintek PCI-to-UART Product
The original driver fixed the io address with 0xe000+idx*8, but real io address assigned from BIOS is dynamically from read PCI configure space 0x24, 0x20, 0x1c. The Fintek F81504/F81508/F81512 maybe malfunction without this patch and malfunction surely when more then 1 PCI card. Signed-off-by: Peter Hung <hpeter+linux_kernel@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/8250/8250_pci.c61
1 files changed, 46 insertions, 15 deletions
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
index 0468e15e6f10..31feeb2d0a66 100644
--- a/drivers/tty/serial/8250/8250_pci.c
+++ b/drivers/tty/serial/8250/8250_pci.c
@@ -1554,25 +1554,48 @@ static int pci_fintek_setup(struct serial_private *priv,
1554 unsigned long iobase; 1554 unsigned long iobase;
1555 unsigned long ciobase = 0; 1555 unsigned long ciobase = 0;
1556 u8 config_base; 1556 u8 config_base;
1557 u32 bar_data[3];
1557 1558
1558 /* 1559 /*
1559 * We are supposed to be able to read these from the PCI config space, 1560 * Find each UARTs offset in PCI configuraion space
1560 * but the values there don't seem to match what we need to use, so
1561 * just use these hard-coded values for now, as they are correct.
1562 */ 1561 */
1563 switch (idx) { 1562 switch (idx) {
1564 case 0: iobase = 0xe000; config_base = 0x40; break; 1563 case 0:
1565 case 1: iobase = 0xe008; config_base = 0x48; break; 1564 config_base = 0x40;
1566 case 2: iobase = 0xe010; config_base = 0x50; break; 1565 break;
1567 case 3: iobase = 0xe018; config_base = 0x58; break; 1566 case 1:
1568 case 4: iobase = 0xe020; config_base = 0x60; break; 1567 config_base = 0x48;
1569 case 5: iobase = 0xe028; config_base = 0x68; break; 1568 break;
1570 case 6: iobase = 0xe030; config_base = 0x70; break; 1569 case 2:
1571 case 7: iobase = 0xe038; config_base = 0x78; break; 1570 config_base = 0x50;
1572 case 8: iobase = 0xe040; config_base = 0x80; break; 1571 break;
1573 case 9: iobase = 0xe048; config_base = 0x88; break; 1572 case 3:
1574 case 10: iobase = 0xe050; config_base = 0x90; break; 1573 config_base = 0x58;
1575 case 11: iobase = 0xe058; config_base = 0x98; break; 1574 break;
1575 case 4:
1576 config_base = 0x60;
1577 break;
1578 case 5:
1579 config_base = 0x68;
1580 break;
1581 case 6:
1582 config_base = 0x70;
1583 break;
1584 case 7:
1585 config_base = 0x78;
1586 break;
1587 case 8:
1588 config_base = 0x80;
1589 break;
1590 case 9:
1591 config_base = 0x88;
1592 break;
1593 case 10:
1594 config_base = 0x90;
1595 break;
1596 case 11:
1597 config_base = 0x98;
1598 break;
1576 default: 1599 default:
1577 /* Unknown number of ports, get out of here */ 1600 /* Unknown number of ports, get out of here */
1578 return -EINVAL; 1601 return -EINVAL;
@@ -1583,6 +1606,14 @@ static int pci_fintek_setup(struct serial_private *priv,
1583 ciobase = (int)(base + (0x8 * idx)); 1606 ciobase = (int)(base + (0x8 * idx));
1584 } 1607 }
1585 1608
1609 /* Get the io address dispatch from the BIOS */
1610 pci_read_config_dword(pdev, 0x24, &bar_data[0]);
1611 pci_read_config_dword(pdev, 0x20, &bar_data[1]);
1612 pci_read_config_dword(pdev, 0x1c, &bar_data[2]);
1613
1614 /* Calculate Real IO Port */
1615 iobase = (bar_data[idx/4] & 0xffffffe0) + (idx % 4) * 8;
1616
1586 dev_dbg(&pdev->dev, "%s: idx=%d iobase=0x%lx ciobase=0x%lx config_base=0x%2x\n", 1617 dev_dbg(&pdev->dev, "%s: idx=%d iobase=0x%lx ciobase=0x%lx config_base=0x%2x\n",
1587 __func__, idx, iobase, ciobase, config_base); 1618 __func__, idx, iobase, ciobase, config_base);
1588 1619