mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 07:37:31 -04:00
arm: dma-mapping: map sg lists into the SMMU as virtually contiguous
In arm_iommu_map_sg, currently we map each individual link in the given scatterlist into the SMMU individually such that they may or may not be virtually contiguous. However, in most of our use cases we actually want the entire sg list mapped into the SMMU as a single contiguous range. This was missing for arm 32bit, add it. Change-Id: Ibf67f29a60b8d19e526c4719590f2f473ea9dca5 Signed-off-by: Chintan Pandya <cpandya@codeaurora.org> Signed-off-by: Charan Teja Reddy <charante@codeaurora.org> Signed-off-by: Vijayanand Jitta <vjitta@codeaurora.org> Signed-off-by: Qingqing Zhou <qqzhou@codeaurora.org>
This commit is contained in:
parent
de79fc71ee
commit
832decaf00
1 changed files with 37 additions and 2 deletions
|
|
@ -1751,7 +1751,34 @@ int arm_coherent_iommu_map_sg(struct device *dev, struct scatterlist *sg,
|
|||
int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg,
|
||||
int nents, enum dma_data_direction dir, unsigned long attrs)
|
||||
{
|
||||
return __iommu_map_sg(dev, sg, nents, dir, attrs, false);
|
||||
struct scatterlist *s;
|
||||
int i;
|
||||
size_t ret;
|
||||
struct dma_iommu_mapping *mapping = dev->archdata.mapping;
|
||||
unsigned int total_length = 0, current_offset = 0;
|
||||
dma_addr_t iova;
|
||||
int prot = __dma_info_to_prot(dir, attrs);
|
||||
|
||||
for_each_sg(sg, s, nents, i)
|
||||
total_length += s->length;
|
||||
|
||||
iova = __alloc_iova(mapping, total_length);
|
||||
ret = iommu_map_sg(mapping->domain, iova, sg, nents, prot);
|
||||
if (ret != total_length) {
|
||||
__free_iova(mapping, iova, total_length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for_each_sg(sg, s, nents, i) {
|
||||
s->dma_address = iova + current_offset;
|
||||
if (i == 0)
|
||||
s->dma_length = total_length;
|
||||
else
|
||||
s->dma_length = 0;
|
||||
current_offset += s->length;
|
||||
}
|
||||
|
||||
return nents;
|
||||
}
|
||||
|
||||
static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
|
||||
|
|
@ -1802,7 +1829,15 @@ void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
|
|||
enum dma_data_direction dir,
|
||||
unsigned long attrs)
|
||||
{
|
||||
__iommu_unmap_sg(dev, sg, nents, dir, attrs, false);
|
||||
struct dma_iommu_mapping *mapping = dev->archdata.mapping;
|
||||
unsigned int total_length = sg_dma_len(sg);
|
||||
dma_addr_t iova = sg_dma_address(sg);
|
||||
|
||||
total_length = PAGE_ALIGN((iova & ~PAGE_MASK) + total_length);
|
||||
iova &= PAGE_MASK;
|
||||
|
||||
iommu_unmap(mapping->domain, iova, total_length);
|
||||
__free_iova(mapping, iova, total_length);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue