This brings back the ops->detach_dev() code that commit
1b932ceddd19 ("iommu: Remove detach_dev callbacks") deleted and turns it
into an IDENTITY domain.

Signed-off-by: Jason Gunthorpe <j...@nvidia.com>
---
 drivers/iommu/arm/arm-smmu/qcom_iommu.c | 39 +++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c 
b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index a503ed758ec302..9d7b9d8b4386d4 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -387,6 +387,44 @@ static int qcom_iommu_attach_dev(struct iommu_domain 
*domain, struct device *dev
        return 0;
 }
 
+static int qcom_iommu_identity_attach(struct iommu_domain *identity_domain,
+                                     struct device *dev)
+{
+       struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
+       struct qcom_iommu_domain *qcom_domain;
+       struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+       struct qcom_iommu_dev *qcom_iommu = to_iommu(dev);
+       unsigned int i;
+
+       if (domain == identity_domain || !domain)
+               return 0;
+
+       qcom_domain = to_qcom_iommu_domain(domain);
+       if (WARN_ON(!qcom_domain->iommu))
+               return -EINVAL;
+
+       pm_runtime_get_sync(qcom_iommu->dev);
+       for (i = 0; i < fwspec->num_ids; i++) {
+               struct qcom_iommu_ctx *ctx = to_ctx(qcom_domain, 
fwspec->ids[i]);
+
+               /* Disable the context bank: */
+               iommu_writel(ctx, ARM_SMMU_CB_SCTLR, 0);
+
+               ctx->domain = NULL;
+       }
+       pm_runtime_put_sync(qcom_iommu->dev);
+       return 0;
+}
+
+static struct iommu_domain_ops qcom_iommu_identity_ops = {
+       .attach_dev = qcom_iommu_identity_attach,
+};
+
+static struct iommu_domain qcom_iommu_identity_domain = {
+       .type = IOMMU_DOMAIN_IDENTITY,
+       .ops = &qcom_iommu_identity_ops,
+};
+
 static int qcom_iommu_map(struct iommu_domain *domain, unsigned long iova,
                          phys_addr_t paddr, size_t pgsize, size_t pgcount,
                          int prot, gfp_t gfp, size_t *mapped)
@@ -553,6 +591,7 @@ static int qcom_iommu_of_xlate(struct device *dev, struct 
of_phandle_args *args)
 }
 
 static const struct iommu_ops qcom_iommu_ops = {
+       .identity_domain = &qcom_iommu_identity_domain,
        .capable        = qcom_iommu_capable,
        .domain_alloc   = qcom_iommu_domain_alloc,
        .probe_device   = qcom_iommu_probe_device,
-- 
2.40.1

Reply via email to