From 1d7cddf956a9a4be550b7bd4fc282a1ca362c8e2 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 23 Jun 2004 19:25:06 -0700 Subject: [PATCH] sh: dma-mapping updates. From: Paul Mundt This updates the sh dma-mapping code, as well as doing some cleanup in the consistent API. We also add a consistent_{alloc,free} to the machvec for platforms that need special handling. Signed-off-by: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/mm/consistent.c | 40 +++++++++++++++++++++------------------- include/asm-sh/dma-mapping.h | 32 ++++++++++++++++++++++++++++++++ include/asm-sh/machvec.h | 4 ++++ 3 files changed, 57 insertions(+), 19 deletions(-) diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c index f988035c7c86..789bacf1a7aa 100644 --- a/arch/sh/mm/consistent.c +++ b/arch/sh/mm/consistent.c @@ -24,56 +24,58 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle) if (!page) return NULL; - ret = (void *)P2SEGADDR(page_to_bus(page)); + ret = page_address(page); + *handle = virt_to_phys(ret); /* * We must flush the cache before we pass it on to the device */ dma_cache_wback_inv(ret, size); - *handle = (unsigned long)ret; - + page = virt_to_page(ret); free = page + (size >> PAGE_SHIFT); end = page + (1 << order); - do { + while (++page < end) { set_page_count(page, 1); - page++; - } while (size -= PAGE_SIZE); - /* - * Free any unused pages - */ - while (page < end) { - set_page_count(page, 1); - __free_page(page); - page++; + /* Free any unused pages */ + if (page >= free) { + __free_page(page); + } } - return ret; + return P2SEGADDR(ret); } void consistent_free(void *vaddr, size_t size) { 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; - free_pages(addr, get_order(size)); + for(i=0;ibus == &pci_bus_type) return __pci_alloc_consistent(NULL, size, dma_handle); #endif + if (sh_mv.mv_consistent_alloc) + return sh_mv.mv_consistent_alloc(dev, size, dma_handle, flag); return consistent_alloc(flag, size, dma_handle); } @@ -61,6 +63,11 @@ static inline void dma_free_coherent(struct device *dev, size_t size, } #endif + if (sh_mv.mv_consistent_free) { + sh_mv.mv_consistent_free(dev, size, vaddr, dma_handle); + return; + } + consistent_free(vaddr, size); } @@ -152,6 +159,26 @@ static inline void dma_sync_sg(struct device *dev, struct scatterlist *sg, } } +static inline void dma_sync_single_for_cpu(struct device *dev, + dma_addr_t dma_handle, size_t size, + enum dma_data_direction dir) + __attribute__ ((alias("dma_sync_single"))); + +static inline void dma_sync_single_for_device(struct device *dev, + dma_addr_t dma_handle, size_t size, + enum dma_data_direction dir) + __attribute__ ((alias("dma_sync_single"))); + +static inline void dma_sync_sg_for_cpu(struct device *dev, + struct scatterlist *sg, int nelems, + enum dma_data_direction dir) + __attribute__ ((alias("dma_sync_sg"))); + +static inline void dma_sync_sg_for_device(struct device *dev, + struct scatterlist *sg, int nelems, + enum dma_data_direction dir) + __attribute__ ((alias("dma_sync_sg"))); + static inline int dma_get_cache_alignment(void) { /* @@ -161,5 +188,10 @@ static inline int dma_get_cache_alignment(void) return L1_CACHE_BYTES; } +static inline int dma_mapping_error(dma_addr_t dma_addr) +{ + return dma_addr == 0; +} + #endif /* __ASM_SH_DMA_MAPPING_H */ diff --git a/include/asm-sh/machvec.h b/include/asm-sh/machvec.h index 4953570c961d..8a2e3dcd1779 100644 --- a/include/asm-sh/machvec.h +++ b/include/asm-sh/machvec.h @@ -17,6 +17,7 @@ #include #include +struct device; struct timeval; struct sh_machine_vector @@ -62,6 +63,9 @@ struct sh_machine_vector void (*mv_init_pci)(void); void (*mv_heartbeat)(void); + + void *(*mv_consistent_alloc)(struct device *, size_t, dma_addr_t *, int); + void (*mv_consistent_free)(struct device *, size_t, void *, dma_addr_t); }; extern struct sh_machine_vector sh_mv; -- cgit v1.2.3