aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/controller/vmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/controller/vmd.c')
-rw-r--r--drivers/pci/controller/vmd.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
index 990630ec57c6..ad56df98b8e6 100644
--- a/drivers/pci/controller/vmd.c
+++ b/drivers/pci/controller/vmd.c
@@ -541,8 +541,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);
}
}
}
@@ -927,7 +942,8 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
if (!list_empty(&child->devices)) {
dev = list_first_entry(&child->devices,
struct pci_dev, bus_list);
- if (pci_reset_bus(dev))
+ ret = pci_reset_bus(dev);
+ if (ret)
pci_warn(dev, "can't reset device: %d\n", ret);
break;
@@ -1036,6 +1052,13 @@ static void vmd_remove(struct pci_dev *dev)
ida_simple_remove(&vmd_instance_ida, vmd->instance);
}
+static void vmd_shutdown(struct pci_dev *dev)
+{
+ struct vmd_dev *vmd = pci_get_drvdata(dev);
+
+ vmd_remove_irq_domain(vmd);
+}
+
#ifdef CONFIG_PM_SLEEP
static int vmd_suspend(struct device *dev)
{
@@ -1101,6 +1124,7 @@ static struct pci_driver vmd_drv = {
.id_table = vmd_ids,
.probe = vmd_probe,
.remove = vmd_remove,
+ .shutdown = vmd_shutdown,
.driver = {
.pm = &vmd_dev_pm_ops,
},