Loading drivers/gpu/drm/msm/msm_smmu.c +42 −14 Original line number Diff line number Diff line Loading @@ -120,31 +120,59 @@ static int msm_smmu_map(struct msm_mmu *mmu, uint64_t iova, { struct msm_smmu *smmu = to_msm_smmu(mmu); struct msm_smmu_client *client = msm_smmu_to_client(smmu); struct iommu_domain *domain; int ret; if (!client || !sgt) return -EINVAL; if (iova != 0) { if (!client->mmu_mapping || !client->mmu_mapping->domain) return -EINVAL; domain = client->mmu_mapping->domain; return iommu_map_sg(domain, iova, sgt->sgl, sgt->nents, flags); } else { if (priv) ret = msm_dma_map_sg_lazy(client->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL, priv); ret = msm_dma_map_sg_lazy(client->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL, priv); else ret = dma_map_sg(client->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL); return (ret != sgt->nents) ? -ENOMEM : 0; } } static void msm_smmu_unmap(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt, void *priv) { struct msm_smmu *smmu = to_msm_smmu(mmu); struct msm_smmu_client *client = msm_smmu_to_client(smmu); struct iommu_domain *domain = client->mmu_mapping->domain; struct scatterlist *sg; size_t len = 0; int unmapped, i = 0; if (iova != 0) { for_each_sg(sgt->sgl, sg, sgt->nents, i) len += sg->length; unmapped = iommu_unmap(domain, iova, len); if (unmapped < len) dev_warn(mmu->dev, "could not unmap iova@%llx\n", iova); } else { if (priv) msm_dma_unmap_sg(client->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL, priv); msm_dma_unmap_sg(client->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL, priv); else dma_unmap_sg(client->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL); } } static void msm_smmu_destroy(struct msm_mmu *mmu) { Loading Loading
drivers/gpu/drm/msm/msm_smmu.c +42 −14 Original line number Diff line number Diff line Loading @@ -120,31 +120,59 @@ static int msm_smmu_map(struct msm_mmu *mmu, uint64_t iova, { struct msm_smmu *smmu = to_msm_smmu(mmu); struct msm_smmu_client *client = msm_smmu_to_client(smmu); struct iommu_domain *domain; int ret; if (!client || !sgt) return -EINVAL; if (iova != 0) { if (!client->mmu_mapping || !client->mmu_mapping->domain) return -EINVAL; domain = client->mmu_mapping->domain; return iommu_map_sg(domain, iova, sgt->sgl, sgt->nents, flags); } else { if (priv) ret = msm_dma_map_sg_lazy(client->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL, priv); ret = msm_dma_map_sg_lazy(client->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL, priv); else ret = dma_map_sg(client->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL); return (ret != sgt->nents) ? -ENOMEM : 0; } } static void msm_smmu_unmap(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt, void *priv) { struct msm_smmu *smmu = to_msm_smmu(mmu); struct msm_smmu_client *client = msm_smmu_to_client(smmu); struct iommu_domain *domain = client->mmu_mapping->domain; struct scatterlist *sg; size_t len = 0; int unmapped, i = 0; if (iova != 0) { for_each_sg(sgt->sgl, sg, sgt->nents, i) len += sg->length; unmapped = iommu_unmap(domain, iova, len); if (unmapped < len) dev_warn(mmu->dev, "could not unmap iova@%llx\n", iova); } else { if (priv) msm_dma_unmap_sg(client->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL, priv); msm_dma_unmap_sg(client->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL, priv); else dma_unmap_sg(client->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL); } } static void msm_smmu_destroy(struct msm_mmu *mmu) { Loading