diff options
Diffstat (limited to 'drivers/pci/controller/vmd.c')
-rw-r--r-- | drivers/pci/controller/vmd.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c index e718a816d481..0452cbc362ee 100644 --- a/drivers/pci/controller/vmd.c +++ b/drivers/pci/controller/vmd.c @@ -525,10 +525,9 @@ static void vmd_domain_reset(struct vmd_dev *vmd) base = vmd->cfgbar + PCIE_ECAM_OFFSET(bus, PCI_DEVFN(dev, 0), 0); - hdr_type = readb(base + PCI_HEADER_TYPE) & - PCI_HEADER_TYPE_MASK; + hdr_type = readb(base + PCI_HEADER_TYPE); - functions = (hdr_type & 0x80) ? 8 : 1; + functions = (hdr_type & PCI_HEADER_TYPE_MFD) ? 8 : 1; for (fn = 0; fn < functions; fn++) { base = vmd->cfgbar + PCIE_ECAM_OFFSET(bus, PCI_DEVFN(dev, fn), 0); @@ -541,8 +540,23 @@ static void vmd_domain_reset(struct vmd_dev *vmd) PCI_CLASS_BRIDGE_PCI)) continue; - memset_io(base + PCI_IO_BASE, 0, - PCI_ROM_ADDRESS1 - PCI_IO_BASE); + /* + * Temporarily disable the I/O range before updating + * PCI_IO_BASE. + */ + writel(0x0000ffff, base + PCI_IO_BASE_UPPER16); + /* Update lower 16 bits of I/O base/limit */ + writew(0x00f0, base + PCI_IO_BASE); + /* Update upper 16 bits of I/O base/limit */ + writel(0, base + PCI_IO_BASE_UPPER16); + + /* MMIO Base/Limit */ + writel(0x0000fff0, base + PCI_MEMORY_BASE); + + /* Prefetchable MMIO Base/Limit */ + writel(0, base + PCI_PREF_LIMIT_UPPER32); + writel(0x0000fff0, base + PCI_PREF_MEMORY_BASE); + writel(0xffffffff, base + PCI_PREF_BASE_UPPER32); } } } @@ -737,7 +751,7 @@ static int vmd_pm_enable_quirk(struct pci_dev *pdev, void *userdata) if (!(features & VMD_FEAT_BIOS_PM_QUIRK)) return 0; - pci_enable_link_state(pdev, PCIE_LINK_STATE_ALL); + pci_enable_link_state_locked(pdev, PCIE_LINK_STATE_ALL); pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_LTR); if (!pos) @@ -1063,10 +1077,7 @@ static int vmd_resume(struct device *dev) struct vmd_dev *vmd = pci_get_drvdata(pdev); int err, i; - if (vmd->irq_domain) - vmd_set_msi_remapping(vmd, true); - else - vmd_set_msi_remapping(vmd, false); + vmd_set_msi_remapping(vmd, !!vmd->irq_domain); for (i = 0; i < vmd->msix_count; i++) { err = devm_request_irq(dev, vmd->irqs[i].virq, |