drm/msm: Get rid of the MMU ->map_dma_buf and ->unmap_dma_buf funcs

Finish consolidating the MMU map and unmap operations into a single
function. By passing in the meta token to map/unmap the specific
SMMU operations can make a local decision as to which function to
call.

Change-Id: Ic0dedbad52aac6ed1317411b2667755794d1818f
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
This commit is contained in:
Jordan Crouse 2017-04-07 15:01:40 -06:00
parent 82fbc52e90
commit 438cdcdae0
4 changed files with 26 additions and 59 deletions

View file

@ -42,13 +42,8 @@ static void smmu_aspace_unmap_vma(struct msm_gem_address_space *aspace,
struct msm_gem_vma *vma, struct sg_table *sgt,
void *priv)
{
struct dma_buf *buf = priv;
if (buf)
aspace->mmu->funcs->unmap_dma_buf(aspace->mmu,
sgt, buf, DMA_BIDIRECTIONAL);
else
aspace->mmu->funcs->unmap(aspace->mmu, 0, sgt);
aspace->mmu->funcs->unmap(aspace->mmu, 0, sgt, priv);
vma->iova = 0;
@ -60,20 +55,15 @@ static int smmu_aspace_map_vma(struct msm_gem_address_space *aspace,
struct msm_gem_vma *vma, struct sg_table *sgt,
void *priv, unsigned int flags)
{
struct dma_buf *buf = priv;
int ret;
if (buf)
ret = aspace->mmu->funcs->map_dma_buf(aspace->mmu, sgt, buf,
DMA_BIDIRECTIONAL);
else
ret = aspace->mmu->funcs->map(aspace->mmu, 0, sgt, flags);
if (!ret)
ret = aspace->mmu->funcs->map(aspace->mmu, 0, sgt, flags, priv);
if (!ret) {
vma->iova = sg_dma_address(sgt->sgl);
/* Get a reference to the aspace to keep it around */
kref_get(&aspace->kref);
/* Get a reference to the aspace to keep it around */
kref_get(&aspace->kref);
}
return ret;
}
@ -122,7 +112,7 @@ static void iommu_aspace_unmap_vma(struct msm_gem_address_space *aspace,
return;
if (aspace->mmu)
aspace->mmu->funcs->unmap(aspace->mmu, vma->iova, sgt);
aspace->mmu->funcs->unmap(aspace->mmu, vma->iova, sgt, NULL);
drm_mm_remove_node(&vma->node);
@ -155,7 +145,7 @@ static int iommu_aspace_map_vma(struct msm_gem_address_space *aspace,
if (aspace->mmu)
ret = aspace->mmu->funcs->map(aspace->mmu, vma->iova, sgt,
flags);
flags, NULL);
/* Get a reference to the aspace to keep it around */
kref_get(&aspace->kref);

View file

@ -196,7 +196,7 @@ static void msm_iommu_detach_dynamic(struct msm_mmu *mmu)
}
static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
struct sg_table *sgt, u32 flags)
struct sg_table *sgt, u32 flags, void *priv)
{
struct msm_iommu *iommu = to_msm_iommu(mmu);
struct iommu_domain *domain = iommu->domain;
@ -224,7 +224,7 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
}
static void msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova,
struct sg_table *sgt)
struct sg_table *sgt, void *priv)
{
struct msm_iommu *iommu = to_msm_iommu(mmu);
struct iommu_domain *domain = iommu->domain;

View file

@ -34,12 +34,9 @@ struct msm_mmu_funcs {
int (*attach)(struct msm_mmu *mmu, const char **names, int cnt);
void (*detach)(struct msm_mmu *mmu);
int (*map)(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt,
u32 flags);
void (*unmap)(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt);
int (*map_dma_buf)(struct msm_mmu *mmu, struct sg_table *sgt,
struct dma_buf *dma_buf, int dir);
void (*unmap_dma_buf)(struct msm_mmu *mmu, struct sg_table *sgt,
struct dma_buf *dma_buf, int dir);
u32 flags, void *priv);
void (*unmap)(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt,
void *priv);
void (*destroy)(struct msm_mmu *mmu);
};

View file

@ -105,25 +105,34 @@ static void msm_smmu_detach(struct msm_mmu *mmu)
}
static int msm_smmu_map(struct msm_mmu *mmu, uint64_t iova,
struct sg_table *sgt, u32 flags)
struct sg_table *sgt, u32 flags, void *priv)
{
struct msm_smmu *smmu = to_msm_smmu(mmu);
struct msm_smmu_client *client = msm_smmu_to_client(smmu);
int ret;
ret = dma_map_sg(client->dev, sgt->sgl, sgt->nents,
if (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)
struct sg_table *sgt, void *priv)
{
struct msm_smmu *smmu = to_msm_smmu(mmu);
struct msm_smmu_client *client = msm_smmu_to_client(smmu);
dma_unmap_sg(client->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
if (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)
@ -136,40 +145,11 @@ static void msm_smmu_destroy(struct msm_mmu *mmu)
kfree(smmu);
}
static int msm_smmu_map_dma_buf(struct msm_mmu *mmu, struct sg_table *sgt,
struct dma_buf *dma_buf, int dir)
{
struct msm_smmu *smmu = to_msm_smmu(mmu);
struct msm_smmu_client *client = msm_smmu_to_client(smmu);
int ret;
ret = msm_dma_map_sg_lazy(client->dev, sgt->sgl, sgt->nents, dir,
dma_buf);
if (ret != sgt->nents) {
DRM_ERROR("dma map sg failed\n");
return -ENOMEM;
}
return 0;
}
static void msm_smmu_unmap_dma_buf(struct msm_mmu *mmu, struct sg_table *sgt,
struct dma_buf *dma_buf, int dir)
{
struct msm_smmu *smmu = to_msm_smmu(mmu);
struct msm_smmu_client *client = msm_smmu_to_client(smmu);
msm_dma_unmap_sg(client->dev, sgt->sgl, sgt->nents, dir, dma_buf);
}
static const struct msm_mmu_funcs funcs = {
.attach = msm_smmu_attach,
.detach = msm_smmu_detach,
.map = msm_smmu_map,
.unmap = msm_smmu_unmap,
.map_dma_buf = msm_smmu_map_dma_buf,
.unmap_dma_buf = msm_smmu_unmap_dma_buf,
.destroy = msm_smmu_destroy,
};