aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/include/asm/dma-mapping.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/include/asm/dma-mapping.h')
-rw-r--r--arch/arm/include/asm/dma-mapping.h87
1 files changed, 68 insertions, 19 deletions
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index a96300bf83f..69ce0727edb 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -57,18 +57,58 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
57#endif 57#endif
58 58
59/* 59/*
60 * DMA-consistent mapping functions. These allocate/free a region of 60 * The DMA API is built upon the notion of "buffer ownership". A buffer
61 * uncached, unwrite-buffered mapped memory space for use with DMA 61 * is either exclusively owned by the CPU (and therefore may be accessed
62 * devices. This is the "generic" version. The PCI specific version 62 * by it) or exclusively owned by the DMA device. These helper functions
63 * is in pci.h 63 * represent the transitions between these two ownership states.
64 * 64 *
65 * Note: Drivers should NOT use this function directly, as it will break 65 * Note, however, that on later ARMs, this notion does not work due to
66 * platforms with CONFIG_DMABOUNCE. 66 * speculative prefetches. We model our approach on the assumption that
67 * Use the driver DMA support - see dma-mapping.h (dma_sync_*) 67 * the CPU does do speculative prefetches, which means we clean caches
68 * before transfers and delay cache invalidation until transfer completion.
69 *
70 * Private support functions: these are not part of the API and are
71 * liable to change. Drivers must not use these.
68 */ 72 */
69extern void dma_cache_maint(const void *kaddr, size_t size, int rw); 73static inline void __dma_single_cpu_to_dev(const void *kaddr, size_t size,
70extern void dma_cache_maint_page(struct page *page, unsigned long offset, 74 enum dma_data_direction dir)
71 size_t size, int rw); 75{
76 extern void ___dma_single_cpu_to_dev(const void *, size_t,
77 enum dma_data_direction);
78
79 if (!arch_is_coherent())
80 ___dma_single_cpu_to_dev(kaddr, size, dir);
81}
82
83static inline void __dma_single_dev_to_cpu(const void *kaddr, size_t size,
84 enum dma_data_direction dir)
85{
86 extern void ___dma_single_dev_to_cpu(const void *, size_t,
87 enum dma_data_direction);
88
89 if (!arch_is_coherent())
90 ___dma_single_dev_to_cpu(kaddr, size, dir);
91}
92
93static inline void __dma_page_cpu_to_dev(struct page *page, unsigned long off,
94 size_t size, enum dma_data_direction dir)
95{
96 extern void ___dma_page_cpu_to_dev(struct page *, unsigned long,
97 size_t, enum dma_data_direction);
98
99 if (!arch_is_coherent())
100 ___dma_page_cpu_to_dev(page, off, size, dir);
101}
102
103static inline void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
104 size_t size, enum dma_data_direction dir)
105{
106 extern void ___dma_page_dev_to_cpu(struct page *, unsigned long,
107 size_t, enum dma_data_direction);
108
109 if (!arch_is_coherent())
110 ___dma_page_dev_to_cpu(page, off, size, dir);
111}
72 112
73/* 113/*
74 * Return whether the given device DMA address mask can be supported 114 * Return whether the given device DMA address mask can be supported
@@ -88,6 +128,14 @@ static inline int dma_supported(struct device *dev, u64 mask)
88 128
89static inline int dma_set_mask(struct device *dev, u64 dma_mask) 129static inline int dma_set_mask(struct device *dev, u64 dma_mask)
90{ 130{
131#ifdef CONFIG_DMABOUNCE
132 if (dev->archdata.dmabounce) {
133 if (dma_mask >= ISA_DMA_THRESHOLD)
134 return 0;
135 else
136 return -EIO;
137 }
138#endif
91 if (!dev->dma_mask || !dma_supported(dev, dma_mask)) 139 if (!dev->dma_mask || !dma_supported(dev, dma_mask))
92 return -EIO; 140 return -EIO;
93 141
@@ -304,8 +352,7 @@ static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
304{ 352{
305 BUG_ON(!valid_dma_direction(dir)); 353 BUG_ON(!valid_dma_direction(dir));
306 354
307 if (!arch_is_coherent()) 355 __dma_single_cpu_to_dev(cpu_addr, size, dir);
308 dma_cache_maint(cpu_addr, size, dir);
309 356
310 return virt_to_dma(dev, cpu_addr); 357 return virt_to_dma(dev, cpu_addr);
311} 358}
@@ -329,8 +376,7 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
329{ 376{
330 BUG_ON(!valid_dma_direction(dir)); 377 BUG_ON(!valid_dma_direction(dir));
331 378
332 if (!arch_is_coherent()) 379 __dma_page_cpu_to_dev(page, offset, size, dir);
333 dma_cache_maint_page(page, offset, size, dir);
334 380
335 return page_to_dma(dev, page) + offset; 381 return page_to_dma(dev, page) + offset;
336} 382}
@@ -352,7 +398,7 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
352static inline void dma_unmap_single(struct device *dev, dma_addr_t handle, 398static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
353 size_t size, enum dma_data_direction dir) 399 size_t size, enum dma_data_direction dir)
354{ 400{
355 /* nothing to do */ 401 __dma_single_dev_to_cpu(dma_to_virt(dev, handle), size, dir);
356} 402}
357 403
358/** 404/**
@@ -372,7 +418,8 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
372static inline void dma_unmap_page(struct device *dev, dma_addr_t handle, 418static inline void dma_unmap_page(struct device *dev, dma_addr_t handle,
373 size_t size, enum dma_data_direction dir) 419 size_t size, enum dma_data_direction dir)
374{ 420{
375 /* nothing to do */ 421 __dma_page_dev_to_cpu(dma_to_page(dev, handle), handle & ~PAGE_MASK,
422 size, dir);
376} 423}
377#endif /* CONFIG_DMABOUNCE */ 424#endif /* CONFIG_DMABOUNCE */
378 425
@@ -400,7 +447,10 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev,
400{ 447{
401 BUG_ON(!valid_dma_direction(dir)); 448 BUG_ON(!valid_dma_direction(dir));
402 449
403 dmabounce_sync_for_cpu(dev, handle, offset, size, dir); 450 if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir))
451 return;
452
453 __dma_single_dev_to_cpu(dma_to_virt(dev, handle) + offset, size, dir);
404} 454}
405 455
406static inline void dma_sync_single_range_for_device(struct device *dev, 456static inline void dma_sync_single_range_for_device(struct device *dev,
@@ -412,8 +462,7 @@ static inline void dma_sync_single_range_for_device(struct device *dev,
412 if (!dmabounce_sync_for_device(dev, handle, offset, size, dir)) 462 if (!dmabounce_sync_for_device(dev, handle, offset, size, dir))
413 return; 463 return;
414 464
415 if (!arch_is_coherent()) 465 __dma_single_cpu_to_dev(dma_to_virt(dev, handle) + offset, size, dir);
416 dma_cache_maint(dma_to_virt(dev, handle) + offset, size, dir);
417} 466}
418 467
419static inline void dma_sync_single_for_cpu(struct device *dev, 468static inline void dma_sync_single_for_cpu(struct device *dev,