diff options
| -rw-r--r-- | arch/powerpc/kernel/dma-swiotlb.c | 10 | ||||
| -rw-r--r-- | lib/swiotlb.c | 41 |
2 files changed, 23 insertions, 28 deletions
diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c index 68ccf11e4f19..41534ae2f589 100644 --- a/arch/powerpc/kernel/dma-swiotlb.c +++ b/arch/powerpc/kernel/dma-swiotlb.c | |||
| @@ -24,16 +24,6 @@ | |||
| 24 | int swiotlb __read_mostly; | 24 | int swiotlb __read_mostly; |
| 25 | unsigned int ppc_swiotlb_enable; | 25 | unsigned int ppc_swiotlb_enable; |
| 26 | 26 | ||
| 27 | void *swiotlb_bus_to_virt(struct device *hwdev, dma_addr_t addr) | ||
| 28 | { | ||
| 29 | unsigned long pfn = PFN_DOWN(swiotlb_bus_to_phys(hwdev, addr)); | ||
| 30 | void *pageaddr = page_address(pfn_to_page(pfn)); | ||
| 31 | |||
| 32 | if (pageaddr != NULL) | ||
| 33 | return pageaddr + (addr % PAGE_SIZE); | ||
| 34 | return NULL; | ||
| 35 | } | ||
| 36 | |||
| 37 | dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr) | 27 | dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr) |
| 38 | { | 28 | { |
| 39 | return paddr + get_dma_direct_offset(hwdev); | 29 | return paddr + get_dma_direct_offset(hwdev); |
diff --git a/lib/swiotlb.c b/lib/swiotlb.c index dc1cd1f5369e..cba3db809fbc 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c | |||
| @@ -124,17 +124,13 @@ phys_addr_t __weak swiotlb_bus_to_phys(struct device *hwdev, dma_addr_t baddr) | |||
| 124 | return baddr; | 124 | return baddr; |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | /* Note that this doesn't work with highmem page */ | ||
| 127 | static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev, | 128 | static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev, |
| 128 | volatile void *address) | 129 | volatile void *address) |
| 129 | { | 130 | { |
| 130 | return swiotlb_phys_to_bus(hwdev, virt_to_phys(address)); | 131 | return swiotlb_phys_to_bus(hwdev, virt_to_phys(address)); |
| 131 | } | 132 | } |
| 132 | 133 | ||
| 133 | void * __weak swiotlb_bus_to_virt(struct device *hwdev, dma_addr_t address) | ||
| 134 | { | ||
| 135 | return phys_to_virt(swiotlb_bus_to_phys(hwdev, address)); | ||
| 136 | } | ||
| 137 | |||
| 138 | int __weak swiotlb_arch_address_needs_mapping(struct device *hwdev, | 134 | int __weak swiotlb_arch_address_needs_mapping(struct device *hwdev, |
| 139 | dma_addr_t addr, size_t size) | 135 | dma_addr_t addr, size_t size) |
| 140 | { | 136 | { |
| @@ -307,9 +303,10 @@ address_needs_mapping(struct device *hwdev, dma_addr_t addr, size_t size) | |||
| 307 | return swiotlb_arch_address_needs_mapping(hwdev, addr, size); | 303 | return swiotlb_arch_address_needs_mapping(hwdev, addr, size); |
| 308 | } | 304 | } |
| 309 | 305 | ||
| 310 | static int is_swiotlb_buffer(char *addr) | 306 | static int is_swiotlb_buffer(phys_addr_t paddr) |
| 311 | { | 307 | { |
| 312 | return addr >= io_tlb_start && addr < io_tlb_end; | 308 | return paddr >= virt_to_phys(io_tlb_start) && |
| 309 | paddr < virt_to_phys(io_tlb_end); | ||
| 313 | } | 310 | } |
| 314 | 311 | ||
| 315 | /* | 312 | /* |
| @@ -582,11 +579,13 @@ EXPORT_SYMBOL(swiotlb_alloc_coherent); | |||
| 582 | 579 | ||
| 583 | void | 580 | void |
| 584 | swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, | 581 | swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, |
| 585 | dma_addr_t dma_handle) | 582 | dma_addr_t dev_addr) |
| 586 | { | 583 | { |
| 584 | phys_addr_t paddr = swiotlb_bus_to_phys(hwdev, dev_addr); | ||
| 585 | |||
| 587 | WARN_ON(irqs_disabled()); | 586 | WARN_ON(irqs_disabled()); |
| 588 | if (!is_swiotlb_buffer(vaddr)) | 587 | if (!is_swiotlb_buffer(paddr)) |
| 589 | free_pages((unsigned long) vaddr, get_order(size)); | 588 | free_pages((unsigned long)vaddr, get_order(size)); |
| 590 | else | 589 | else |
| 591 | /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ | 590 | /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ |
| 592 | do_unmap_single(hwdev, vaddr, size, DMA_TO_DEVICE); | 591 | do_unmap_single(hwdev, vaddr, size, DMA_TO_DEVICE); |
| @@ -671,19 +670,25 @@ EXPORT_SYMBOL_GPL(swiotlb_map_page); | |||
| 671 | static void unmap_single(struct device *hwdev, dma_addr_t dev_addr, | 670 | static void unmap_single(struct device *hwdev, dma_addr_t dev_addr, |
| 672 | size_t size, int dir) | 671 | size_t size, int dir) |
| 673 | { | 672 | { |
| 674 | char *dma_addr = swiotlb_bus_to_virt(hwdev, dev_addr); | 673 | phys_addr_t paddr = swiotlb_bus_to_phys(hwdev, dev_addr); |
| 675 | 674 | ||
| 676 | BUG_ON(dir == DMA_NONE); | 675 | BUG_ON(dir == DMA_NONE); |
| 677 | 676 | ||
| 678 | if (is_swiotlb_buffer(dma_addr)) { | 677 | if (is_swiotlb_buffer(paddr)) { |
| 679 | do_unmap_single(hwdev, dma_addr, size, dir); | 678 | do_unmap_single(hwdev, phys_to_virt(paddr), size, dir); |
| 680 | return; | 679 | return; |
| 681 | } | 680 | } |
| 682 | 681 | ||
| 683 | if (dir != DMA_FROM_DEVICE) | 682 | if (dir != DMA_FROM_DEVICE) |
| 684 | return; | 683 | return; |
| 685 | 684 | ||
| 686 | dma_mark_clean(dma_addr, size); | 685 | /* |
| 686 | * phys_to_virt doesn't work with hihgmem page but we could | ||
| 687 | * call dma_mark_clean() with hihgmem page here. However, we | ||
| 688 | * are fine since dma_mark_clean() is null on POWERPC. We can | ||
| 689 | * make dma_mark_clean() take a physical address if necessary. | ||
| 690 | */ | ||
| 691 | dma_mark_clean(phys_to_virt(paddr), size); | ||
| 687 | } | 692 | } |
| 688 | 693 | ||
| 689 | void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr, | 694 | void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr, |
| @@ -708,19 +713,19 @@ static void | |||
| 708 | swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr, | 713 | swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr, |
| 709 | size_t size, int dir, int target) | 714 | size_t size, int dir, int target) |
| 710 | { | 715 | { |
| 711 | char *dma_addr = swiotlb_bus_to_virt(hwdev, dev_addr); | 716 | phys_addr_t paddr = swiotlb_bus_to_phys(hwdev, dev_addr); |
| 712 | 717 | ||
| 713 | BUG_ON(dir == DMA_NONE); | 718 | BUG_ON(dir == DMA_NONE); |
| 714 | 719 | ||
| 715 | if (is_swiotlb_buffer(dma_addr)) { | 720 | if (is_swiotlb_buffer(paddr)) { |
| 716 | sync_single(hwdev, dma_addr, size, dir, target); | 721 | sync_single(hwdev, phys_to_virt(paddr), size, dir, target); |
| 717 | return; | 722 | return; |
| 718 | } | 723 | } |
| 719 | 724 | ||
| 720 | if (dir != DMA_FROM_DEVICE) | 725 | if (dir != DMA_FROM_DEVICE) |
| 721 | return; | 726 | return; |
| 722 | 727 | ||
| 723 | dma_mark_clean(dma_addr, size); | 728 | dma_mark_clean(phys_to_virt(paddr), size); |
| 724 | } | 729 | } |
| 725 | 730 | ||
| 726 | void | 731 | void |
