Commit 8a7bcf0d authored by Paul Mundt's avatar Paul Mundt
Browse files

sh: Add SH-5 support to the consistent DMA impl.



Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent b613881e
Loading
Loading
Loading
Loading
+28 −18
Original line number Diff line number Diff line
/*
 * arch/sh/mm/consistent.c
 *
 * Copyright (C) 2004  Paul Mundt
 * Copyright (C) 2004 - 2007  Paul Mundt
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
@@ -16,7 +16,7 @@
void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle)
{
	struct page *page, *end, *free;
	void *ret;
	void *ret, *vp;
	int order;

	size = PAGE_ALIGN(size);
@@ -28,13 +28,20 @@ void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle)
	split_page(page, order);

	ret = page_address(page);
	memset(ret, 0, size);
	*handle = virt_to_phys(ret);

	vp = ioremap_nocache(*handle, size);
	if (!vp) {
		free_pages((unsigned long)ret, order);
		return NULL;
	}

	memset(vp, 0, size);

	/*
	 * We must flush the cache before we pass it on to the device
	 */
	__flush_purge_region(ret, size);
	dma_cache_sync(NULL, ret, size, DMA_BIDIRECTIONAL);

	page = virt_to_page(ret);
	free = page + (size >> PAGE_SHIFT);
@@ -47,24 +54,31 @@ void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle)
		}
	}

	return P2SEGADDR(ret);
	return vp;
}
EXPORT_SYMBOL(consistent_alloc);

void consistent_free(void *vaddr, size_t size)
void consistent_free(void *vaddr, size_t size, dma_addr_t dma_handle)
{
	unsigned long addr = P1SEGADDR((unsigned long)vaddr);
	struct page *page=virt_to_page(addr);
	int num_pages=(size+PAGE_SIZE-1) >> PAGE_SHIFT;
	int i;
	struct page *page;
	unsigned long addr;

	for(i=0;i<num_pages;i++) {
		__free_page((page+i));
	}
	addr = (unsigned long)phys_to_virt((unsigned long)dma_handle);
	page = virt_to_page(addr);

	free_pages(addr, get_order(size));

	iounmap(vaddr);
}
EXPORT_SYMBOL(consistent_free);

void consistent_sync(void *vaddr, size_t size, int direction)
{
#ifdef CONFIG_CPU_SH5
	void *p1addr = vaddr;
#else
	void *p1addr = (void*) P1SEGADDR((unsigned long)vaddr);
#endif

	switch (direction) {
	case DMA_FROM_DEVICE:		/* invalidate only */
@@ -80,8 +94,4 @@ void consistent_sync(void *vaddr, size_t size, int direction)
		BUG();
	}
}

EXPORT_SYMBOL(consistent_alloc);
EXPORT_SYMBOL(consistent_free);
EXPORT_SYMBOL(consistent_sync);
+2 −2
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ extern struct bus_type pci_bus_type;

/* arch/sh/mm/consistent.c */
extern void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle);
extern void consistent_free(void *vaddr, size_t size);
extern void consistent_free(void *vaddr, size_t size, dma_addr_t handle);
extern void consistent_sync(void *vaddr, size_t size, int direction);

#define dma_supported(dev, mask)	(1)
@@ -50,7 +50,7 @@ static inline void dma_free_coherent(struct device *dev, size_t size,
			return;
	}

	consistent_free(vaddr, size);
	consistent_free(vaddr, size, dma_handle);
}

#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)