diff options
-rw-r--r-- | drivers/tty/serial/8250/8250_pci.c | 61 |
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 | ||