Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 14072e39 authored by Chintan Pandya's avatar Chintan Pandya Committed by Gerrit - the friendly Code Review server
Browse files

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: default avatarChintan Pandya <cpandya@codeaurora.org>
Signed-off-by: default avatarCharan Teja Reddy <charante@codeaurora.org>
Signed-off-by: default avatarVijayanand Jitta <vjitta@codeaurora.org>
Signed-off-by: default avatarQingqing Zhou <qqzhou@codeaurora.org>
parent 13f08bf5
Loading
Loading
Loading
Loading
+34 −2
Original line number Diff line number Diff line
@@ -1825,7 +1825,31 @@ 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;
		s->dma_length = total_length - current_offset;
		current_offset += s->length;
	}

	return nents;
}

static void __iommu_unmap_sg(struct device *dev, struct scatterlist *sg,
@@ -1876,7 +1900,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);
}

/**