aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/Kconfig2
-rw-r--r--arch/x86/include/asm/swiotlb.h7
-rw-r--r--arch/x86/kernel/amd_gart_64.c2
-rw-r--r--arch/x86/kernel/pci-swiotlb.c9
-rw-r--r--arch/x86/pci/sta2x11-fixup.c6
-rw-r--r--include/linux/swiotlb.h2
-rw-r--r--lib/swiotlb.c2
7 files changed, 20 insertions, 10 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 896a411a4584..4a0137f6f032 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -41,7 +41,7 @@ config X86
41 select ARCH_WANT_OPTIONAL_GPIOLIB 41 select ARCH_WANT_OPTIONAL_GPIOLIB
42 select ARCH_WANT_FRAME_POINTERS 42 select ARCH_WANT_FRAME_POINTERS
43 select HAVE_DMA_ATTRS 43 select HAVE_DMA_ATTRS
44 select HAVE_DMA_CONTIGUOUS if !SWIOTLB 44 select HAVE_DMA_CONTIGUOUS
45 select HAVE_KRETPROBES 45 select HAVE_KRETPROBES
46 select GENERIC_EARLY_IOREMAP 46 select GENERIC_EARLY_IOREMAP
47 select HAVE_OPTPROBES 47 select HAVE_OPTPROBES
diff --git a/arch/x86/include/asm/swiotlb.h b/arch/x86/include/asm/swiotlb.h
index 977f1761a25d..ab05d73e2bb7 100644
--- a/arch/x86/include/asm/swiotlb.h
+++ b/arch/x86/include/asm/swiotlb.h
@@ -29,4 +29,11 @@ static inline void pci_swiotlb_late_init(void)
29 29
30static inline void dma_mark_clean(void *addr, size_t size) {} 30static inline void dma_mark_clean(void *addr, size_t size) {}
31 31
32extern void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
33 dma_addr_t *dma_handle, gfp_t flags,
34 struct dma_attrs *attrs);
35extern void x86_swiotlb_free_coherent(struct device *dev, size_t size,
36 void *vaddr, dma_addr_t dma_addr,
37 struct dma_attrs *attrs);
38
32#endif /* _ASM_X86_SWIOTLB_H */ 39#endif /* _ASM_X86_SWIOTLB_H */
diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c
index b574b295a2f9..8e3842fc8bea 100644
--- a/arch/x86/kernel/amd_gart_64.c
+++ b/arch/x86/kernel/amd_gart_64.c
@@ -512,7 +512,7 @@ gart_free_coherent(struct device *dev, size_t size, void *vaddr,
512 dma_addr_t dma_addr, struct dma_attrs *attrs) 512 dma_addr_t dma_addr, struct dma_attrs *attrs)
513{ 513{
514 gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, NULL); 514 gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, NULL);
515 free_pages((unsigned long)vaddr, get_order(size)); 515 dma_generic_free_coherent(dev, size, vaddr, dma_addr, attrs);
516} 516}
517 517
518static int gart_mapping_error(struct device *dev, dma_addr_t dma_addr) 518static int gart_mapping_error(struct device *dev, dma_addr_t dma_addr)
diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c
index 6c483ba98b9c..77dd0ad58be4 100644
--- a/arch/x86/kernel/pci-swiotlb.c
+++ b/arch/x86/kernel/pci-swiotlb.c
@@ -14,7 +14,7 @@
14#include <asm/iommu_table.h> 14#include <asm/iommu_table.h>
15int swiotlb __read_mostly; 15int swiotlb __read_mostly;
16 16
17static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, 17void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
18 dma_addr_t *dma_handle, gfp_t flags, 18 dma_addr_t *dma_handle, gfp_t flags,
19 struct dma_attrs *attrs) 19 struct dma_attrs *attrs)
20{ 20{
@@ -28,11 +28,14 @@ static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
28 return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags); 28 return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags);
29} 29}
30 30
31static void x86_swiotlb_free_coherent(struct device *dev, size_t size, 31void x86_swiotlb_free_coherent(struct device *dev, size_t size,
32 void *vaddr, dma_addr_t dma_addr, 32 void *vaddr, dma_addr_t dma_addr,
33 struct dma_attrs *attrs) 33 struct dma_attrs *attrs)
34{ 34{
35 swiotlb_free_coherent(dev, size, vaddr, dma_addr); 35 if (is_swiotlb_buffer(dma_to_phys(dev, dma_addr)))
36 swiotlb_free_coherent(dev, size, vaddr, dma_addr);
37 else
38 dma_generic_free_coherent(dev, size, vaddr, dma_addr, attrs);
36} 39}
37 40
38static struct dma_map_ops swiotlb_dma_ops = { 41static struct dma_map_ops swiotlb_dma_ops = {
diff --git a/arch/x86/pci/sta2x11-fixup.c b/arch/x86/pci/sta2x11-fixup.c
index 9d8a509c9730..5ceda85b8687 100644
--- a/arch/x86/pci/sta2x11-fixup.c
+++ b/arch/x86/pci/sta2x11-fixup.c
@@ -173,9 +173,7 @@ static void *sta2x11_swiotlb_alloc_coherent(struct device *dev,
173{ 173{
174 void *vaddr; 174 void *vaddr;
175 175
176 vaddr = dma_generic_alloc_coherent(dev, size, dma_handle, flags, attrs); 176 vaddr = x86_swiotlb_alloc_coherent(dev, size, dma_handle, flags, attrs);
177 if (!vaddr)
178 vaddr = swiotlb_alloc_coherent(dev, size, dma_handle, flags);
179 *dma_handle = p2a(*dma_handle, to_pci_dev(dev)); 177 *dma_handle = p2a(*dma_handle, to_pci_dev(dev));
180 return vaddr; 178 return vaddr;
181} 179}
@@ -183,7 +181,7 @@ static void *sta2x11_swiotlb_alloc_coherent(struct device *dev,
183/* We have our own dma_ops: the same as swiotlb but from alloc (above) */ 181/* We have our own dma_ops: the same as swiotlb but from alloc (above) */
184static struct dma_map_ops sta2x11_dma_ops = { 182static struct dma_map_ops sta2x11_dma_ops = {
185 .alloc = sta2x11_swiotlb_alloc_coherent, 183 .alloc = sta2x11_swiotlb_alloc_coherent,
186 .free = swiotlb_free_coherent, 184 .free = x86_swiotlb_free_coherent,
187 .map_page = swiotlb_map_page, 185 .map_page = swiotlb_map_page,
188 .unmap_page = swiotlb_unmap_page, 186 .unmap_page = swiotlb_unmap_page,
189 .map_sg = swiotlb_map_sg_attrs, 187 .map_sg = swiotlb_map_sg_attrs,
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index a5ffd32642fd..e7a018eaf3a2 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -116,4 +116,6 @@ static inline void swiotlb_free(void) { }
116#endif 116#endif
117 117
118extern void swiotlb_print_info(void); 118extern void swiotlb_print_info(void);
119extern int is_swiotlb_buffer(phys_addr_t paddr);
120
119#endif /* __LINUX_SWIOTLB_H */ 121#endif /* __LINUX_SWIOTLB_H */
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index b604b831f4d1..649d097853a1 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -374,7 +374,7 @@ void __init swiotlb_free(void)
374 io_tlb_nslabs = 0; 374 io_tlb_nslabs = 0;
375} 375}
376 376
377static int is_swiotlb_buffer(phys_addr_t paddr) 377int is_swiotlb_buffer(phys_addr_t paddr)
378{ 378{
379 return paddr >= io_tlb_start && paddr < io_tlb_end; 379 return paddr >= io_tlb_start && paddr < io_tlb_end;
380} 380}