aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorPeter Hung <hpeter@gmail.com>2015-04-01 02:00:21 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-04-10 08:43:48 -0400
commit6a8bc239a8c3e6ad34fceabb61ff8ec6222dad4e (patch)
treecf6b21ba068e44a29232ec1bd366dc6f07bdd954 /drivers/tty
parentca782f16ce02e3f4fa2ae28a5ff256ac69f731e2 (diff)
serial: 8250_pci: port failed after wakeup from S3
Serial ports of F81504/F81508/F81512 will failed when wakeup from S3(STR). It's due to when the system wakeup from S3(STR), this PCI device's configuration space from 0x40 to 0x40 + max_port * 0x08 should be re-configured. We move all initialization from pci_fintek_setup() to pci_fintek_init() and set it to pci_serial_quirks .init section. It's will re-init this device when system wakeup from pciserial_resume_ports(). 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.c114
1 files changed, 50 insertions, 64 deletions
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
index 98e5a6d9cfef..08da4d3e2162 100644
--- a/drivers/tty/serial/8250/8250_pci.c
+++ b/drivers/tty/serial/8250/8250_pci.c
@@ -1690,88 +1690,71 @@ static int pci_fintek_setup(struct serial_private *priv,
1690 struct uart_8250_port *port, int idx) 1690 struct uart_8250_port *port, int idx)
1691{ 1691{
1692 struct pci_dev *pdev = priv->dev; 1692 struct pci_dev *pdev = priv->dev;
1693 unsigned long iobase;
1694 u8 config_base; 1693 u8 config_base;
1694 u16 iobase;
1695
1696 config_base = 0x40 + 0x08 * idx;
1697
1698 /* Get the io address from configuration space */
1699 pci_read_config_word(pdev, config_base + 4, &iobase);
1700
1701 dev_dbg(&pdev->dev, "%s: idx=%d iobase=0x%x", __func__, idx, iobase);
1702
1703 port->port.iotype = UPIO_PORT;
1704 port->port.iobase = iobase;
1705
1706 return 0;
1707}
1708
1709static int pci_fintek_init(struct pci_dev *dev)
1710{
1711 unsigned long iobase;
1712 u32 max_port, i;
1695 u32 bar_data[3]; 1713 u32 bar_data[3];
1714 u8 config_base;
1696 1715
1697 /* 1716 switch (dev->device) {
1698 * Find each UARTs offset in PCI configuraion space 1717 case 0x1104: /* 4 ports */
1699 */ 1718 case 0x1108: /* 8 ports */
1700 switch (idx) { 1719 max_port = dev->device & 0xff;
1701 case 0:
1702 config_base = 0x40;
1703 break; 1720 break;
1704 case 1: 1721 case 0x1112: /* 12 ports */
1705 config_base = 0x48; 1722 max_port = 12;
1706 break;
1707 case 2:
1708 config_base = 0x50;
1709 break;
1710 case 3:
1711 config_base = 0x58;
1712 break;
1713 case 4:
1714 config_base = 0x60;
1715 break;
1716 case 5:
1717 config_base = 0x68;
1718 break;
1719 case 6:
1720 config_base = 0x70;
1721 break;
1722 case 7:
1723 config_base = 0x78;
1724 break;
1725 case 8:
1726 config_base = 0x80;
1727 break;
1728 case 9:
1729 config_base = 0x88;
1730 break;
1731 case 10:
1732 config_base = 0x90;
1733 break;
1734 case 11:
1735 config_base = 0x98;
1736 break; 1723 break;
1737 default: 1724 default:
1738 /* Unknown number of ports, get out of here */
1739 return -EINVAL; 1725 return -EINVAL;
1740 } 1726 }
1741 1727
1742 /* Get the io address dispatch from the BIOS */ 1728 /* Get the io address dispatch from the BIOS */
1743 pci_read_config_dword(pdev, 0x24, &bar_data[0]); 1729 pci_read_config_dword(dev, 0x24, &bar_data[0]);
1744 pci_read_config_dword(pdev, 0x20, &bar_data[1]); 1730 pci_read_config_dword(dev, 0x20, &bar_data[1]);
1745 pci_read_config_dword(pdev, 0x1c, &bar_data[2]); 1731 pci_read_config_dword(dev, 0x1c, &bar_data[2]);
1746
1747 /* Calculate Real IO Port */
1748 iobase = (bar_data[idx/4] & 0xffffffe0) + (idx % 4) * 8;
1749 1732
1750 dev_dbg(&pdev->dev, "%s: idx=%d iobase=0x%lx config_base=0x%2x\n", 1733 for (i = 0; i < max_port; ++i) {
1751 __func__, idx, iobase, config_base); 1734 /* UART0 configuration offset start from 0x40 */
1735 config_base = 0x40 + 0x08 * i;
1752 1736
1753 /* Enable UART I/O port */ 1737 /* Calculate Real IO Port */
1754 pci_write_config_byte(pdev, config_base + 0x00, 0x01); 1738 iobase = (bar_data[i / 4] & 0xffffffe0) + (i % 4) * 8;
1755 1739
1756 /* Select 128-byte FIFO and 8x FIFO threshold */ 1740 /* Enable UART I/O port */
1757 pci_write_config_byte(pdev, config_base + 0x01, 0x33); 1741 pci_write_config_byte(dev, config_base + 0x00, 0x01);
1758 1742
1759 /* LSB UART */ 1743 /* Select 128-byte FIFO and 8x FIFO threshold */
1760 pci_write_config_byte(pdev, config_base + 0x04, (u8)(iobase & 0xff)); 1744 pci_write_config_byte(dev, config_base + 0x01, 0x33);
1761 1745
1762 /* MSB UART */ 1746 /* LSB UART */
1763 pci_write_config_byte(pdev, config_base + 0x05, (u8)((iobase & 0xff00) >> 8)); 1747 pci_write_config_byte(dev, config_base + 0x04,
1748 (u8)(iobase & 0xff));
1764 1749
1765 /* irq number, this usually fails, but the spec says to do it anyway. */ 1750 /* MSB UART */
1766 pci_write_config_byte(pdev, config_base + 0x06, pdev->irq); 1751 pci_write_config_byte(dev, config_base + 0x05,
1752 (u8)((iobase & 0xff00) >> 8));
1767 1753
1768 port->port.iotype = UPIO_PORT; 1754 pci_write_config_byte(dev, config_base + 0x06, dev->irq);
1769 port->port.iobase = iobase; 1755 }
1770 port->port.mapbase = 0;
1771 port->port.membase = NULL;
1772 port->port.regshift = 0;
1773 1756
1774 return 0; 1757 return max_port;
1775} 1758}
1776 1759
1777static int skip_tx_en_setup(struct serial_private *priv, 1760static int skip_tx_en_setup(struct serial_private *priv,
@@ -2814,6 +2797,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
2814 .subvendor = PCI_ANY_ID, 2797 .subvendor = PCI_ANY_ID,
2815 .subdevice = PCI_ANY_ID, 2798 .subdevice = PCI_ANY_ID,
2816 .setup = pci_fintek_setup, 2799 .setup = pci_fintek_setup,
2800 .init = pci_fintek_init,
2817 }, 2801 },
2818 { 2802 {
2819 .vendor = 0x1c29, 2803 .vendor = 0x1c29,
@@ -2821,6 +2805,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
2821 .subvendor = PCI_ANY_ID, 2805 .subvendor = PCI_ANY_ID,
2822 .subdevice = PCI_ANY_ID, 2806 .subdevice = PCI_ANY_ID,
2823 .setup = pci_fintek_setup, 2807 .setup = pci_fintek_setup,
2808 .init = pci_fintek_init,
2824 }, 2809 },
2825 { 2810 {
2826 .vendor = 0x1c29, 2811 .vendor = 0x1c29,
@@ -2828,6 +2813,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
2828 .subvendor = PCI_ANY_ID, 2813 .subvendor = PCI_ANY_ID,
2829 .subdevice = PCI_ANY_ID, 2814 .subdevice = PCI_ANY_ID,
2830 .setup = pci_fintek_setup, 2815 .setup = pci_fintek_setup,
2816 .init = pci_fintek_init,
2831 }, 2817 },
2832 2818
2833 /* 2819 /*