diff options
author | Rob Clark <robdclark@gmail.com> | 2017-02-15 21:44:04 +0100 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2017-04-08 12:59:31 +0200 |
commit | f90000492ed8df9cb0214e7551a43a2be170db7a (patch) | |
tree | 28a9bbad07e5a5ec46ee73a171edab10ce101632 /drivers/gpu/drm/msm/msm_iommu.c | |
parent | drm/msm/adreno: reset ringbuffer in hw_init (diff) | |
download | linux-f90000492ed8df9cb0214e7551a43a2be170db7a.tar.xz linux-f90000492ed8df9cb0214e7551a43a2be170db7a.zip |
drm/msm: convert to iommu_map_sg
Significantly simplifies things. Also iommu_unmap() can unmap an entire
iova range.
(If backporting to downstream kernel you might need to revert this. Or
at least double check older iommu implementation.)
Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm/msm_iommu.c')
-rw-r--r-- | drivers/gpu/drm/msm/msm_iommu.c | 54 |
1 files changed, 5 insertions, 49 deletions
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index 7f5779daf5c8..6583fadc6e5b 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c @@ -52,64 +52,20 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt, unsigned len, int prot) { struct msm_iommu *iommu = to_msm_iommu(mmu); - struct iommu_domain *domain = iommu->domain; - struct scatterlist *sg; - unsigned long da = iova; - unsigned int i, j; - int ret; + size_t ret; - if (!domain || !sgt) - return -EINVAL; + ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot); + WARN_ON(ret < 0); - for_each_sg(sgt->sgl, sg, sgt->nents, i) { - dma_addr_t pa = sg_phys(sg) - sg->offset; - size_t bytes = sg->length + sg->offset; - - VERB("map[%d]: %08lx %08lx(%zx)", i, da, (unsigned long)pa, bytes); - - ret = iommu_map(domain, da, pa, bytes, prot); - if (ret) - goto fail; - - da += bytes; - } - - return 0; - -fail: - da = iova; - - for_each_sg(sgt->sgl, sg, i, j) { - size_t bytes = sg->length + sg->offset; - iommu_unmap(domain, da, bytes); - da += bytes; - } - return ret; + return (ret == len) ? 0 : -EINVAL; } static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt, unsigned len) { struct msm_iommu *iommu = to_msm_iommu(mmu); - struct iommu_domain *domain = iommu->domain; - struct scatterlist *sg; - unsigned long da = iova; - int i; - - for_each_sg(sgt->sgl, sg, sgt->nents, i) { - size_t bytes = sg->length + sg->offset; - size_t unmapped; - - unmapped = iommu_unmap(domain, da, bytes); - if (unmapped < bytes) - return unmapped; - - VERB("unmap[%d]: %08lx(%zx)", i, da, bytes); - - BUG_ON(!PAGE_ALIGNED(bytes)); - da += bytes; - } + iommu_unmap(iommu->domain, iova, len); return 0; } |