diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-11-28 11:16:43 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-11-28 11:16:43 -0800 |
commit | 81b6b96475ac7a4ebfceae9f16fb3758327adbfe (patch) | |
tree | 8288f9aacb9ee6dbcba8ee146c168a87bdc445a7 /arch/xtensa/kernel | |
parent | a308a7102215a582fc474375648965bc5692894b (diff) | |
parent | a7ba70f1787f977f970cd116076c6fce4b9e01cc (diff) | |
download | linux-81b6b96475ac7a4ebfceae9f16fb3758327adbfe.tar.bz2 |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux; tag 'dma-mapping-5.5' of git://git.infradead.org/users/hch/dma-mapping
Pull dma-mapping updates from Christoph Hellwig:
- improve dma-debug scalability (Eric Dumazet)
- tiny dma-debug cleanup (Dan Carpenter)
- check for vmap memory in dma_map_single (Kees Cook)
- check for dma_addr_t overflows in dma-direct when using DMA offsets
(Nicolas Saenz Julienne)
- switch the x86 sta2x11 SOC to use more generic DMA code (Nicolas
Saenz Julienne)
- fix arm-nommu dma-ranges handling (Vladimir Murzin)
- use __initdata in CMA (Shyam Saini)
- replace the bus dma mask with a limit (Nicolas Saenz Julienne)
- merge the remapping helpers into the main dma-direct flow (me)
- switch xtensa to the generic dma remap handling (me)
- various cleanups around dma_capable (me)
- remove unused dev arguments to various dma-noncoherent helpers (me)
* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux:
* tag 'dma-mapping-5.5' of git://git.infradead.org/users/hch/dma-mapping: (22 commits)
dma-mapping: treat dev->bus_dma_mask as a DMA limit
dma-direct: exclude dma_direct_map_resource from the min_low_pfn check
dma-direct: don't check swiotlb=force in dma_direct_map_resource
dma-debug: clean up put_hash_bucket()
powerpc: remove support for NULL dev in __phys_to_dma / __dma_to_phys
dma-direct: avoid a forward declaration for phys_to_dma
dma-direct: unify the dma_capable definitions
dma-mapping: drop the dev argument to arch_sync_dma_for_*
x86/PCI: sta2x11: use default DMA address translation
dma-direct: check for overflows on 32 bit DMA addresses
dma-debug: increase HASH_SIZE
dma-debug: reorder struct dma_debug_entry fields
xtensa: use the generic uncached segment support
dma-mapping: merge the generic remapping helpers into dma-direct
dma-direct: provide mmap and get_sgtable method overrides
dma-direct: remove the dma_handle argument to __dma_direct_alloc_pages
dma-direct: remove __dma_direct_free_pages
usb: core: Remove redundant vmap checks
kernel: dma-contiguous: mark CMA parameters __initdata/__initconst
dma-debug: add a schedule point in debug_dma_dump_mappings()
...
Diffstat (limited to 'arch/xtensa/kernel')
-rw-r--r-- | arch/xtensa/kernel/Makefile | 3 | ||||
-rw-r--r-- | arch/xtensa/kernel/pci-dma.c | 129 |
2 files changed, 18 insertions, 114 deletions
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile index 6f629027ac7d..d4082c6a121b 100644 --- a/arch/xtensa/kernel/Makefile +++ b/arch/xtensa/kernel/Makefile @@ -5,10 +5,11 @@ extra-y := head.o vmlinux.lds -obj-y := align.o coprocessor.o entry.o irq.o pci-dma.o platform.o process.o \ +obj-y := align.o coprocessor.o entry.o irq.o platform.o process.o \ ptrace.o setup.o signal.o stacktrace.o syscall.o time.o traps.o \ vectors.o +obj-$(CONFIG_MMU) += pci-dma.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o obj-$(CONFIG_FUNCTION_TRACER) += mcount.o diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c index 154979d62b73..72b6222daa0b 100644 --- a/arch/xtensa/kernel/pci-dma.c +++ b/arch/xtensa/kernel/pci-dma.c @@ -44,8 +44,8 @@ static void do_cache_op(phys_addr_t paddr, size_t size, } } -void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { switch (dir) { case DMA_BIDIRECTIONAL: @@ -62,8 +62,8 @@ void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, } } -void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { switch (dir) { case DMA_BIDIRECTIONAL: @@ -81,122 +81,25 @@ void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, } } -#ifdef CONFIG_MMU -bool platform_vaddr_cached(const void *p) -{ - unsigned long addr = (unsigned long)p; - - return addr >= XCHAL_KSEG_CACHED_VADDR && - addr - XCHAL_KSEG_CACHED_VADDR < XCHAL_KSEG_SIZE; -} - -bool platform_vaddr_uncached(const void *p) -{ - unsigned long addr = (unsigned long)p; - - return addr >= XCHAL_KSEG_BYPASS_VADDR && - addr - XCHAL_KSEG_BYPASS_VADDR < XCHAL_KSEG_SIZE; -} - -void *platform_vaddr_to_uncached(void *p) -{ - return p + XCHAL_KSEG_BYPASS_VADDR - XCHAL_KSEG_CACHED_VADDR; -} - -void *platform_vaddr_to_cached(void *p) -{ - return p + XCHAL_KSEG_CACHED_VADDR - XCHAL_KSEG_BYPASS_VADDR; -} -#else -bool __attribute__((weak)) platform_vaddr_cached(const void *p) -{ - WARN_ONCE(1, "Default %s implementation is used\n", __func__); - return true; -} - -bool __attribute__((weak)) platform_vaddr_uncached(const void *p) -{ - WARN_ONCE(1, "Default %s implementation is used\n", __func__); - return false; -} - -void __attribute__((weak)) *platform_vaddr_to_uncached(void *p) +void arch_dma_prep_coherent(struct page *page, size_t size) { - WARN_ONCE(1, "Default %s implementation is used\n", __func__); - return p; -} - -void __attribute__((weak)) *platform_vaddr_to_cached(void *p) -{ - WARN_ONCE(1, "Default %s implementation is used\n", __func__); - return p; + __invalidate_dcache_range((unsigned long)page_address(page), size); } -#endif /* - * Note: We assume that the full memory space is always mapped to 'kseg' - * Otherwise we have to use page attributes (not implemented). + * Memory caching is platform-dependent in noMMU xtensa configurations. + * The following two functions should be implemented in platform code + * in order to enable coherent DMA memory operations when CONFIG_MMU is not + * enabled. */ - -void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, - gfp_t flag, unsigned long attrs) -{ - unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT; - struct page *page = NULL; - - /* ignore region speicifiers */ - - flag &= ~(__GFP_DMA | __GFP_HIGHMEM); - - if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff)) - flag |= GFP_DMA; - - if (gfpflags_allow_blocking(flag)) - page = dma_alloc_from_contiguous(dev, count, get_order(size), - flag & __GFP_NOWARN); - - if (!page) - page = alloc_pages(flag | __GFP_ZERO, get_order(size)); - - if (!page) - return NULL; - - *handle = phys_to_dma(dev, page_to_phys(page)); - #ifdef CONFIG_MMU - if (PageHighMem(page)) { - void *p; - - p = dma_common_contiguous_remap(page, size, - pgprot_noncached(PAGE_KERNEL), - __builtin_return_address(0)); - if (!p) { - if (!dma_release_from_contiguous(dev, page, count)) - __free_pages(page, get_order(size)); - } - return p; - } -#endif - BUG_ON(!platform_vaddr_cached(page_address(page))); - __invalidate_dcache_range((unsigned long)page_address(page), size); - return platform_vaddr_to_uncached(page_address(page)); +void *uncached_kernel_address(void *p) +{ + return p + XCHAL_KSEG_BYPASS_VADDR - XCHAL_KSEG_CACHED_VADDR; } -void arch_dma_free(struct device *dev, size_t size, void *vaddr, - dma_addr_t dma_handle, unsigned long attrs) +void *cached_kernel_address(void *p) { - unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT; - struct page *page; - - if (platform_vaddr_uncached(vaddr)) { - page = virt_to_page(platform_vaddr_to_cached(vaddr)); - } else { -#ifdef CONFIG_MMU - dma_common_free_remap(vaddr, size); -#endif - page = pfn_to_page(PHYS_PFN(dma_to_phys(dev, dma_handle))); - } - - if (!dma_release_from_contiguous(dev, page, count)) - __free_pages(page, get_order(size)); + return p + XCHAL_KSEG_CACHED_VADDR - XCHAL_KSEG_BYPASS_VADDR; } +#endif /* CONFIG_MMU */ |