Merge tag 'usb-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
[linux-2.6-microblaze.git] / drivers / dma / idxd / init.c
index 993a5dc..355fb3e 100644 (file)
@@ -512,18 +512,15 @@ static int idxd_probe(struct idxd_device *idxd)
        dev_dbg(dev, "IDXD reset complete\n");
 
        if (IS_ENABLED(CONFIG_INTEL_IDXD_SVM) && sva) {
-               rc = iommu_dev_enable_feature(dev, IOMMU_DEV_FEAT_SVA);
-               if (rc == 0) {
-                       rc = idxd_enable_system_pasid(idxd);
-                       if (rc < 0) {
-                               iommu_dev_disable_feature(dev, IOMMU_DEV_FEAT_SVA);
-                               dev_warn(dev, "Failed to enable PASID. No SVA support: %d\n", rc);
-                       } else {
-                               set_bit(IDXD_FLAG_PASID_ENABLED, &idxd->flags);
-                       }
-               } else {
-                       dev_warn(dev, "Unable to turn on SVA feature.\n");
-               }
+               if (iommu_dev_enable_feature(dev, IOMMU_DEV_FEAT_SVA))
+                       dev_warn(dev, "Unable to turn on user SVA feature.\n");
+               else
+                       set_bit(IDXD_FLAG_USER_PASID_ENABLED, &idxd->flags);
+
+               if (idxd_enable_system_pasid(idxd))
+                       dev_warn(dev, "No in-kernel DMA with PASID.\n");
+               else
+                       set_bit(IDXD_FLAG_PASID_ENABLED, &idxd->flags);
        } else if (!sva) {
                dev_warn(dev, "User forced SVA off via module param.\n");
        }
@@ -561,7 +558,8 @@ static int idxd_probe(struct idxd_device *idxd)
  err:
        if (device_pasid_enabled(idxd))
                idxd_disable_system_pasid(idxd);
-       iommu_dev_disable_feature(dev, IOMMU_DEV_FEAT_SVA);
+       if (device_user_pasid_enabled(idxd))
+               iommu_dev_disable_feature(dev, IOMMU_DEV_FEAT_SVA);
        return rc;
 }
 
@@ -574,7 +572,8 @@ static void idxd_cleanup(struct idxd_device *idxd)
        idxd_cleanup_internals(idxd);
        if (device_pasid_enabled(idxd))
                idxd_disable_system_pasid(idxd);
-       iommu_dev_disable_feature(dev, IOMMU_DEV_FEAT_SVA);
+       if (device_user_pasid_enabled(idxd))
+               iommu_dev_disable_feature(dev, IOMMU_DEV_FEAT_SVA);
 }
 
 static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -691,7 +690,8 @@ static void idxd_remove(struct pci_dev *pdev)
        free_irq(irq_entry->vector, irq_entry);
        pci_free_irq_vectors(pdev);
        pci_iounmap(pdev, idxd->reg_base);
-       iommu_dev_disable_feature(&pdev->dev, IOMMU_DEV_FEAT_SVA);
+       if (device_user_pasid_enabled(idxd))
+               iommu_dev_disable_feature(&pdev->dev, IOMMU_DEV_FEAT_SVA);
        pci_disable_device(pdev);
        destroy_workqueue(idxd->wq);
        perfmon_pmu_remove(idxd);