Loading arch/sh/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ config SUPERH select HAVE_GENERIC_DMA_COHERENT select HAVE_IOREMAP_PROT if MMU select HAVE_ARCH_TRACEHOOK select HAVE_DMA_API_DEBUG help The SuperH is a RISC processor targeted for use in embedded systems and consumer electronics; it was also used in the Sega Dreamcast Loading arch/sh/include/asm/dma-mapping.h +31 −5 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ #include <linux/mm.h> #include <linux/scatterlist.h> #include <linux/dma-debug.h> #include <asm/cacheflush.h> #include <asm/io.h> #include <asm-generic/dma-coherent.h> Loading Loading @@ -38,16 +39,26 @@ static inline dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, enum dma_data_direction dir) { dma_addr_t addr = virt_to_phys(ptr); #if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT) if (dev->bus == &pci_bus_type) return virt_to_phys(ptr); return addr; #endif dma_cache_sync(dev, ptr, size, dir); return virt_to_phys(ptr); debug_dma_map_page(dev, virt_to_page(ptr), (unsigned long)ptr & ~PAGE_MASK, size, dir, addr, true); return addr; } #define dma_unmap_single(dev, addr, size, dir) do { } while (0) static inline void dma_unmap_single(struct device *dev, dma_addr_t addr, size_t size, enum dma_data_direction dir) { debug_dma_unmap_page(dev, addr, size, dir, true); } static inline int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir) Loading @@ -59,12 +70,19 @@ static inline int dma_map_sg(struct device *dev, struct scatterlist *sg, dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir); #endif sg[i].dma_address = sg_phys(&sg[i]); sg[i].dma_length = sg[i].length; } debug_dma_map_sg(dev, sg, nents, i, dir); return nents; } #define dma_unmap_sg(dev, sg, nents, dir) do { } while (0) static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir) { debug_dma_unmap_sg(dev, sg, nents, dir); } static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, Loading Loading @@ -111,6 +129,7 @@ static inline void dma_sync_sg(struct device *dev, struct scatterlist *sg, dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir); #endif sg[i].dma_address = sg_phys(&sg[i]); sg[i].dma_length = sg[i].length; } } Loading @@ -119,6 +138,7 @@ static inline void dma_sync_single_for_cpu(struct device *dev, enum dma_data_direction dir) { dma_sync_single(dev, dma_handle, size, dir); debug_dma_sync_single_for_cpu(dev, dma_handle, size, dir); } static inline void dma_sync_single_for_device(struct device *dev, Loading @@ -127,6 +147,7 @@ static inline void dma_sync_single_for_device(struct device *dev, enum dma_data_direction dir) { dma_sync_single(dev, dma_handle, size, dir); debug_dma_sync_single_for_device(dev, dma_handle, size, dir); } static inline void dma_sync_single_range_for_cpu(struct device *dev, Loading @@ -136,6 +157,8 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev, enum dma_data_direction direction) { dma_sync_single_for_cpu(dev, dma_handle+offset, size, direction); debug_dma_sync_single_range_for_cpu(dev, dma_handle, offset, size, direction); } static inline void dma_sync_single_range_for_device(struct device *dev, Loading @@ -145,6 +168,8 @@ static inline void dma_sync_single_range_for_device(struct device *dev, enum dma_data_direction direction) { dma_sync_single_for_device(dev, dma_handle+offset, size, direction); debug_dma_sync_single_range_for_device(dev, dma_handle, offset, size, direction); } Loading @@ -153,6 +178,7 @@ static inline void dma_sync_sg_for_cpu(struct device *dev, enum dma_data_direction dir) { dma_sync_sg(dev, sg, nelems, dir); debug_dma_sync_sg_for_cpu(dev, sg, nelems, dir); } static inline void dma_sync_sg_for_device(struct device *dev, Loading @@ -160,9 +186,9 @@ static inline void dma_sync_sg_for_device(struct device *dev, enum dma_data_direction dir) { dma_sync_sg(dev, sg, nelems, dir); debug_dma_sync_sg_for_device(dev, sg, nelems, dir); } static inline int dma_get_cache_alignment(void) { /* Loading arch/sh/include/asm/scatterlist.h +6 −5 Original line number Diff line number Diff line Loading @@ -9,8 +9,9 @@ struct scatterlist { #endif unsigned long page_link; unsigned int offset; /* for highmem, page offset */ dma_addr_t dma_address; unsigned int length; dma_addr_t dma_address; unsigned int dma_length; }; #define ISA_DMA_THRESHOLD PHYS_ADDR_MASK Loading arch/sh/mm/consistent.c +13 −6 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include <linux/mm.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> #include <linux/dma-debug.h> #include <asm/cacheflush.h> #include <asm/addrspace.h> #include <asm/io.h> Loading Loading @@ -45,6 +46,9 @@ void *dma_alloc_coherent(struct device *dev, size_t size, split_page(pfn_to_page(virt_to_phys(ret) >> PAGE_SHIFT), order); *dma_handle = virt_to_phys(ret); debug_dma_alloc_coherent(dev, size, *dma_handle, ret_nocache); return ret_nocache; } EXPORT_SYMBOL(dma_alloc_coherent); Loading @@ -56,13 +60,16 @@ void dma_free_coherent(struct device *dev, size_t size, unsigned long pfn = dma_handle >> PAGE_SHIFT; int k; if (!dma_release_from_coherent(dev, order, vaddr)) { WARN_ON(irqs_disabled()); /* for portability */ if (dma_release_from_coherent(dev, order, vaddr)) return; debug_dma_free_coherent(dev, size, vaddr, dma_handle); for (k = 0; k < (1 << order); k++) __free_pages(pfn_to_page(pfn + k), 0); iounmap(vaddr); } } EXPORT_SYMBOL(dma_free_coherent); void dma_cache_sync(struct device *dev, void *vaddr, size_t size, Loading Loading
arch/sh/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ config SUPERH select HAVE_GENERIC_DMA_COHERENT select HAVE_IOREMAP_PROT if MMU select HAVE_ARCH_TRACEHOOK select HAVE_DMA_API_DEBUG help The SuperH is a RISC processor targeted for use in embedded systems and consumer electronics; it was also used in the Sega Dreamcast Loading
arch/sh/include/asm/dma-mapping.h +31 −5 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ #include <linux/mm.h> #include <linux/scatterlist.h> #include <linux/dma-debug.h> #include <asm/cacheflush.h> #include <asm/io.h> #include <asm-generic/dma-coherent.h> Loading Loading @@ -38,16 +39,26 @@ static inline dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, enum dma_data_direction dir) { dma_addr_t addr = virt_to_phys(ptr); #if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT) if (dev->bus == &pci_bus_type) return virt_to_phys(ptr); return addr; #endif dma_cache_sync(dev, ptr, size, dir); return virt_to_phys(ptr); debug_dma_map_page(dev, virt_to_page(ptr), (unsigned long)ptr & ~PAGE_MASK, size, dir, addr, true); return addr; } #define dma_unmap_single(dev, addr, size, dir) do { } while (0) static inline void dma_unmap_single(struct device *dev, dma_addr_t addr, size_t size, enum dma_data_direction dir) { debug_dma_unmap_page(dev, addr, size, dir, true); } static inline int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir) Loading @@ -59,12 +70,19 @@ static inline int dma_map_sg(struct device *dev, struct scatterlist *sg, dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir); #endif sg[i].dma_address = sg_phys(&sg[i]); sg[i].dma_length = sg[i].length; } debug_dma_map_sg(dev, sg, nents, i, dir); return nents; } #define dma_unmap_sg(dev, sg, nents, dir) do { } while (0) static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir) { debug_dma_unmap_sg(dev, sg, nents, dir); } static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, Loading Loading @@ -111,6 +129,7 @@ static inline void dma_sync_sg(struct device *dev, struct scatterlist *sg, dma_cache_sync(dev, sg_virt(&sg[i]), sg[i].length, dir); #endif sg[i].dma_address = sg_phys(&sg[i]); sg[i].dma_length = sg[i].length; } } Loading @@ -119,6 +138,7 @@ static inline void dma_sync_single_for_cpu(struct device *dev, enum dma_data_direction dir) { dma_sync_single(dev, dma_handle, size, dir); debug_dma_sync_single_for_cpu(dev, dma_handle, size, dir); } static inline void dma_sync_single_for_device(struct device *dev, Loading @@ -127,6 +147,7 @@ static inline void dma_sync_single_for_device(struct device *dev, enum dma_data_direction dir) { dma_sync_single(dev, dma_handle, size, dir); debug_dma_sync_single_for_device(dev, dma_handle, size, dir); } static inline void dma_sync_single_range_for_cpu(struct device *dev, Loading @@ -136,6 +157,8 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev, enum dma_data_direction direction) { dma_sync_single_for_cpu(dev, dma_handle+offset, size, direction); debug_dma_sync_single_range_for_cpu(dev, dma_handle, offset, size, direction); } static inline void dma_sync_single_range_for_device(struct device *dev, Loading @@ -145,6 +168,8 @@ static inline void dma_sync_single_range_for_device(struct device *dev, enum dma_data_direction direction) { dma_sync_single_for_device(dev, dma_handle+offset, size, direction); debug_dma_sync_single_range_for_device(dev, dma_handle, offset, size, direction); } Loading @@ -153,6 +178,7 @@ static inline void dma_sync_sg_for_cpu(struct device *dev, enum dma_data_direction dir) { dma_sync_sg(dev, sg, nelems, dir); debug_dma_sync_sg_for_cpu(dev, sg, nelems, dir); } static inline void dma_sync_sg_for_device(struct device *dev, Loading @@ -160,9 +186,9 @@ static inline void dma_sync_sg_for_device(struct device *dev, enum dma_data_direction dir) { dma_sync_sg(dev, sg, nelems, dir); debug_dma_sync_sg_for_device(dev, sg, nelems, dir); } static inline int dma_get_cache_alignment(void) { /* Loading
arch/sh/include/asm/scatterlist.h +6 −5 Original line number Diff line number Diff line Loading @@ -9,8 +9,9 @@ struct scatterlist { #endif unsigned long page_link; unsigned int offset; /* for highmem, page offset */ dma_addr_t dma_address; unsigned int length; dma_addr_t dma_address; unsigned int dma_length; }; #define ISA_DMA_THRESHOLD PHYS_ADDR_MASK Loading
arch/sh/mm/consistent.c +13 −6 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include <linux/mm.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> #include <linux/dma-debug.h> #include <asm/cacheflush.h> #include <asm/addrspace.h> #include <asm/io.h> Loading Loading @@ -45,6 +46,9 @@ void *dma_alloc_coherent(struct device *dev, size_t size, split_page(pfn_to_page(virt_to_phys(ret) >> PAGE_SHIFT), order); *dma_handle = virt_to_phys(ret); debug_dma_alloc_coherent(dev, size, *dma_handle, ret_nocache); return ret_nocache; } EXPORT_SYMBOL(dma_alloc_coherent); Loading @@ -56,13 +60,16 @@ void dma_free_coherent(struct device *dev, size_t size, unsigned long pfn = dma_handle >> PAGE_SHIFT; int k; if (!dma_release_from_coherent(dev, order, vaddr)) { WARN_ON(irqs_disabled()); /* for portability */ if (dma_release_from_coherent(dev, order, vaddr)) return; debug_dma_free_coherent(dev, size, vaddr, dma_handle); for (k = 0; k < (1 << order); k++) __free_pages(pfn_to_page(pfn + k), 0); iounmap(vaddr); } } EXPORT_SYMBOL(dma_free_coherent); void dma_cache_sync(struct device *dev, void *vaddr, size_t size, Loading