aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-04-04 20:13:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-04-04 20:13:43 -0400
commit58bca4a8fa90fcf9069379653b396b2cec642f7f (patch)
tree483c535136b5b168f36326956453e80ce5aa6543 /arch/sparc
parent64ebe987311853ea857a244439de5b947a4b1b07 (diff)
parent64d70fe5d3640e1a89790ed21120921278f8cb86 (diff)
Merge branch 'for-linus' of git://git.linaro.org/people/mszyprowski/linux-dma-mapping
Pull DMA mapping branch from Marek Szyprowski: "Short summary for the whole series: A few limitations have been identified in the current dma-mapping design and its implementations for various architectures. There exist more than one function for allocating and freeing the buffers: currently these 3 are used dma_{alloc, free}_coherent, dma_{alloc,free}_writecombine, dma_{alloc,free}_noncoherent. For most of the systems these calls are almost equivalent and can be interchanged. For others, especially the truly non-coherent ones (like ARM), the difference can be easily noticed in overall driver performance. Sadly not all architectures provide implementations for all of them, so the drivers might need to be adapted and cannot be easily shared between different architectures. The provided patches unify all these functions and hide the differences under the already existing dma attributes concept. The thread with more references is available here: http://www.spinics.net/lists/linux-sh/msg09777.html These patches are also a prerequisite for unifying DMA-mapping implementation on ARM architecture with the common one provided by dma_map_ops structure and extending it with IOMMU support. More information is available in the following thread: http://thread.gmane.org/gmane.linux.kernel.cross-arch/12819 More works on dma-mapping framework are planned, especially in the area of buffer sharing and managing the shared mappings (together with the recently introduced dma_buf interface: commit d15bd7ee445d "dma-buf: Introduce dma buffer sharing mechanism"). The patches in the current set introduce a new alloc/free methods (with support for memory attributes) in dma_map_ops structure, which will later replace dma_alloc_coherent and dma_alloc_writecombine functions." People finally started piping up with support for merging this, so I'm merging it as the last of the pending stuff from the merge window. Looks like pohmelfs is going to wait for 3.5 and more external support for merging. * 'for-linus' of git://git.linaro.org/people/mszyprowski/linux-dma-mapping: common: DMA-mapping: add NON-CONSISTENT attribute common: DMA-mapping: add WRITE_COMBINE attribute common: dma-mapping: introduce mmap method common: dma-mapping: remove old alloc_coherent and free_coherent methods Hexagon: adapt for dma_map_ops changes Unicore32: adapt for dma_map_ops changes Microblaze: adapt for dma_map_ops changes SH: adapt for dma_map_ops changes Alpha: adapt for dma_map_ops changes SPARC: adapt for dma_map_ops changes PowerPC: adapt for dma_map_ops changes MIPS: adapt for dma_map_ops changes X86 & IA64: adapt for dma_map_ops changes common: dma-mapping: introduce generic alloc() and free() methods
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/include/asm/dma-mapping.h18
-rw-r--r--arch/sparc/kernel/iommu.c10
-rw-r--r--arch/sparc/kernel/ioport.c18
-rw-r--r--arch/sparc/kernel/pci_sun4v.c9
4 files changed, 33 insertions, 22 deletions
diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h
index 8c0e4f7bb204..48a7c65731d2 100644
--- a/arch/sparc/include/asm/dma-mapping.h
+++ b/arch/sparc/include/asm/dma-mapping.h
@@ -26,24 +26,30 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
26 26
27#include <asm-generic/dma-mapping-common.h> 27#include <asm-generic/dma-mapping-common.h>
28 28
29static inline void *dma_alloc_coherent(struct device *dev, size_t size, 29#define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL)
30 dma_addr_t *dma_handle, gfp_t flag) 30
31static inline void *dma_alloc_attrs(struct device *dev, size_t size,
32 dma_addr_t *dma_handle, gfp_t flag,
33 struct dma_attrs *attrs)
31{ 34{
32 struct dma_map_ops *ops = get_dma_ops(dev); 35 struct dma_map_ops *ops = get_dma_ops(dev);
33 void *cpu_addr; 36 void *cpu_addr;
34 37
35 cpu_addr = ops->alloc_coherent(dev, size, dma_handle, flag); 38 cpu_addr = ops->alloc(dev, size, dma_handle, flag, attrs);
36 debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr); 39 debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr);
37 return cpu_addr; 40 return cpu_addr;
38} 41}
39 42
40static inline void dma_free_coherent(struct device *dev, size_t size, 43#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL)
41 void *cpu_addr, dma_addr_t dma_handle) 44
45static inline void dma_free_attrs(struct device *dev, size_t size,
46 void *cpu_addr, dma_addr_t dma_handle,
47 struct dma_attrs *attrs)
42{ 48{
43 struct dma_map_ops *ops = get_dma_ops(dev); 49 struct dma_map_ops *ops = get_dma_ops(dev);
44 50
45 debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); 51 debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
46 ops->free_coherent(dev, size, cpu_addr, dma_handle); 52 ops->free(dev, size, cpu_addr, dma_handle, attrs);
47} 53}
48 54
49static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) 55static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c
index 4643d68713fa..070ed141aac7 100644
--- a/arch/sparc/kernel/iommu.c
+++ b/arch/sparc/kernel/iommu.c
@@ -280,7 +280,8 @@ static inline void iommu_free_ctx(struct iommu *iommu, int ctx)
280} 280}
281 281
282static void *dma_4u_alloc_coherent(struct device *dev, size_t size, 282static void *dma_4u_alloc_coherent(struct device *dev, size_t size,
283 dma_addr_t *dma_addrp, gfp_t gfp) 283 dma_addr_t *dma_addrp, gfp_t gfp,
284 struct dma_attrs *attrs)
284{ 285{
285 unsigned long flags, order, first_page; 286 unsigned long flags, order, first_page;
286 struct iommu *iommu; 287 struct iommu *iommu;
@@ -330,7 +331,8 @@ static void *dma_4u_alloc_coherent(struct device *dev, size_t size,
330} 331}
331 332
332static void dma_4u_free_coherent(struct device *dev, size_t size, 333static void dma_4u_free_coherent(struct device *dev, size_t size,
333 void *cpu, dma_addr_t dvma) 334 void *cpu, dma_addr_t dvma,
335 struct dma_attrs *attrs)
334{ 336{
335 struct iommu *iommu; 337 struct iommu *iommu;
336 unsigned long flags, order, npages; 338 unsigned long flags, order, npages;
@@ -825,8 +827,8 @@ static void dma_4u_sync_sg_for_cpu(struct device *dev,
825} 827}
826 828
827static struct dma_map_ops sun4u_dma_ops = { 829static struct dma_map_ops sun4u_dma_ops = {
828 .alloc_coherent = dma_4u_alloc_coherent, 830 .alloc = dma_4u_alloc_coherent,
829 .free_coherent = dma_4u_free_coherent, 831 .free = dma_4u_free_coherent,
830 .map_page = dma_4u_map_page, 832 .map_page = dma_4u_map_page,
831 .unmap_page = dma_4u_unmap_page, 833 .unmap_page = dma_4u_unmap_page,
832 .map_sg = dma_4u_map_sg, 834 .map_sg = dma_4u_map_sg,
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index d0479e2163fa..21bd73943f7f 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -261,7 +261,8 @@ EXPORT_SYMBOL(sbus_set_sbus64);
261 * CPU may access them without any explicit flushing. 261 * CPU may access them without any explicit flushing.
262 */ 262 */
263static void *sbus_alloc_coherent(struct device *dev, size_t len, 263static void *sbus_alloc_coherent(struct device *dev, size_t len,
264 dma_addr_t *dma_addrp, gfp_t gfp) 264 dma_addr_t *dma_addrp, gfp_t gfp,
265 struct dma_attrs *attrs)
265{ 266{
266 struct platform_device *op = to_platform_device(dev); 267 struct platform_device *op = to_platform_device(dev);
267 unsigned long len_total = PAGE_ALIGN(len); 268 unsigned long len_total = PAGE_ALIGN(len);
@@ -315,7 +316,7 @@ err_nopages:
315} 316}
316 317
317static void sbus_free_coherent(struct device *dev, size_t n, void *p, 318static void sbus_free_coherent(struct device *dev, size_t n, void *p,
318 dma_addr_t ba) 319 dma_addr_t ba, struct dma_attrs *attrs)
319{ 320{
320 struct resource *res; 321 struct resource *res;
321 struct page *pgv; 322 struct page *pgv;
@@ -407,8 +408,8 @@ static void sbus_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
407} 408}
408 409
409struct dma_map_ops sbus_dma_ops = { 410struct dma_map_ops sbus_dma_ops = {
410 .alloc_coherent = sbus_alloc_coherent, 411 .alloc = sbus_alloc_coherent,
411 .free_coherent = sbus_free_coherent, 412 .free = sbus_free_coherent,
412 .map_page = sbus_map_page, 413 .map_page = sbus_map_page,
413 .unmap_page = sbus_unmap_page, 414 .unmap_page = sbus_unmap_page,
414 .map_sg = sbus_map_sg, 415 .map_sg = sbus_map_sg,
@@ -436,7 +437,8 @@ arch_initcall(sparc_register_ioport);
436 * hwdev should be valid struct pci_dev pointer for PCI devices. 437 * hwdev should be valid struct pci_dev pointer for PCI devices.
437 */ 438 */
438static void *pci32_alloc_coherent(struct device *dev, size_t len, 439static void *pci32_alloc_coherent(struct device *dev, size_t len,
439 dma_addr_t *pba, gfp_t gfp) 440 dma_addr_t *pba, gfp_t gfp,
441 struct dma_attrs *attrs)
440{ 442{
441 unsigned long len_total = PAGE_ALIGN(len); 443 unsigned long len_total = PAGE_ALIGN(len);
442 void *va; 444 void *va;
@@ -489,7 +491,7 @@ err_nopages:
489 * past this call are illegal. 491 * past this call are illegal.
490 */ 492 */
491static void pci32_free_coherent(struct device *dev, size_t n, void *p, 493static void pci32_free_coherent(struct device *dev, size_t n, void *p,
492 dma_addr_t ba) 494 dma_addr_t ba, struct dma_attrs *attrs)
493{ 495{
494 struct resource *res; 496 struct resource *res;
495 497
@@ -645,8 +647,8 @@ static void pci32_sync_sg_for_device(struct device *device, struct scatterlist *
645} 647}
646 648
647struct dma_map_ops pci32_dma_ops = { 649struct dma_map_ops pci32_dma_ops = {
648 .alloc_coherent = pci32_alloc_coherent, 650 .alloc = pci32_alloc_coherent,
649 .free_coherent = pci32_free_coherent, 651 .free = pci32_free_coherent,
650 .map_page = pci32_map_page, 652 .map_page = pci32_map_page,
651 .unmap_page = pci32_unmap_page, 653 .unmap_page = pci32_unmap_page,
652 .map_sg = pci32_map_sg, 654 .map_sg = pci32_map_sg,
diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c
index af5755d20fbe..7661e84a05a0 100644
--- a/arch/sparc/kernel/pci_sun4v.c
+++ b/arch/sparc/kernel/pci_sun4v.c
@@ -128,7 +128,8 @@ static inline long iommu_batch_end(void)
128} 128}
129 129
130static void *dma_4v_alloc_coherent(struct device *dev, size_t size, 130static void *dma_4v_alloc_coherent(struct device *dev, size_t size,
131 dma_addr_t *dma_addrp, gfp_t gfp) 131 dma_addr_t *dma_addrp, gfp_t gfp,
132 struct dma_attrs *attrs)
132{ 133{
133 unsigned long flags, order, first_page, npages, n; 134 unsigned long flags, order, first_page, npages, n;
134 struct iommu *iommu; 135 struct iommu *iommu;
@@ -198,7 +199,7 @@ range_alloc_fail:
198} 199}
199 200
200static void dma_4v_free_coherent(struct device *dev, size_t size, void *cpu, 201static void dma_4v_free_coherent(struct device *dev, size_t size, void *cpu,
201 dma_addr_t dvma) 202 dma_addr_t dvma, struct dma_attrs *attrs)
202{ 203{
203 struct pci_pbm_info *pbm; 204 struct pci_pbm_info *pbm;
204 struct iommu *iommu; 205 struct iommu *iommu;
@@ -527,8 +528,8 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist,
527} 528}
528 529
529static struct dma_map_ops sun4v_dma_ops = { 530static struct dma_map_ops sun4v_dma_ops = {
530 .alloc_coherent = dma_4v_alloc_coherent, 531 .alloc = dma_4v_alloc_coherent,
531 .free_coherent = dma_4v_free_coherent, 532 .free = dma_4v_free_coherent,
532 .map_page = dma_4v_map_page, 533 .map_page = dma_4v_map_page,
533 .unmap_page = dma_4v_unmap_page, 534 .unmap_page = dma_4v_unmap_page,
534 .map_sg = dma_4v_map_sg, 535 .map_sg = dma_4v_map_sg,