The jazzdma ops implement support for a very basic IOMMU. Thus we really should not use the dma-direct code that takes physical address limits into account. This survived through the great MIPS DMA ops cleanup mostly because I was lazy, but now it is time to fully split the implementations.
Unified · Split
| @@ -16,7 +16,6 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/memblock.h> |
| 17 | 17 | #include <linux/spinlock.h> |
| 18 | 18 | #include <linux/gfp.h> |
| 19 | −#include <linux/dma-direct.h> | |
| 20 | 19 | #include <linux/dma-noncoherent.h> |
| 21 | 20 | #include <asm/mipsregs.h> |
| 22 | 21 | #include <asm/jazz.h> |
| @@ -492,26 +491,39 @@ int vdma_get_enable(int channel) · 469 unmodified lines | ||
| 492 | 491 | static void *jazz_dma_alloc(struct device *dev, size_t size, |
| 493 | 492 | dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) |
| 494 | 493 | { |
| 494 | + struct page *page; | |
| 495 | 495 | void *ret; |
| 496 | 496 | |
| 497 | − ret = dma_direct_alloc_pages(dev, size, dma_handle, gfp, attrs); | |
| 498 | − if (!ret) | |
| 499 | − return NULL; | |
| 497 | + if (attrs & DMA_ATTR_NO_WARN) | |
| 498 | + gfp |= __GFP_NOWARN; | |
| 500 | 499 | |
| 501 | − *dma_handle = vdma_alloc(virt_to_phys(ret), size); | |
| 502 | − if (*dma_handle == DMA_MAPPING_ERROR) { | |
| 503 | − dma_direct_free_pages(dev, size, ret, *dma_handle, attrs); | |
| 500 | + size = PAGE_ALIGN(size); | |
| 501 | + page = alloc_pages(gfp, get_order(size)); | |
| 502 | + if (!page) | |
| 504 | 503 | return NULL; |
| 505 | − } | |
| 504 | + ret = page_address(page); | |
| 505 | + memset(ret, 0, size); | |
| 506 | + *dma_handle = vdma_alloc(virt_to_phys(ret), size); | |
| 507 | + if (*dma_handle == DMA_MAPPING_ERROR) | |
| 508 | + goto out_free_pages; | |
| 509 | + | |
| 510 | + if (attrs & DMA_ATTR_NON_CONSISTENT) | |
| 511 | + return ret; | |
| 512 | + arch_dma_prep_coherent(page, size); | |
| 513 | + return (void *)(UNCAC_BASE + __pa(ret)); | |
| 506 | 514 | |
| 507 | − return ret; | |
| 515 | +out_free_pages: | |
| 516 | + __free_pages(page, get_order(size)); | |
| 517 | + return NULL; | |
| 508 | 518 | } |
| 509 | 519 | |
| 510 | 520 | static void jazz_dma_free(struct device *dev, size_t size, void *vaddr, |
| 511 | 521 | dma_addr_t dma_handle, unsigned long attrs) |
| 512 | 522 | { |
| 513 | 523 | vdma_free(dma_handle); |
| 514 | − dma_direct_free_pages(dev, size, vaddr, dma_handle, attrs); | |
| 524 | + if (!(attrs & DMA_ATTR_NON_CONSISTENT)) | |
| 525 | + vaddr = __va(vaddr - UNCAC_BASE); | |
| 526 | + __free_pages(virt_to_page(vaddr), get_order(size)); | |
| 515 | 527 | } |
| 516 | 528 | |
| 517 | 529 | static dma_addr_t jazz_dma_map_page(struct device *dev, struct page *page, |
| @@ -608,7 +620,6 @@ const struct dma_map_ops jazz_dma_ops = { · 90 unmodified lines | ||
| 608 | 620 | .sync_single_for_device = jazz_dma_sync_single_for_device, |
| 609 | 621 | .sync_sg_for_cpu = jazz_dma_sync_sg_for_cpu, |
| 610 | 622 | .sync_sg_for_device = jazz_dma_sync_sg_for_device, |
| 611 | − .dma_supported = dma_direct_supported, | |
| 612 | 623 | .cache_sync = arch_dma_cache_sync, |
| 613 | 624 | .mmap = dma_common_mmap, |
| 614 | 625 | .get_sgtable = dma_common_get_sgtable, |