Skip to content

Commit

Permalink
Merge branch 'remotes/lorenzo/pci/vmd'
Browse files Browse the repository at this point in the history
- Restore MSI remapping configuration during resume because the
  configuration is cleared out by firmware when suspending (Nirmal Patel)

- Reset the hierarchy below VMD when probing the VMD; we attempted this
  before, but with the wrong device, so it didn't work (Francisco Munoz)

* remotes/lorenzo/pci/vmd:
  PCI: vmd: Fix secondary bus reset for Intel bridges
  PCI: vmd: Disable MSI remapping after suspend
  • Loading branch information
bjorn-helgaas committed Dec 10, 2022
2 parents 4e5db79 + 0a58465 commit ba7deaa
Showing 1 changed file with 25 additions and 2 deletions.
27 changes: 25 additions & 2 deletions drivers/pci/controller/vmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
resource_size_t offset[2] = {0};
resource_size_t membar2_offset = 0x2000;
struct pci_bus *child;
struct pci_dev *dev;
int ret;

/*
Expand Down Expand Up @@ -859,8 +860,25 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)

pci_scan_child_bus(vmd->bus);
vmd_domain_reset(vmd);
list_for_each_entry(child, &vmd->bus->children, node)
pci_reset_bus(child->self);

/* When Intel VMD is enabled, the OS does not discover the Root Ports
* owned by Intel VMD within the MMCFG space. pci_reset_bus() applies
* a reset to the parent of the PCI device supplied as argument. This
* is why we pass a child device, so the reset can be triggered at
* the Intel bridge level and propagated to all the children in the
* hierarchy.
*/
list_for_each_entry(child, &vmd->bus->children, node) {
if (!list_empty(&child->devices)) {
dev = list_first_entry(&child->devices,
struct pci_dev, bus_list);
if (pci_reset_bus(dev))
pci_warn(dev, "can't reset device: %d\n", ret);

break;
}
}

pci_assign_unassigned_bus_resources(vmd->bus);

/*
Expand Down Expand Up @@ -980,6 +998,11 @@ 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);

for (i = 0; i < vmd->msix_count; i++) {
err = devm_request_irq(dev, vmd->irqs[i].virq,
vmd_irq, IRQF_NO_THREAD,
Expand Down

0 comments on commit ba7deaa

Please sign in to comment.