Code cleanup in arch/powerpc/include/asm/dma-mapping.h and arch/powerpc/include/asm/io.h.
I replaced _dma_sync and _dma_sync_page with a new dma_mapping_ops API called sync: this is necessary to make sure that the proper synchronization mechanism is used for each device on a platform where multiple DMA architecture would co-exist. Removed the page_to_bus macro which is not used anymore. Added the hook to use the new dma-noncoherent code if CONFIG_NOT_COHERENT_CACHE is set. Signed-off-by: Remi Machet <[EMAIL PROTECTED]> --- dma-mapping.h | 69 ++++++++++++++++++++++++++++++---------------------------- io.h | 6 ----- 2 files changed, 36 insertions(+), 39 deletions(-) diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index fddb229..3328244 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -18,32 +18,6 @@ #define DMA_ERROR_CODE (~(dma_addr_t)0x0) -#ifdef CONFIG_NOT_COHERENT_CACHE -/* - * DMA-consistent mapping functions for PowerPCs that don't support - * cache snooping. These allocate/free a region of uncached mapped - * memory space for use with DMA devices. Alternatively, you could - * allocate the space "normally" and use the cache management functions - * to ensure it is consistent. - */ -extern void *__dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp); -extern void __dma_free_coherent(size_t size, void *vaddr); -extern void __dma_sync(void *vaddr, size_t size, int direction); -extern void __dma_sync_page(struct page *page, unsigned long offset, - size_t size, int direction); - -#else /* ! CONFIG_NOT_COHERENT_CACHE */ -/* - * Cache coherent cores. - */ - -#define __dma_alloc_coherent(gfp, size, handle) NULL -#define __dma_free_coherent(size, addr) ((void)0) -#define __dma_sync(addr, size, rw) ((void)0) -#define __dma_sync_page(pg, off, sz, rw) ((void)0) - -#endif /* ! CONFIG_NOT_COHERENT_CACHE */ - static inline unsigned long device_to_mask(struct device *dev) { if (dev->dma_mask && *dev->dma_mask) @@ -82,6 +56,8 @@ struct dma_mapping_ops { dma_addr_t dma_address, size_t size, enum dma_data_direction direction, struct dma_attrs *attrs); + void (*sync)(struct device *dev, dma_addr_t dma_address, + size_t size, enum dma_data_direction direction); }; /* @@ -90,6 +66,9 @@ struct dma_mapping_ops { #ifdef CONFIG_PPC64 extern struct dma_mapping_ops dma_iommu_ops; #endif +#ifdef CONFIG_NOT_COHERENT_CACHE +extern struct dma_mapping_ops dma_noncoherent_direct_ops; +#endif extern struct dma_mapping_ops dma_direct_ops; static inline struct dma_mapping_ops *get_dma_ops(struct device *dev) @@ -108,8 +87,12 @@ static inline struct dma_mapping_ops *get_dma_ops(struct device *dev) /* TODO: Long term, we should fix drivers so that dev and * archdata dma_ops are set up for all buses. */ +#ifdef CONFIG_NOT_COHERENT_CACHE + return &dma_noncoherent_direct_ops; +#else return &dma_direct_ops; #endif +#endif } return dev->archdata.dma_ops; @@ -168,6 +151,8 @@ static inline dma_addr_t dma_map_single_attrs(struct device *dev, return dma_ops->map_single(dev, cpu_addr, size, direction, attrs); + /* If vaddr is in high mem virt_to_page won't work */ + BUG_ON(!virt_addr_valid(cpu_addr)); return dma_ops->map_page(dev, virt_to_page(cpu_addr), (unsigned long)cpu_addr % PAGE_SIZE, size, direction, attrs); @@ -312,42 +297,54 @@ static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + BUG_ON(direction == DMA_NONE); - __dma_sync(bus_to_virt(dma_handle), size, direction); + if (dma_ops->sync != NULL) + dma_ops->sync(dev, dma_handle, size, direction); } static inline void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + BUG_ON(direction == DMA_NONE); - __dma_sync(bus_to_virt(dma_handle), size, direction); + if (dma_ops->sync != NULL) + dma_ops->sync(dev, dma_handle, size, direction); } static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl, int nents, enum dma_data_direction direction) { + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); struct scatterlist *sg; int i; BUG_ON(direction == DMA_NONE); - for_each_sg(sgl, sg, nents, i) - __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction); + if (dma_ops->sync != NULL) + for_each_sg(sgl, sg, nents, i) + dma_ops->sync(dev, sg->dma_address, + sg->dma_length, direction); } static inline void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sgl, int nents, enum dma_data_direction direction) { + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); struct scatterlist *sg; int i; BUG_ON(direction == DMA_NONE); - for_each_sg(sgl, sg, nents, i) - __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction); + if (dma_ops->sync != NULL) + for_each_sg(sgl, sg, nents, i) + dma_ops->sync(dev, sg->dma_address, + sg->dma_length, direction); } static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) @@ -401,8 +398,14 @@ static inline void dma_sync_single_range_for_device(struct device *dev, static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { + struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + BUG_ON(direction == DMA_NONE); - __dma_sync(vaddr, size, (int)direction); + if (dma_ops->sync != NULL) { + /* If vaddr is in high mem virt_to_page won't work */ + BUG_ON(!virt_addr_valid(vaddr)); + dma_ops->sync(dev, virt_to_bus(vaddr), size, direction); + } } #endif /* __KERNEL__ */ diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h index 77c7fa0..fdb54d6 100644 --- a/arch/powerpc/include/asm/io.h +++ b/arch/powerpc/include/asm/io.h @@ -726,8 +726,6 @@ static inline void * phys_to_virt(unsigned long address) * drivers (shame shame shame) that use bus_to_virt() and haven't been * fixed yet so I need to define it here. */ -#ifdef CONFIG_PPC32 - static inline unsigned long virt_to_bus(volatile void * address) { if (address == NULL) @@ -742,10 +740,6 @@ static inline void * bus_to_virt(unsigned long address) return __va(address - PCI_DRAM_OFFSET); } -#define page_to_bus(page) (page_to_phys(page) + PCI_DRAM_OFFSET) - -#endif /* CONFIG_PPC32 */ - /* access ports */ #define setbits32(_addr, _v) out_be32((_addr), in_be32(_addr) | (_v)) #define clrbits32(_addr, _v) out_be32((_addr), in_be32(_addr) & ~(_v)) _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev