diff options
Diffstat (limited to 'arch/arc/mm/dma.c')
| -rw-r--r-- | arch/arc/mm/dma.c | 140 | 
1 files changed, 13 insertions, 127 deletions
| diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c index 08d91c13ac52..8c1071840979 100644 --- a/arch/arc/mm/dma.c +++ b/arch/arc/mm/dma.c @@ -16,13 +16,12 @@   * The default DMA address == Phy address which is 0x8000_0000 based.   */ -#include <linux/dma-mapping.h> +#include <linux/dma-noncoherent.h>  #include <asm/cache.h>  #include <asm/cacheflush.h> - -static void *arc_dma_alloc(struct device *dev, size_t size, -		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) +void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, +		gfp_t gfp, unsigned long attrs)  {  	unsigned long order = get_order(size);  	struct page *page; @@ -89,7 +88,7 @@ static void *arc_dma_alloc(struct device *dev, size_t size,  	return kvaddr;  } -static void arc_dma_free(struct device *dev, size_t size, void *vaddr, +void arch_dma_free(struct device *dev, size_t size, void *vaddr,  		dma_addr_t dma_handle, unsigned long attrs)  {  	phys_addr_t paddr = dma_handle; @@ -105,9 +104,9 @@ static void arc_dma_free(struct device *dev, size_t size, void *vaddr,  	__free_pages(page, get_order(size));  } -static int arc_dma_mmap(struct device *dev, struct vm_area_struct *vma, -			void *cpu_addr, dma_addr_t dma_addr, size_t size, -			unsigned long attrs) +int arch_dma_mmap(struct device *dev, struct vm_area_struct *vma, +		void *cpu_addr, dma_addr_t dma_addr, size_t size, +		unsigned long attrs)  {  	unsigned long user_count = vma_pages(vma);  	unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT; @@ -130,127 +129,14 @@ static int arc_dma_mmap(struct device *dev, struct vm_area_struct *vma,  	return ret;  } -static void arc_dma_sync_single_for_device(struct device *dev, -		dma_addr_t dma_handle, size_t size, enum dma_data_direction dir) -{ -	dma_cache_wback(dma_handle, size); -} - -static void arc_dma_sync_single_for_cpu(struct device *dev, -		dma_addr_t dma_handle, size_t size, enum dma_data_direction dir) -{ -	dma_cache_inv(dma_handle, size); -} - -/* - * arc_dma_map_page - map a portion of a page for streaming DMA - * - * Ensure that any data held in the cache is appropriately discarded - * or written back. - * - * The device owns this memory once this call has completed.  The CPU - * can regain ownership by calling dma_unmap_page(). - * - * Note: while it takes struct page as arg, caller can "abuse" it to pass - * a region larger than PAGE_SIZE, provided it is physically contiguous - * and this still works correctly - */ -static dma_addr_t arc_dma_map_page(struct device *dev, struct page *page, -		unsigned long offset, size_t size, enum dma_data_direction dir, -		unsigned long attrs) -{ -	phys_addr_t paddr = page_to_phys(page) + offset; - -	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) -		arc_dma_sync_single_for_device(dev, paddr, size, dir); - -	return paddr; -} - -/* - * arc_dma_unmap_page - unmap a buffer previously mapped through dma_map_page() - * - * After this call, reads by the CPU to the buffer are guaranteed to see - * whatever the device wrote there. - * - * Note: historically this routine was not implemented for ARC - */ -static void arc_dma_unmap_page(struct device *dev, dma_addr_t handle, -			       size_t size, enum dma_data_direction dir, -			       unsigned long attrs) -{ -	phys_addr_t paddr = handle; - -	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) -		arc_dma_sync_single_for_cpu(dev, paddr, size, dir); -} - -static int arc_dma_map_sg(struct device *dev, struct scatterlist *sg, -	   int nents, enum dma_data_direction dir, unsigned long attrs) +void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, +		size_t size, enum dma_data_direction dir)  { -	struct scatterlist *s; -	int i; - -	for_each_sg(sg, s, nents, i) -		s->dma_address = dma_map_page(dev, sg_page(s), s->offset, -					       s->length, dir); - -	return nents; +	dma_cache_wback(paddr, size);  } -static void arc_dma_unmap_sg(struct device *dev, struct scatterlist *sg, -			     int nents, enum dma_data_direction dir, -			     unsigned long attrs) +void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, +		size_t size, enum dma_data_direction dir)  { -	struct scatterlist *s; -	int i; - -	for_each_sg(sg, s, nents, i) -		arc_dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir, -				   attrs); +	dma_cache_inv(paddr, size);  } - -static void arc_dma_sync_sg_for_cpu(struct device *dev, -		struct scatterlist *sglist, int nelems, -		enum dma_data_direction dir) -{ -	int i; -	struct scatterlist *sg; - -	for_each_sg(sglist, sg, nelems, i) -		arc_dma_sync_single_for_cpu(dev, sg_phys(sg), sg->length, dir); -} - -static void arc_dma_sync_sg_for_device(struct device *dev, -		struct scatterlist *sglist, int nelems, -		enum dma_data_direction dir) -{ -	int i; -	struct scatterlist *sg; - -	for_each_sg(sglist, sg, nelems, i) -		arc_dma_sync_single_for_device(dev, sg_phys(sg), sg->length, -				dir); -} - -static int arc_dma_supported(struct device *dev, u64 dma_mask) -{ -	/* Support 32 bit DMA mask exclusively */ -	return dma_mask == DMA_BIT_MASK(32); -} - -const struct dma_map_ops arc_dma_ops = { -	.alloc			= arc_dma_alloc, -	.free			= arc_dma_free, -	.mmap			= arc_dma_mmap, -	.map_page		= arc_dma_map_page, -	.unmap_page		= arc_dma_unmap_page, -	.map_sg			= arc_dma_map_sg, -	.unmap_sg		= arc_dma_unmap_sg, -	.sync_single_for_device	= arc_dma_sync_single_for_device, -	.sync_single_for_cpu	= arc_dma_sync_single_for_cpu, -	.sync_sg_for_cpu	= arc_dma_sync_sg_for_cpu, -	.sync_sg_for_device	= arc_dma_sync_sg_for_device, -	.dma_supported		= arc_dma_supported, -}; -EXPORT_SYMBOL(arc_dma_ops); | 
