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

Commit 1ef0f00e authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "arm: dma-mapping: Add dma_remap functions"

parents c1e177d9 4a45a33a
Loading
Loading
Loading
Loading
+49 −0
Original line number Diff line number Diff line
@@ -116,6 +116,21 @@ static void __dma_page_cpu_to_dev(struct page *, unsigned long,
static void __dma_page_dev_to_cpu(struct page *, unsigned long,
		size_t, enum dma_data_direction);

static void *
__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
		const void *caller);

static void __dma_free_remap(void *cpu_addr, size_t size, bool no_warn);

static inline pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot);

static void *arm_dma_remap(struct device *dev, void *cpu_addr,
			dma_addr_t handle, size_t size,
			unsigned long attrs);

static void arm_dma_unremap(struct device *dev, void *remapped_addr,
				size_t size);

/**
 * arm_dma_map_page - map a portion of a page for streaming DMA
 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
@@ -197,6 +212,8 @@ struct dma_map_ops arm_dma_ops = {
	.sync_single_for_device	= arm_dma_sync_single_for_device,
	.sync_sg_for_cpu	= arm_dma_sync_sg_for_cpu,
	.sync_sg_for_device	= arm_dma_sync_sg_for_device,
	.remap			= arm_dma_remap,
	.unremap		= arm_dma_unremap,
};
EXPORT_SYMBOL(arm_dma_ops);

@@ -917,6 +934,38 @@ static int __arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
	return ret;
}

static void *arm_dma_remap(struct device *dev, void *cpu_addr,
			dma_addr_t handle, size_t size,
			unsigned long attrs)
{
	void *ptr;
	struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
	unsigned long offset = handle & ~PAGE_MASK;

	size = PAGE_ALIGN(size + offset);
	ptr = __dma_alloc_remap(page, size, GFP_KERNEL, prot,
			__builtin_return_address(0));
	return ptr ? ptr + offset : ptr;
}

static void arm_dma_unremap(struct device *dev, void *remapped_addr,
				size_t size)
{
	unsigned int flags = VM_ARM_DMA_CONSISTENT | VM_USERMAP;
	struct vm_struct *area;

	remapped_addr = (void *)((unsigned long)remapped_addr & PAGE_MASK);

	area = find_vm_area(remapped_addr);
	if (!area || (area->flags & flags) != flags) {
		WARN(1, "trying to free invalid coherent area: %p\n",
			remapped_addr);
		return;
	}

	vunmap(remapped_addr);
}
/*
 * Create userspace mapping for the DMA-coherent memory.
 */
+1 −1
Original line number Diff line number Diff line
@@ -306,7 +306,7 @@ void *dma_common_contiguous_remap(struct page *page, size_t size,
			unsigned long vm_flags,
			pgprot_t prot, const void *caller)
{
	int i;
	unsigned long i;
	struct page **pages;
	void *ptr;
	unsigned long pfn;