Merge tag 'dmaengine-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul...
[platform/kernel/linux-starfive.git] / drivers / dma / idxd / init.c
index 92f60d3..1aa8239 100644 (file)
@@ -110,7 +110,7 @@ static int idxd_setup_interrupts(struct idxd_device *idxd)
                ie = idxd_get_ie(idxd, msix_idx);
                ie->id = msix_idx;
                ie->int_handle = INVALID_INT_HANDLE;
-               ie->pasid = INVALID_IOASID;
+               ie->pasid = IOMMU_PASID_INVALID;
 
                spin_lock_init(&ie->list_lock);
                init_llist_head(&ie->pending_llist);
@@ -560,6 +560,27 @@ static void idxd_disable_system_pasid(struct idxd_device *idxd)
        idxd->sva = NULL;
 }
 
+static int idxd_enable_sva(struct pci_dev *pdev)
+{
+       int ret;
+
+       ret = iommu_dev_enable_feature(&pdev->dev, IOMMU_DEV_FEAT_IOPF);
+       if (ret)
+               return ret;
+
+       ret = iommu_dev_enable_feature(&pdev->dev, IOMMU_DEV_FEAT_SVA);
+       if (ret)
+               iommu_dev_disable_feature(&pdev->dev, IOMMU_DEV_FEAT_IOPF);
+
+       return ret;
+}
+
+static void idxd_disable_sva(struct pci_dev *pdev)
+{
+       iommu_dev_disable_feature(&pdev->dev, IOMMU_DEV_FEAT_SVA);
+       iommu_dev_disable_feature(&pdev->dev, IOMMU_DEV_FEAT_IOPF);
+}
+
 static int idxd_probe(struct idxd_device *idxd)
 {
        struct pci_dev *pdev = idxd->pdev;
@@ -574,7 +595,7 @@ static int idxd_probe(struct idxd_device *idxd)
        dev_dbg(dev, "IDXD reset complete\n");
 
        if (IS_ENABLED(CONFIG_INTEL_IDXD_SVM) && sva) {
-               if (iommu_dev_enable_feature(dev, IOMMU_DEV_FEAT_SVA)) {
+               if (idxd_enable_sva(pdev)) {
                        dev_warn(dev, "Unable to turn on user SVA feature.\n");
                } else {
                        set_bit(IDXD_FLAG_USER_PASID_ENABLED, &idxd->flags);
@@ -622,21 +643,19 @@ static int idxd_probe(struct idxd_device *idxd)
        if (device_pasid_enabled(idxd))
                idxd_disable_system_pasid(idxd);
        if (device_user_pasid_enabled(idxd))
-               iommu_dev_disable_feature(dev, IOMMU_DEV_FEAT_SVA);
+               idxd_disable_sva(pdev);
        return rc;
 }
 
 static void idxd_cleanup(struct idxd_device *idxd)
 {
-       struct device *dev = &idxd->pdev->dev;
-
        perfmon_pmu_remove(idxd);
        idxd_cleanup_interrupts(idxd);
        idxd_cleanup_internals(idxd);
        if (device_pasid_enabled(idxd))
                idxd_disable_system_pasid(idxd);
        if (device_user_pasid_enabled(idxd))
-               iommu_dev_disable_feature(dev, IOMMU_DEV_FEAT_SVA);
+               idxd_disable_sva(idxd->pdev);
 }
 
 static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -759,7 +778,7 @@ static void idxd_remove(struct pci_dev *pdev)
        pci_free_irq_vectors(pdev);
        pci_iounmap(pdev, idxd->reg_base);
        if (device_user_pasid_enabled(idxd))
-               iommu_dev_disable_feature(&pdev->dev, IOMMU_DEV_FEAT_SVA);
+               idxd_disable_sva(pdev);
        pci_disable_device(pdev);
        destroy_workqueue(idxd->wq);
        perfmon_pmu_remove(idxd);