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 |