diff --git a/msm/msm_smmu.c b/msm/msm_smmu.c index bc12cfb3ae..998445ad24 100644 --- a/msm/msm_smmu.c +++ b/msm/msm_smmu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -31,6 +32,7 @@ struct msm_smmu_client { struct device *dev; struct iommu_domain *domain; + const struct dma_map_ops *dma_ops; bool domain_attached; bool secure; }; @@ -65,6 +67,12 @@ static int msm_smmu_attach(struct msm_mmu *mmu, const char * const *names, if (client->domain_attached) return 0; + if (client->dma_ops) { + set_dma_ops(client->dev, client->dma_ops); + client->dma_ops = NULL; + dev_dbg(client->dev, "iommu domain ops restored\n"); + } + rc = iommu_attach_device(client->domain, client->dev); if (rc) { dev_err(client->dev, "iommu attach dev failed (%d)\n", rc); @@ -95,6 +103,13 @@ static void msm_smmu_detach(struct msm_mmu *mmu, const char * const *names, pm_runtime_get_sync(mmu->dev); msm_dma_unmap_all_for_dev(client->dev); iommu_detach_device(client->domain, client->dev); + + client->dma_ops = get_dma_ops(client->dev); + if (client->dma_ops) { + set_dma_ops(client->dev, NULL); + dev_dbg(client->dev, "iommu domain ops removed\n"); + } + pm_runtime_put_sync(mmu->dev); client->domain_attached = false;