summaryrefslogtreecommitdiffstats
path: root/drivers/pci/controller/vmd.c
diff options
context:
space:
mode:
authorKalle Valo <kvalo@kernel.org>2023-01-17 13:36:25 +0200
committerKalle Valo <kvalo@kernel.org>2023-01-17 13:36:25 +0200
commitd0e99511834b6828c960e978d9a8cb6e5731250d (patch)
treee7b062c1f9d28a55083477a1462286a7923a57fd /drivers/pci/controller/vmd.c
parentde7d0ff301fccc75281d7d8eb98c4a47faacf32d (diff)
parent80f8a66dede0a4b4e9e846765a97809c6fe49ce5 (diff)
downloadlinux-d0e99511834b6828c960e978d9a8cb6e5731250d.tar.gz
linux-d0e99511834b6828c960e978d9a8cb6e5731250d.tar.bz2
linux-d0e99511834b6828c960e978d9a8cb6e5731250d.zip
Merge wireless into wireless-next
Due to the two cherry picked commits from wireless to wireless-next we have several conflicts in mt76. To avoid any bugs with conflicts merge wireless into wireless-next. 96f134dc1964 wifi: mt76: handle possible mt76_rx_token_consume failures fe13dad8992b wifi: mt76: dma: do not increment queue head if mt76_dma_add_buf fails
Diffstat (limited to 'drivers/pci/controller/vmd.c')
-rw-r--r--drivers/pci/controller/vmd.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
index e06e9f4fc50f..769eedeb8802 100644
--- a/drivers/pci/controller/vmd.c
+++ b/drivers/pci/controller/vmd.c
@@ -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;
/*
@@ -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);
/*
@@ -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,