diff options
45 files changed, 354 insertions, 198 deletions
diff --git a/Documentation/DMA-attributes.txt b/Documentation/DMA-attributes.txt index b768cc0e402b..5c72eed89563 100644 --- a/Documentation/DMA-attributes.txt +++ b/Documentation/DMA-attributes.txt | |||
@@ -31,3 +31,21 @@ may be weakly ordered, that is that reads and writes may pass each other. | |||
31 | Since it is optional for platforms to implement DMA_ATTR_WEAK_ORDERING, | 31 | Since it is optional for platforms to implement DMA_ATTR_WEAK_ORDERING, |
32 | those that do not will simply ignore the attribute and exhibit default | 32 | those that do not will simply ignore the attribute and exhibit default |
33 | behavior. | 33 | behavior. |
34 | |||
35 | DMA_ATTR_WRITE_COMBINE | ||
36 | ---------------------- | ||
37 | |||
38 | DMA_ATTR_WRITE_COMBINE specifies that writes to the mapping may be | ||
39 | buffered to improve performance. | ||
40 | |||
41 | Since it is optional for platforms to implement DMA_ATTR_WRITE_COMBINE, | ||
42 | those that do not will simply ignore the attribute and exhibit default | ||
43 | behavior. | ||
44 | |||
45 | DMA_ATTR_NON_CONSISTENT | ||
46 | ----------------------- | ||
47 | |||
48 | DMA_ATTR_NON_CONSISTENT lets the platform to choose to return either | ||
49 | consistent or non-consistent memory as it sees fit. By using this API, | ||
50 | you are guaranteeing to the platform that you have all the correct and | ||
51 | necessary sync points for this memory in the driver. | ||
diff --git a/arch/alpha/include/asm/dma-mapping.h b/arch/alpha/include/asm/dma-mapping.h index 4567aca6fdd6..dfa32f061320 100644 --- a/arch/alpha/include/asm/dma-mapping.h +++ b/arch/alpha/include/asm/dma-mapping.h | |||
@@ -12,16 +12,22 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev) | |||
12 | 12 | ||
13 | #include <asm-generic/dma-mapping-common.h> | 13 | #include <asm-generic/dma-mapping-common.h> |
14 | 14 | ||
15 | static inline void *dma_alloc_coherent(struct device *dev, size_t size, | 15 | #define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL) |
16 | dma_addr_t *dma_handle, gfp_t gfp) | 16 | |
17 | static inline void *dma_alloc_attrs(struct device *dev, size_t size, | ||
18 | dma_addr_t *dma_handle, gfp_t gfp, | ||
19 | struct dma_attrs *attrs) | ||
17 | { | 20 | { |
18 | return get_dma_ops(dev)->alloc_coherent(dev, size, dma_handle, gfp); | 21 | return get_dma_ops(dev)->alloc(dev, size, dma_handle, gfp, attrs); |
19 | } | 22 | } |
20 | 23 | ||
21 | static inline void dma_free_coherent(struct device *dev, size_t size, | 24 | #define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) |
22 | void *vaddr, dma_addr_t dma_handle) | 25 | |
26 | static inline void dma_free_attrs(struct device *dev, size_t size, | ||
27 | void *vaddr, dma_addr_t dma_handle, | ||
28 | struct dma_attrs *attrs) | ||
23 | { | 29 | { |
24 | get_dma_ops(dev)->free_coherent(dev, size, vaddr, dma_handle); | 30 | get_dma_ops(dev)->free(dev, size, vaddr, dma_handle, attrs); |
25 | } | 31 | } |
26 | 32 | ||
27 | static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | 33 | static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) |
diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c index 04eea4894ef3..df24b76f9246 100644 --- a/arch/alpha/kernel/pci-noop.c +++ b/arch/alpha/kernel/pci-noop.c | |||
@@ -108,7 +108,8 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn, | |||
108 | } | 108 | } |
109 | 109 | ||
110 | static void *alpha_noop_alloc_coherent(struct device *dev, size_t size, | 110 | static void *alpha_noop_alloc_coherent(struct device *dev, size_t size, |
111 | dma_addr_t *dma_handle, gfp_t gfp) | 111 | dma_addr_t *dma_handle, gfp_t gfp, |
112 | struct dma_attrs *attrs) | ||
112 | { | 113 | { |
113 | void *ret; | 114 | void *ret; |
114 | 115 | ||
@@ -123,7 +124,8 @@ static void *alpha_noop_alloc_coherent(struct device *dev, size_t size, | |||
123 | } | 124 | } |
124 | 125 | ||
125 | static void alpha_noop_free_coherent(struct device *dev, size_t size, | 126 | static void alpha_noop_free_coherent(struct device *dev, size_t size, |
126 | void *cpu_addr, dma_addr_t dma_addr) | 127 | void *cpu_addr, dma_addr_t dma_addr, |
128 | struct dma_attrs *attrs) | ||
127 | { | 129 | { |
128 | free_pages((unsigned long)cpu_addr, get_order(size)); | 130 | free_pages((unsigned long)cpu_addr, get_order(size)); |
129 | } | 131 | } |
@@ -174,8 +176,8 @@ static int alpha_noop_set_mask(struct device *dev, u64 mask) | |||
174 | } | 176 | } |
175 | 177 | ||
176 | struct dma_map_ops alpha_noop_ops = { | 178 | struct dma_map_ops alpha_noop_ops = { |
177 | .alloc_coherent = alpha_noop_alloc_coherent, | 179 | .alloc = alpha_noop_alloc_coherent, |
178 | .free_coherent = alpha_noop_free_coherent, | 180 | .free = alpha_noop_free_coherent, |
179 | .map_page = alpha_noop_map_page, | 181 | .map_page = alpha_noop_map_page, |
180 | .map_sg = alpha_noop_map_sg, | 182 | .map_sg = alpha_noop_map_sg, |
181 | .mapping_error = alpha_noop_mapping_error, | 183 | .mapping_error = alpha_noop_mapping_error, |
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index 43610804987d..cd634795aa9c 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c | |||
@@ -434,7 +434,8 @@ static void alpha_pci_unmap_page(struct device *dev, dma_addr_t dma_addr, | |||
434 | else DMA_ADDRP is undefined. */ | 434 | else DMA_ADDRP is undefined. */ |
435 | 435 | ||
436 | static void *alpha_pci_alloc_coherent(struct device *dev, size_t size, | 436 | static void *alpha_pci_alloc_coherent(struct device *dev, size_t size, |
437 | dma_addr_t *dma_addrp, gfp_t gfp) | 437 | dma_addr_t *dma_addrp, gfp_t gfp, |
438 | struct dma_attrs *attrs) | ||
438 | { | 439 | { |
439 | struct pci_dev *pdev = alpha_gendev_to_pci(dev); | 440 | struct pci_dev *pdev = alpha_gendev_to_pci(dev); |
440 | void *cpu_addr; | 441 | void *cpu_addr; |
@@ -478,7 +479,8 @@ try_again: | |||
478 | DMA_ADDR past this call are illegal. */ | 479 | DMA_ADDR past this call are illegal. */ |
479 | 480 | ||
480 | static void alpha_pci_free_coherent(struct device *dev, size_t size, | 481 | static void alpha_pci_free_coherent(struct device *dev, size_t size, |
481 | void *cpu_addr, dma_addr_t dma_addr) | 482 | void *cpu_addr, dma_addr_t dma_addr, |
483 | struct dma_attrs *attrs) | ||
482 | { | 484 | { |
483 | struct pci_dev *pdev = alpha_gendev_to_pci(dev); | 485 | struct pci_dev *pdev = alpha_gendev_to_pci(dev); |
484 | pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL); | 486 | pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL); |
@@ -952,8 +954,8 @@ static int alpha_pci_set_mask(struct device *dev, u64 mask) | |||
952 | } | 954 | } |
953 | 955 | ||
954 | struct dma_map_ops alpha_pci_ops = { | 956 | struct dma_map_ops alpha_pci_ops = { |
955 | .alloc_coherent = alpha_pci_alloc_coherent, | 957 | .alloc = alpha_pci_alloc_coherent, |
956 | .free_coherent = alpha_pci_free_coherent, | 958 | .free = alpha_pci_free_coherent, |
957 | .map_page = alpha_pci_map_page, | 959 | .map_page = alpha_pci_map_page, |
958 | .unmap_page = alpha_pci_unmap_page, | 960 | .unmap_page = alpha_pci_unmap_page, |
959 | .map_sg = alpha_pci_map_sg, | 961 | .map_sg = alpha_pci_map_sg, |
diff --git a/arch/hexagon/include/asm/dma-mapping.h b/arch/hexagon/include/asm/dma-mapping.h index 448b224ba4ef..233ed3d2d25e 100644 --- a/arch/hexagon/include/asm/dma-mapping.h +++ b/arch/hexagon/include/asm/dma-mapping.h | |||
@@ -71,29 +71,35 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | |||
71 | return (dma_addr == bad_dma_address); | 71 | return (dma_addr == bad_dma_address); |
72 | } | 72 | } |
73 | 73 | ||
74 | static inline void *dma_alloc_coherent(struct device *dev, size_t size, | 74 | #define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL) |
75 | dma_addr_t *dma_handle, gfp_t flag) | 75 | |
76 | static inline void *dma_alloc_attrs(struct device *dev, size_t size, | ||
77 | dma_addr_t *dma_handle, gfp_t flag, | ||
78 | struct dma_attrs *attrs) | ||
76 | { | 79 | { |
77 | void *ret; | 80 | void *ret; |
78 | struct dma_map_ops *ops = get_dma_ops(dev); | 81 | struct dma_map_ops *ops = get_dma_ops(dev); |
79 | 82 | ||
80 | BUG_ON(!dma_ops); | 83 | BUG_ON(!dma_ops); |
81 | 84 | ||
82 | ret = ops->alloc_coherent(dev, size, dma_handle, flag); | 85 | ret = ops->alloc(dev, size, dma_handle, flag, attrs); |
83 | 86 | ||
84 | debug_dma_alloc_coherent(dev, size, *dma_handle, ret); | 87 | debug_dma_alloc_coherent(dev, size, *dma_handle, ret); |
85 | 88 | ||
86 | return ret; | 89 | return ret; |
87 | } | 90 | } |
88 | 91 | ||
89 | static inline void dma_free_coherent(struct device *dev, size_t size, | 92 | #define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) |
90 | void *cpu_addr, dma_addr_t dma_handle) | 93 | |
94 | static inline void dma_free_attrs(struct device *dev, size_t size, | ||
95 | void *cpu_addr, dma_addr_t dma_handle, | ||
96 | struct dma_attrs *attrs) | ||
91 | { | 97 | { |
92 | struct dma_map_ops *dma_ops = get_dma_ops(dev); | 98 | struct dma_map_ops *dma_ops = get_dma_ops(dev); |
93 | 99 | ||
94 | BUG_ON(!dma_ops); | 100 | BUG_ON(!dma_ops); |
95 | 101 | ||
96 | dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); | 102 | dma_ops->free(dev, size, cpu_addr, dma_handle, attrs); |
97 | 103 | ||
98 | debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); | 104 | debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); |
99 | } | 105 | } |
diff --git a/arch/hexagon/kernel/dma.c b/arch/hexagon/kernel/dma.c index e711ace62fdf..37302218ca4a 100644 --- a/arch/hexagon/kernel/dma.c +++ b/arch/hexagon/kernel/dma.c | |||
@@ -54,7 +54,8 @@ static struct gen_pool *coherent_pool; | |||
54 | /* Allocates from a pool of uncached memory that was reserved at boot time */ | 54 | /* Allocates from a pool of uncached memory that was reserved at boot time */ |
55 | 55 | ||
56 | void *hexagon_dma_alloc_coherent(struct device *dev, size_t size, | 56 | void *hexagon_dma_alloc_coherent(struct device *dev, size_t size, |
57 | dma_addr_t *dma_addr, gfp_t flag) | 57 | dma_addr_t *dma_addr, gfp_t flag, |
58 | struct dma_attrs *attrs) | ||
58 | { | 59 | { |
59 | void *ret; | 60 | void *ret; |
60 | 61 | ||
@@ -81,7 +82,7 @@ void *hexagon_dma_alloc_coherent(struct device *dev, size_t size, | |||
81 | } | 82 | } |
82 | 83 | ||
83 | static void hexagon_free_coherent(struct device *dev, size_t size, void *vaddr, | 84 | static void hexagon_free_coherent(struct device *dev, size_t size, void *vaddr, |
84 | dma_addr_t dma_addr) | 85 | dma_addr_t dma_addr, struct dma_attrs *attrs) |
85 | { | 86 | { |
86 | gen_pool_free(coherent_pool, (unsigned long) vaddr, size); | 87 | gen_pool_free(coherent_pool, (unsigned long) vaddr, size); |
87 | } | 88 | } |
@@ -202,8 +203,8 @@ static void hexagon_sync_single_for_device(struct device *dev, | |||
202 | } | 203 | } |
203 | 204 | ||
204 | struct dma_map_ops hexagon_dma_ops = { | 205 | struct dma_map_ops hexagon_dma_ops = { |
205 | .alloc_coherent = hexagon_dma_alloc_coherent, | 206 | .alloc = hexagon_dma_alloc_coherent, |
206 | .free_coherent = hexagon_free_coherent, | 207 | .free = hexagon_free_coherent, |
207 | .map_sg = hexagon_map_sg, | 208 | .map_sg = hexagon_map_sg, |
208 | .map_page = hexagon_map_page, | 209 | .map_page = hexagon_map_page, |
209 | .sync_single_for_cpu = hexagon_sync_single_for_cpu, | 210 | .sync_single_for_cpu = hexagon_sync_single_for_cpu, |
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index f6ea3a3b4a84..bcda5b2d121a 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c | |||
@@ -1129,7 +1129,8 @@ void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, | |||
1129 | * See Documentation/DMA-API-HOWTO.txt | 1129 | * See Documentation/DMA-API-HOWTO.txt |
1130 | */ | 1130 | */ |
1131 | static void * | 1131 | static void * |
1132 | sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags) | 1132 | sba_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, |
1133 | gfp_t flags, struct dma_attrs *attrs) | ||
1133 | { | 1134 | { |
1134 | struct ioc *ioc; | 1135 | struct ioc *ioc; |
1135 | void *addr; | 1136 | void *addr; |
@@ -1191,8 +1192,8 @@ sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp | |||
1191 | * | 1192 | * |
1192 | * See Documentation/DMA-API-HOWTO.txt | 1193 | * See Documentation/DMA-API-HOWTO.txt |
1193 | */ | 1194 | */ |
1194 | static void sba_free_coherent (struct device *dev, size_t size, void *vaddr, | 1195 | static void sba_free_coherent(struct device *dev, size_t size, void *vaddr, |
1195 | dma_addr_t dma_handle) | 1196 | dma_addr_t dma_handle, struct dma_attrs *attrs) |
1196 | { | 1197 | { |
1197 | sba_unmap_single_attrs(dev, dma_handle, size, 0, NULL); | 1198 | sba_unmap_single_attrs(dev, dma_handle, size, 0, NULL); |
1198 | free_pages((unsigned long) vaddr, get_order(size)); | 1199 | free_pages((unsigned long) vaddr, get_order(size)); |
@@ -2212,8 +2213,8 @@ sba_page_override(char *str) | |||
2212 | __setup("sbapagesize=",sba_page_override); | 2213 | __setup("sbapagesize=",sba_page_override); |
2213 | 2214 | ||
2214 | struct dma_map_ops sba_dma_ops = { | 2215 | struct dma_map_ops sba_dma_ops = { |
2215 | .alloc_coherent = sba_alloc_coherent, | 2216 | .alloc = sba_alloc_coherent, |
2216 | .free_coherent = sba_free_coherent, | 2217 | .free = sba_free_coherent, |
2217 | .map_page = sba_map_page, | 2218 | .map_page = sba_map_page, |
2218 | .unmap_page = sba_unmap_page, | 2219 | .unmap_page = sba_unmap_page, |
2219 | .map_sg = sba_map_sg_attrs, | 2220 | .map_sg = sba_map_sg_attrs, |
diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h index 4336d080b241..4f5e8148440d 100644 --- a/arch/ia64/include/asm/dma-mapping.h +++ b/arch/ia64/include/asm/dma-mapping.h | |||
@@ -23,23 +23,29 @@ extern void machvec_dma_sync_single(struct device *, dma_addr_t, size_t, | |||
23 | extern void machvec_dma_sync_sg(struct device *, struct scatterlist *, int, | 23 | extern void machvec_dma_sync_sg(struct device *, struct scatterlist *, int, |
24 | enum dma_data_direction); | 24 | enum dma_data_direction); |
25 | 25 | ||
26 | static inline void *dma_alloc_coherent(struct device *dev, size_t size, | 26 | #define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL) |
27 | dma_addr_t *daddr, gfp_t gfp) | 27 | |
28 | static inline void *dma_alloc_attrs(struct device *dev, size_t size, | ||
29 | dma_addr_t *daddr, gfp_t gfp, | ||
30 | struct dma_attrs *attrs) | ||
28 | { | 31 | { |
29 | struct dma_map_ops *ops = platform_dma_get_ops(dev); | 32 | struct dma_map_ops *ops = platform_dma_get_ops(dev); |
30 | void *caddr; | 33 | void *caddr; |
31 | 34 | ||
32 | caddr = ops->alloc_coherent(dev, size, daddr, gfp); | 35 | caddr = ops->alloc(dev, size, daddr, gfp, attrs); |
33 | debug_dma_alloc_coherent(dev, size, *daddr, caddr); | 36 | debug_dma_alloc_coherent(dev, size, *daddr, caddr); |
34 | return caddr; | 37 | return caddr; |
35 | } | 38 | } |
36 | 39 | ||
37 | static inline void dma_free_coherent(struct device *dev, size_t size, | 40 | #define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) |
38 | void *caddr, dma_addr_t daddr) | 41 | |
42 | static inline void dma_free_attrs(struct device *dev, size_t size, | ||
43 | void *caddr, dma_addr_t daddr, | ||
44 | struct dma_attrs *attrs) | ||
39 | { | 45 | { |
40 | struct dma_map_ops *ops = platform_dma_get_ops(dev); | 46 | struct dma_map_ops *ops = platform_dma_get_ops(dev); |
41 | debug_dma_free_coherent(dev, size, caddr, daddr); | 47 | debug_dma_free_coherent(dev, size, caddr, daddr); |
42 | ops->free_coherent(dev, size, caddr, daddr); | 48 | ops->free(dev, size, caddr, daddr, attrs); |
43 | } | 49 | } |
44 | 50 | ||
45 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) | 51 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) |
diff --git a/arch/ia64/kernel/pci-swiotlb.c b/arch/ia64/kernel/pci-swiotlb.c index d9485d952ed0..939260aeac98 100644 --- a/arch/ia64/kernel/pci-swiotlb.c +++ b/arch/ia64/kernel/pci-swiotlb.c | |||
@@ -15,16 +15,24 @@ int swiotlb __read_mostly; | |||
15 | EXPORT_SYMBOL(swiotlb); | 15 | EXPORT_SYMBOL(swiotlb); |
16 | 16 | ||
17 | static void *ia64_swiotlb_alloc_coherent(struct device *dev, size_t size, | 17 | static void *ia64_swiotlb_alloc_coherent(struct device *dev, size_t size, |
18 | dma_addr_t *dma_handle, gfp_t gfp) | 18 | dma_addr_t *dma_handle, gfp_t gfp, |
19 | struct dma_attrs *attrs) | ||
19 | { | 20 | { |
20 | if (dev->coherent_dma_mask != DMA_BIT_MASK(64)) | 21 | if (dev->coherent_dma_mask != DMA_BIT_MASK(64)) |
21 | gfp |= GFP_DMA; | 22 | gfp |= GFP_DMA; |
22 | return swiotlb_alloc_coherent(dev, size, dma_handle, gfp); | 23 | return swiotlb_alloc_coherent(dev, size, dma_handle, gfp); |
23 | } | 24 | } |
24 | 25 | ||
26 | static void ia64_swiotlb_free_coherent(struct device *dev, size_t size, | ||
27 | void *vaddr, dma_addr_t dma_addr, | ||
28 | struct dma_attrs *attrs) | ||
29 | { | ||
30 | swiotlb_free_coherent(dev, size, vaddr, dma_addr); | ||
31 | } | ||
32 | |||
25 | struct dma_map_ops swiotlb_dma_ops = { | 33 | struct dma_map_ops swiotlb_dma_ops = { |
26 | .alloc_coherent = ia64_swiotlb_alloc_coherent, | 34 | .alloc = ia64_swiotlb_alloc_coherent, |
27 | .free_coherent = swiotlb_free_coherent, | 35 | .free = ia64_swiotlb_free_coherent, |
28 | .map_page = swiotlb_map_page, | 36 | .map_page = swiotlb_map_page, |
29 | .unmap_page = swiotlb_unmap_page, | 37 | .unmap_page = swiotlb_unmap_page, |
30 | .map_sg = swiotlb_map_sg_attrs, | 38 | .map_sg = swiotlb_map_sg_attrs, |
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c index a9d310de57da..3290d6e00c31 100644 --- a/arch/ia64/sn/pci/pci_dma.c +++ b/arch/ia64/sn/pci/pci_dma.c | |||
@@ -76,7 +76,8 @@ EXPORT_SYMBOL(sn_dma_set_mask); | |||
76 | * more information. | 76 | * more information. |
77 | */ | 77 | */ |
78 | static void *sn_dma_alloc_coherent(struct device *dev, size_t size, | 78 | static void *sn_dma_alloc_coherent(struct device *dev, size_t size, |
79 | dma_addr_t * dma_handle, gfp_t flags) | 79 | dma_addr_t * dma_handle, gfp_t flags, |
80 | struct dma_attrs *attrs) | ||
80 | { | 81 | { |
81 | void *cpuaddr; | 82 | void *cpuaddr; |
82 | unsigned long phys_addr; | 83 | unsigned long phys_addr; |
@@ -137,7 +138,7 @@ static void *sn_dma_alloc_coherent(struct device *dev, size_t size, | |||
137 | * any associated IOMMU mappings. | 138 | * any associated IOMMU mappings. |
138 | */ | 139 | */ |
139 | static void sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, | 140 | static void sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, |
140 | dma_addr_t dma_handle) | 141 | dma_addr_t dma_handle, struct dma_attrs *attrs) |
141 | { | 142 | { |
142 | struct pci_dev *pdev = to_pci_dev(dev); | 143 | struct pci_dev *pdev = to_pci_dev(dev); |
143 | struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); | 144 | struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); |
@@ -466,8 +467,8 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size) | |||
466 | } | 467 | } |
467 | 468 | ||
468 | static struct dma_map_ops sn_dma_ops = { | 469 | static struct dma_map_ops sn_dma_ops = { |
469 | .alloc_coherent = sn_dma_alloc_coherent, | 470 | .alloc = sn_dma_alloc_coherent, |
470 | .free_coherent = sn_dma_free_coherent, | 471 | .free = sn_dma_free_coherent, |
471 | .map_page = sn_dma_map_page, | 472 | .map_page = sn_dma_map_page, |
472 | .unmap_page = sn_dma_unmap_page, | 473 | .unmap_page = sn_dma_unmap_page, |
473 | .map_sg = sn_dma_map_sg, | 474 | .map_sg = sn_dma_map_sg, |
diff --git a/arch/microblaze/include/asm/dma-mapping.h b/arch/microblaze/include/asm/dma-mapping.h index 3a3e5b886854..01d228286cb0 100644 --- a/arch/microblaze/include/asm/dma-mapping.h +++ b/arch/microblaze/include/asm/dma-mapping.h | |||
@@ -123,28 +123,34 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | |||
123 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) | 123 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) |
124 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) | 124 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) |
125 | 125 | ||
126 | static inline void *dma_alloc_coherent(struct device *dev, size_t size, | 126 | #define dma_alloc_coherent(d, s, h, f) dma_alloc_attrs(d, s, h, f, NULL) |
127 | dma_addr_t *dma_handle, gfp_t flag) | 127 | |
128 | static inline void *dma_alloc_attrs(struct device *dev, size_t size, | ||
129 | dma_addr_t *dma_handle, gfp_t flag, | ||
130 | struct dma_attrs *attrs) | ||
128 | { | 131 | { |
129 | struct dma_map_ops *ops = get_dma_ops(dev); | 132 | struct dma_map_ops *ops = get_dma_ops(dev); |
130 | void *memory; | 133 | void *memory; |
131 | 134 | ||
132 | BUG_ON(!ops); | 135 | BUG_ON(!ops); |
133 | 136 | ||
134 | memory = ops->alloc_coherent(dev, size, dma_handle, flag); | 137 | memory = ops->alloc(dev, size, dma_handle, flag, attrs); |
135 | 138 | ||
136 | debug_dma_alloc_coherent(dev, size, *dma_handle, memory); | 139 | debug_dma_alloc_coherent(dev, size, *dma_handle, memory); |
137 | return memory; | 140 | return memory; |
138 | } | 141 | } |
139 | 142 | ||
140 | static inline void dma_free_coherent(struct device *dev, size_t size, | 143 | #define dma_free_coherent(d,s,c,h) dma_free_attrs(d, s, c, h, NULL) |
141 | void *cpu_addr, dma_addr_t dma_handle) | 144 | |
145 | static inline void dma_free_attrs(struct device *dev, size_t size, | ||
146 | void *cpu_addr, dma_addr_t dma_handle, | ||
147 | struct dma_attrs *attrs) | ||
142 | { | 148 | { |
143 | struct dma_map_ops *ops = get_dma_ops(dev); | 149 | struct dma_map_ops *ops = get_dma_ops(dev); |
144 | 150 | ||
145 | BUG_ON(!ops); | 151 | BUG_ON(!ops); |
146 | debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); | 152 | debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); |
147 | ops->free_coherent(dev, size, cpu_addr, dma_handle); | 153 | ops->free(dev, size, cpu_addr, dma_handle, attrs); |
148 | } | 154 | } |
149 | 155 | ||
150 | static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, | 156 | static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, |
diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c index 65a4af4cbbbe..a2bfa2ca5730 100644 --- a/arch/microblaze/kernel/dma.c +++ b/arch/microblaze/kernel/dma.c | |||
@@ -33,7 +33,8 @@ static unsigned long get_dma_direct_offset(struct device *dev) | |||
33 | #define NOT_COHERENT_CACHE | 33 | #define NOT_COHERENT_CACHE |
34 | 34 | ||
35 | static void *dma_direct_alloc_coherent(struct device *dev, size_t size, | 35 | static void *dma_direct_alloc_coherent(struct device *dev, size_t size, |
36 | dma_addr_t *dma_handle, gfp_t flag) | 36 | dma_addr_t *dma_handle, gfp_t flag, |
37 | struct dma_attrs *attrs) | ||
37 | { | 38 | { |
38 | #ifdef NOT_COHERENT_CACHE | 39 | #ifdef NOT_COHERENT_CACHE |
39 | return consistent_alloc(flag, size, dma_handle); | 40 | return consistent_alloc(flag, size, dma_handle); |
@@ -57,7 +58,8 @@ static void *dma_direct_alloc_coherent(struct device *dev, size_t size, | |||
57 | } | 58 | } |
58 | 59 | ||
59 | static void dma_direct_free_coherent(struct device *dev, size_t size, | 60 | static void dma_direct_free_coherent(struct device *dev, size_t size, |
60 | void *vaddr, dma_addr_t dma_handle) | 61 | void *vaddr, dma_addr_t dma_handle, |
62 | struct dma_attrs *attrs) | ||
61 | { | 63 | { |
62 | #ifdef NOT_COHERENT_CACHE | 64 | #ifdef NOT_COHERENT_CACHE |
63 | consistent_free(size, vaddr); | 65 | consistent_free(size, vaddr); |
@@ -176,8 +178,8 @@ dma_direct_sync_sg_for_device(struct device *dev, | |||
176 | } | 178 | } |
177 | 179 | ||
178 | struct dma_map_ops dma_direct_ops = { | 180 | struct dma_map_ops dma_direct_ops = { |
179 | .alloc_coherent = dma_direct_alloc_coherent, | 181 | .alloc = dma_direct_alloc_coherent, |
180 | .free_coherent = dma_direct_free_coherent, | 182 | .free = dma_direct_free_coherent, |
181 | .map_sg = dma_direct_map_sg, | 183 | .map_sg = dma_direct_map_sg, |
182 | .unmap_sg = dma_direct_unmap_sg, | 184 | .unmap_sg = dma_direct_unmap_sg, |
183 | .dma_supported = dma_direct_dma_supported, | 185 | .dma_supported = dma_direct_dma_supported, |
diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c index b6bb92c16a47..41dd00884975 100644 --- a/arch/mips/cavium-octeon/dma-octeon.c +++ b/arch/mips/cavium-octeon/dma-octeon.c | |||
@@ -157,7 +157,7 @@ static void octeon_dma_sync_sg_for_device(struct device *dev, | |||
157 | } | 157 | } |
158 | 158 | ||
159 | static void *octeon_dma_alloc_coherent(struct device *dev, size_t size, | 159 | static void *octeon_dma_alloc_coherent(struct device *dev, size_t size, |
160 | dma_addr_t *dma_handle, gfp_t gfp) | 160 | dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs) |
161 | { | 161 | { |
162 | void *ret; | 162 | void *ret; |
163 | 163 | ||
@@ -192,7 +192,7 @@ static void *octeon_dma_alloc_coherent(struct device *dev, size_t size, | |||
192 | } | 192 | } |
193 | 193 | ||
194 | static void octeon_dma_free_coherent(struct device *dev, size_t size, | 194 | static void octeon_dma_free_coherent(struct device *dev, size_t size, |
195 | void *vaddr, dma_addr_t dma_handle) | 195 | void *vaddr, dma_addr_t dma_handle, struct dma_attrs *attrs) |
196 | { | 196 | { |
197 | int order = get_order(size); | 197 | int order = get_order(size); |
198 | 198 | ||
@@ -240,8 +240,8 @@ EXPORT_SYMBOL(dma_to_phys); | |||
240 | 240 | ||
241 | static struct octeon_dma_map_ops octeon_linear_dma_map_ops = { | 241 | static struct octeon_dma_map_ops octeon_linear_dma_map_ops = { |
242 | .dma_map_ops = { | 242 | .dma_map_ops = { |
243 | .alloc_coherent = octeon_dma_alloc_coherent, | 243 | .alloc = octeon_dma_alloc_coherent, |
244 | .free_coherent = octeon_dma_free_coherent, | 244 | .free = octeon_dma_free_coherent, |
245 | .map_page = octeon_dma_map_page, | 245 | .map_page = octeon_dma_map_page, |
246 | .unmap_page = swiotlb_unmap_page, | 246 | .unmap_page = swiotlb_unmap_page, |
247 | .map_sg = octeon_dma_map_sg, | 247 | .map_sg = octeon_dma_map_sg, |
@@ -325,8 +325,8 @@ void __init plat_swiotlb_setup(void) | |||
325 | #ifdef CONFIG_PCI | 325 | #ifdef CONFIG_PCI |
326 | static struct octeon_dma_map_ops _octeon_pci_dma_map_ops = { | 326 | static struct octeon_dma_map_ops _octeon_pci_dma_map_ops = { |
327 | .dma_map_ops = { | 327 | .dma_map_ops = { |
328 | .alloc_coherent = octeon_dma_alloc_coherent, | 328 | .alloc = octeon_dma_alloc_coherent, |
329 | .free_coherent = octeon_dma_free_coherent, | 329 | .free = octeon_dma_free_coherent, |
330 | .map_page = octeon_dma_map_page, | 330 | .map_page = octeon_dma_map_page, |
331 | .unmap_page = swiotlb_unmap_page, | 331 | .unmap_page = swiotlb_unmap_page, |
332 | .map_sg = octeon_dma_map_sg, | 332 | .map_sg = octeon_dma_map_sg, |
diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index 7aa37ddfca4b..be39a12901c6 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h | |||
@@ -57,25 +57,31 @@ dma_set_mask(struct device *dev, u64 mask) | |||
57 | extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, | 57 | extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, |
58 | enum dma_data_direction direction); | 58 | enum dma_data_direction direction); |
59 | 59 | ||
60 | static inline void *dma_alloc_coherent(struct device *dev, size_t size, | 60 | #define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL) |
61 | dma_addr_t *dma_handle, gfp_t gfp) | 61 | |
62 | static inline void *dma_alloc_attrs(struct device *dev, size_t size, | ||
63 | dma_addr_t *dma_handle, gfp_t gfp, | ||
64 | struct dma_attrs *attrs) | ||
62 | { | 65 | { |
63 | void *ret; | 66 | void *ret; |
64 | struct dma_map_ops *ops = get_dma_ops(dev); | 67 | struct dma_map_ops *ops = get_dma_ops(dev); |
65 | 68 | ||
66 | ret = ops->alloc_coherent(dev, size, dma_handle, gfp); | 69 | ret = ops->alloc(dev, size, dma_handle, gfp, attrs); |
67 | 70 | ||
68 | debug_dma_alloc_coherent(dev, size, *dma_handle, ret); | 71 | debug_dma_alloc_coherent(dev, size, *dma_handle, ret); |
69 | 72 | ||
70 | return ret; | 73 | return ret; |
71 | } | 74 | } |
72 | 75 | ||
73 | static inline void dma_free_coherent(struct device *dev, size_t size, | 76 | #define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) |
74 | void *vaddr, dma_addr_t dma_handle) | 77 | |
78 | static inline void dma_free_attrs(struct device *dev, size_t size, | ||
79 | void *vaddr, dma_addr_t dma_handle, | ||
80 | struct dma_attrs *attrs) | ||
75 | { | 81 | { |
76 | struct dma_map_ops *ops = get_dma_ops(dev); | 82 | struct dma_map_ops *ops = get_dma_ops(dev); |
77 | 83 | ||
78 | ops->free_coherent(dev, size, vaddr, dma_handle); | 84 | ops->free(dev, size, vaddr, dma_handle, attrs); |
79 | 85 | ||
80 | debug_dma_free_coherent(dev, size, vaddr, dma_handle); | 86 | debug_dma_free_coherent(dev, size, vaddr, dma_handle); |
81 | } | 87 | } |
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 46084912e588..3fab2046c8a4 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c | |||
@@ -98,7 +98,7 @@ void *dma_alloc_noncoherent(struct device *dev, size_t size, | |||
98 | EXPORT_SYMBOL(dma_alloc_noncoherent); | 98 | EXPORT_SYMBOL(dma_alloc_noncoherent); |
99 | 99 | ||
100 | static void *mips_dma_alloc_coherent(struct device *dev, size_t size, | 100 | static void *mips_dma_alloc_coherent(struct device *dev, size_t size, |
101 | dma_addr_t * dma_handle, gfp_t gfp) | 101 | dma_addr_t * dma_handle, gfp_t gfp, struct dma_attrs *attrs) |
102 | { | 102 | { |
103 | void *ret; | 103 | void *ret; |
104 | 104 | ||
@@ -132,7 +132,7 @@ void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr, | |||
132 | EXPORT_SYMBOL(dma_free_noncoherent); | 132 | EXPORT_SYMBOL(dma_free_noncoherent); |
133 | 133 | ||
134 | static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, | 134 | static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, |
135 | dma_addr_t dma_handle) | 135 | dma_addr_t dma_handle, struct dma_attrs *attrs) |
136 | { | 136 | { |
137 | unsigned long addr = (unsigned long) vaddr; | 137 | unsigned long addr = (unsigned long) vaddr; |
138 | int order = get_order(size); | 138 | int order = get_order(size); |
@@ -323,8 +323,8 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size, | |||
323 | EXPORT_SYMBOL(dma_cache_sync); | 323 | EXPORT_SYMBOL(dma_cache_sync); |
324 | 324 | ||
325 | static struct dma_map_ops mips_default_dma_map_ops = { | 325 | static struct dma_map_ops mips_default_dma_map_ops = { |
326 | .alloc_coherent = mips_dma_alloc_coherent, | 326 | .alloc = mips_dma_alloc_coherent, |
327 | .free_coherent = mips_dma_free_coherent, | 327 | .free = mips_dma_free_coherent, |
328 | .map_page = mips_dma_map_page, | 328 | .map_page = mips_dma_map_page, |
329 | .unmap_page = mips_dma_unmap_page, | 329 | .unmap_page = mips_dma_unmap_page, |
330 | .map_sg = mips_dma_map_sg, | 330 | .map_sg = mips_dma_map_sg, |
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index dd70fac57ec8..62678e365ca0 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h | |||
@@ -22,9 +22,11 @@ | |||
22 | 22 | ||
23 | /* Some dma direct funcs must be visible for use in other dma_ops */ | 23 | /* Some dma direct funcs must be visible for use in other dma_ops */ |
24 | extern void *dma_direct_alloc_coherent(struct device *dev, size_t size, | 24 | extern void *dma_direct_alloc_coherent(struct device *dev, size_t size, |
25 | dma_addr_t *dma_handle, gfp_t flag); | 25 | dma_addr_t *dma_handle, gfp_t flag, |
26 | struct dma_attrs *attrs); | ||
26 | extern void dma_direct_free_coherent(struct device *dev, size_t size, | 27 | extern void dma_direct_free_coherent(struct device *dev, size_t size, |
27 | void *vaddr, dma_addr_t dma_handle); | 28 | void *vaddr, dma_addr_t dma_handle, |
29 | struct dma_attrs *attrs); | ||
28 | 30 | ||
29 | 31 | ||
30 | #ifdef CONFIG_NOT_COHERENT_CACHE | 32 | #ifdef CONFIG_NOT_COHERENT_CACHE |
@@ -130,23 +132,29 @@ static inline int dma_supported(struct device *dev, u64 mask) | |||
130 | 132 | ||
131 | extern int dma_set_mask(struct device *dev, u64 dma_mask); | 133 | extern int dma_set_mask(struct device *dev, u64 dma_mask); |
132 | 134 | ||
133 | static inline void *dma_alloc_coherent(struct device *dev, size_t size, | 135 | #define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL) |
134 | dma_addr_t *dma_handle, gfp_t flag) | 136 | |
137 | static inline void *dma_alloc_attrs(struct device *dev, size_t size, | ||
138 | dma_addr_t *dma_handle, gfp_t flag, | ||
139 | struct dma_attrs *attrs) | ||
135 | { | 140 | { |
136 | struct dma_map_ops *dma_ops = get_dma_ops(dev); | 141 | struct dma_map_ops *dma_ops = get_dma_ops(dev); |
137 | void *cpu_addr; | 142 | void *cpu_addr; |
138 | 143 | ||
139 | BUG_ON(!dma_ops); | 144 | BUG_ON(!dma_ops); |
140 | 145 | ||
141 | cpu_addr = dma_ops->alloc_coherent(dev, size, dma_handle, flag); | 146 | cpu_addr = dma_ops->alloc(dev, size, dma_handle, flag, attrs); |
142 | 147 | ||
143 | debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr); | 148 | debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr); |
144 | 149 | ||
145 | return cpu_addr; | 150 | return cpu_addr; |
146 | } | 151 | } |
147 | 152 | ||
148 | static inline void dma_free_coherent(struct device *dev, size_t size, | 153 | #define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) |
149 | void *cpu_addr, dma_addr_t dma_handle) | 154 | |
155 | static inline void dma_free_attrs(struct device *dev, size_t size, | ||
156 | void *cpu_addr, dma_addr_t dma_handle, | ||
157 | struct dma_attrs *attrs) | ||
150 | { | 158 | { |
151 | struct dma_map_ops *dma_ops = get_dma_ops(dev); | 159 | struct dma_map_ops *dma_ops = get_dma_ops(dev); |
152 | 160 | ||
@@ -154,7 +162,7 @@ static inline void dma_free_coherent(struct device *dev, size_t size, | |||
154 | 162 | ||
155 | debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); | 163 | debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); |
156 | 164 | ||
157 | dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); | 165 | dma_ops->free(dev, size, cpu_addr, dma_handle, attrs); |
158 | } | 166 | } |
159 | 167 | ||
160 | static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | 168 | static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) |
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 3f6464b4d970..bcfdcd22c766 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c | |||
@@ -17,7 +17,8 @@ | |||
17 | * to the dma address (mapping) of the first page. | 17 | * to the dma address (mapping) of the first page. |
18 | */ | 18 | */ |
19 | static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, | 19 | static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, |
20 | dma_addr_t *dma_handle, gfp_t flag) | 20 | dma_addr_t *dma_handle, gfp_t flag, |
21 | struct dma_attrs *attrs) | ||
21 | { | 22 | { |
22 | return iommu_alloc_coherent(dev, get_iommu_table_base(dev), size, | 23 | return iommu_alloc_coherent(dev, get_iommu_table_base(dev), size, |
23 | dma_handle, dev->coherent_dma_mask, flag, | 24 | dma_handle, dev->coherent_dma_mask, flag, |
@@ -25,7 +26,8 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, | |||
25 | } | 26 | } |
26 | 27 | ||
27 | static void dma_iommu_free_coherent(struct device *dev, size_t size, | 28 | static void dma_iommu_free_coherent(struct device *dev, size_t size, |
28 | void *vaddr, dma_addr_t dma_handle) | 29 | void *vaddr, dma_addr_t dma_handle, |
30 | struct dma_attrs *attrs) | ||
29 | { | 31 | { |
30 | iommu_free_coherent(get_iommu_table_base(dev), size, vaddr, dma_handle); | 32 | iommu_free_coherent(get_iommu_table_base(dev), size, vaddr, dma_handle); |
31 | } | 33 | } |
@@ -105,8 +107,8 @@ static u64 dma_iommu_get_required_mask(struct device *dev) | |||
105 | } | 107 | } |
106 | 108 | ||
107 | struct dma_map_ops dma_iommu_ops = { | 109 | struct dma_map_ops dma_iommu_ops = { |
108 | .alloc_coherent = dma_iommu_alloc_coherent, | 110 | .alloc = dma_iommu_alloc_coherent, |
109 | .free_coherent = dma_iommu_free_coherent, | 111 | .free = dma_iommu_free_coherent, |
110 | .map_sg = dma_iommu_map_sg, | 112 | .map_sg = dma_iommu_map_sg, |
111 | .unmap_sg = dma_iommu_unmap_sg, | 113 | .unmap_sg = dma_iommu_unmap_sg, |
112 | .dma_supported = dma_iommu_dma_supported, | 114 | .dma_supported = dma_iommu_dma_supported, |
diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c index 1ebc9189aada..4ab88dafb235 100644 --- a/arch/powerpc/kernel/dma-swiotlb.c +++ b/arch/powerpc/kernel/dma-swiotlb.c | |||
@@ -47,8 +47,8 @@ static u64 swiotlb_powerpc_get_required(struct device *dev) | |||
47 | * for everything else. | 47 | * for everything else. |
48 | */ | 48 | */ |
49 | struct dma_map_ops swiotlb_dma_ops = { | 49 | struct dma_map_ops swiotlb_dma_ops = { |
50 | .alloc_coherent = dma_direct_alloc_coherent, | 50 | .alloc = dma_direct_alloc_coherent, |
51 | .free_coherent = dma_direct_free_coherent, | 51 | .free = dma_direct_free_coherent, |
52 | .map_sg = swiotlb_map_sg_attrs, | 52 | .map_sg = swiotlb_map_sg_attrs, |
53 | .unmap_sg = swiotlb_unmap_sg_attrs, | 53 | .unmap_sg = swiotlb_unmap_sg_attrs, |
54 | .dma_supported = swiotlb_dma_supported, | 54 | .dma_supported = swiotlb_dma_supported, |
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c index 7d0233c12ee3..b1ec983dcec8 100644 --- a/arch/powerpc/kernel/dma.c +++ b/arch/powerpc/kernel/dma.c | |||
@@ -26,7 +26,8 @@ | |||
26 | 26 | ||
27 | 27 | ||
28 | void *dma_direct_alloc_coherent(struct device *dev, size_t size, | 28 | void *dma_direct_alloc_coherent(struct device *dev, size_t size, |
29 | dma_addr_t *dma_handle, gfp_t flag) | 29 | dma_addr_t *dma_handle, gfp_t flag, |
30 | struct dma_attrs *attrs) | ||
30 | { | 31 | { |
31 | void *ret; | 32 | void *ret; |
32 | #ifdef CONFIG_NOT_COHERENT_CACHE | 33 | #ifdef CONFIG_NOT_COHERENT_CACHE |
@@ -54,7 +55,8 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size, | |||
54 | } | 55 | } |
55 | 56 | ||
56 | void dma_direct_free_coherent(struct device *dev, size_t size, | 57 | void dma_direct_free_coherent(struct device *dev, size_t size, |
57 | void *vaddr, dma_addr_t dma_handle) | 58 | void *vaddr, dma_addr_t dma_handle, |
59 | struct dma_attrs *attrs) | ||
58 | { | 60 | { |
59 | #ifdef CONFIG_NOT_COHERENT_CACHE | 61 | #ifdef CONFIG_NOT_COHERENT_CACHE |
60 | __dma_free_coherent(size, vaddr); | 62 | __dma_free_coherent(size, vaddr); |
@@ -150,8 +152,8 @@ static inline void dma_direct_sync_single(struct device *dev, | |||
150 | #endif | 152 | #endif |
151 | 153 | ||
152 | struct dma_map_ops dma_direct_ops = { | 154 | struct dma_map_ops dma_direct_ops = { |
153 | .alloc_coherent = dma_direct_alloc_coherent, | 155 | .alloc = dma_direct_alloc_coherent, |
154 | .free_coherent = dma_direct_free_coherent, | 156 | .free = dma_direct_free_coherent, |
155 | .map_sg = dma_direct_map_sg, | 157 | .map_sg = dma_direct_map_sg, |
156 | .unmap_sg = dma_direct_unmap_sg, | 158 | .unmap_sg = dma_direct_unmap_sg, |
157 | .dma_supported = dma_direct_dma_supported, | 159 | .dma_supported = dma_direct_dma_supported, |
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 79bb282e6501..b01d14eeca8d 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c | |||
@@ -65,7 +65,8 @@ static struct of_device_id __initdata ibmebus_matches[] = { | |||
65 | static void *ibmebus_alloc_coherent(struct device *dev, | 65 | static void *ibmebus_alloc_coherent(struct device *dev, |
66 | size_t size, | 66 | size_t size, |
67 | dma_addr_t *dma_handle, | 67 | dma_addr_t *dma_handle, |
68 | gfp_t flag) | 68 | gfp_t flag, |
69 | struct dma_attrs *attrs) | ||
69 | { | 70 | { |
70 | void *mem; | 71 | void *mem; |
71 | 72 | ||
@@ -77,7 +78,8 @@ static void *ibmebus_alloc_coherent(struct device *dev, | |||
77 | 78 | ||
78 | static void ibmebus_free_coherent(struct device *dev, | 79 | static void ibmebus_free_coherent(struct device *dev, |
79 | size_t size, void *vaddr, | 80 | size_t size, void *vaddr, |
80 | dma_addr_t dma_handle) | 81 | dma_addr_t dma_handle, |
82 | struct dma_attrs *attrs) | ||
81 | { | 83 | { |
82 | kfree(vaddr); | 84 | kfree(vaddr); |
83 | } | 85 | } |
@@ -136,8 +138,8 @@ static u64 ibmebus_dma_get_required_mask(struct device *dev) | |||
136 | } | 138 | } |
137 | 139 | ||
138 | static struct dma_map_ops ibmebus_dma_ops = { | 140 | static struct dma_map_ops ibmebus_dma_ops = { |
139 | .alloc_coherent = ibmebus_alloc_coherent, | 141 | .alloc = ibmebus_alloc_coherent, |
140 | .free_coherent = ibmebus_free_coherent, | 142 | .free = ibmebus_free_coherent, |
141 | .map_sg = ibmebus_map_sg, | 143 | .map_sg = ibmebus_map_sg, |
142 | .unmap_sg = ibmebus_unmap_sg, | 144 | .unmap_sg = ibmebus_unmap_sg, |
143 | .dma_supported = ibmebus_dma_supported, | 145 | .dma_supported = ibmebus_dma_supported, |
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index b2f7c8480bf6..a3a99901c8ec 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
@@ -482,7 +482,8 @@ static void vio_cmo_balance(struct work_struct *work) | |||
482 | } | 482 | } |
483 | 483 | ||
484 | static void *vio_dma_iommu_alloc_coherent(struct device *dev, size_t size, | 484 | static void *vio_dma_iommu_alloc_coherent(struct device *dev, size_t size, |
485 | dma_addr_t *dma_handle, gfp_t flag) | 485 | dma_addr_t *dma_handle, gfp_t flag, |
486 | struct dma_attrs *attrs) | ||
486 | { | 487 | { |
487 | struct vio_dev *viodev = to_vio_dev(dev); | 488 | struct vio_dev *viodev = to_vio_dev(dev); |
488 | void *ret; | 489 | void *ret; |
@@ -492,7 +493,7 @@ static void *vio_dma_iommu_alloc_coherent(struct device *dev, size_t size, | |||
492 | return NULL; | 493 | return NULL; |
493 | } | 494 | } |
494 | 495 | ||
495 | ret = dma_iommu_ops.alloc_coherent(dev, size, dma_handle, flag); | 496 | ret = dma_iommu_ops.alloc(dev, size, dma_handle, flag, attrs); |
496 | if (unlikely(ret == NULL)) { | 497 | if (unlikely(ret == NULL)) { |
497 | vio_cmo_dealloc(viodev, roundup(size, PAGE_SIZE)); | 498 | vio_cmo_dealloc(viodev, roundup(size, PAGE_SIZE)); |
498 | atomic_inc(&viodev->cmo.allocs_failed); | 499 | atomic_inc(&viodev->cmo.allocs_failed); |
@@ -502,11 +503,12 @@ static void *vio_dma_iommu_alloc_coherent(struct device *dev, size_t size, | |||
502 | } | 503 | } |
503 | 504 | ||
504 | static void vio_dma_iommu_free_coherent(struct device *dev, size_t size, | 505 | static void vio_dma_iommu_free_coherent(struct device *dev, size_t size, |
505 | void *vaddr, dma_addr_t dma_handle) | 506 | void *vaddr, dma_addr_t dma_handle, |
507 | struct dma_attrs *attrs) | ||
506 | { | 508 | { |
507 | struct vio_dev *viodev = to_vio_dev(dev); | 509 | struct vio_dev *viodev = to_vio_dev(dev); |
508 | 510 | ||
509 | dma_iommu_ops.free_coherent(dev, size, vaddr, dma_handle); | 511 | dma_iommu_ops.free(dev, size, vaddr, dma_handle, attrs); |
510 | 512 | ||
511 | vio_cmo_dealloc(viodev, roundup(size, PAGE_SIZE)); | 513 | vio_cmo_dealloc(viodev, roundup(size, PAGE_SIZE)); |
512 | } | 514 | } |
@@ -607,8 +609,8 @@ static u64 vio_dma_get_required_mask(struct device *dev) | |||
607 | } | 609 | } |
608 | 610 | ||
609 | struct dma_map_ops vio_dma_mapping_ops = { | 611 | struct dma_map_ops vio_dma_mapping_ops = { |
610 | .alloc_coherent = vio_dma_iommu_alloc_coherent, | 612 | .alloc = vio_dma_iommu_alloc_coherent, |
611 | .free_coherent = vio_dma_iommu_free_coherent, | 613 | .free = vio_dma_iommu_free_coherent, |
612 | .map_sg = vio_dma_iommu_map_sg, | 614 | .map_sg = vio_dma_iommu_map_sg, |
613 | .unmap_sg = vio_dma_iommu_unmap_sg, | 615 | .unmap_sg = vio_dma_iommu_unmap_sg, |
614 | .map_page = vio_dma_iommu_map_page, | 616 | .map_page = vio_dma_iommu_map_page, |
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index ae9fc7bc17d6..b9f509a34c01 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c | |||
@@ -564,7 +564,8 @@ static struct iommu_table *cell_get_iommu_table(struct device *dev) | |||
564 | /* A coherent allocation implies strong ordering */ | 564 | /* A coherent allocation implies strong ordering */ |
565 | 565 | ||
566 | static void *dma_fixed_alloc_coherent(struct device *dev, size_t size, | 566 | static void *dma_fixed_alloc_coherent(struct device *dev, size_t size, |
567 | dma_addr_t *dma_handle, gfp_t flag) | 567 | dma_addr_t *dma_handle, gfp_t flag, |
568 | struct dma_attrs *attrs) | ||
568 | { | 569 | { |
569 | if (iommu_fixed_is_weak) | 570 | if (iommu_fixed_is_weak) |
570 | return iommu_alloc_coherent(dev, cell_get_iommu_table(dev), | 571 | return iommu_alloc_coherent(dev, cell_get_iommu_table(dev), |
@@ -572,18 +573,19 @@ static void *dma_fixed_alloc_coherent(struct device *dev, size_t size, | |||
572 | device_to_mask(dev), flag, | 573 | device_to_mask(dev), flag, |
573 | dev_to_node(dev)); | 574 | dev_to_node(dev)); |
574 | else | 575 | else |
575 | return dma_direct_ops.alloc_coherent(dev, size, dma_handle, | 576 | return dma_direct_ops.alloc(dev, size, dma_handle, flag, |
576 | flag); | 577 | attrs); |
577 | } | 578 | } |
578 | 579 | ||
579 | static void dma_fixed_free_coherent(struct device *dev, size_t size, | 580 | static void dma_fixed_free_coherent(struct device *dev, size_t size, |
580 | void *vaddr, dma_addr_t dma_handle) | 581 | void *vaddr, dma_addr_t dma_handle, |
582 | struct dma_attrs *attrs) | ||
581 | { | 583 | { |
582 | if (iommu_fixed_is_weak) | 584 | if (iommu_fixed_is_weak) |
583 | iommu_free_coherent(cell_get_iommu_table(dev), size, vaddr, | 585 | iommu_free_coherent(cell_get_iommu_table(dev), size, vaddr, |
584 | dma_handle); | 586 | dma_handle); |
585 | else | 587 | else |
586 | dma_direct_ops.free_coherent(dev, size, vaddr, dma_handle); | 588 | dma_direct_ops.free(dev, size, vaddr, dma_handle, attrs); |
587 | } | 589 | } |
588 | 590 | ||
589 | static dma_addr_t dma_fixed_map_page(struct device *dev, struct page *page, | 591 | static dma_addr_t dma_fixed_map_page(struct device *dev, struct page *page, |
@@ -642,8 +644,8 @@ static int dma_fixed_dma_supported(struct device *dev, u64 mask) | |||
642 | static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask); | 644 | static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask); |
643 | 645 | ||
644 | struct dma_map_ops dma_iommu_fixed_ops = { | 646 | struct dma_map_ops dma_iommu_fixed_ops = { |
645 | .alloc_coherent = dma_fixed_alloc_coherent, | 647 | .alloc = dma_fixed_alloc_coherent, |
646 | .free_coherent = dma_fixed_free_coherent, | 648 | .free = dma_fixed_free_coherent, |
647 | .map_sg = dma_fixed_map_sg, | 649 | .map_sg = dma_fixed_map_sg, |
648 | .unmap_sg = dma_fixed_unmap_sg, | 650 | .unmap_sg = dma_fixed_unmap_sg, |
649 | .dma_supported = dma_fixed_dma_supported, | 651 | .dma_supported = dma_fixed_dma_supported, |
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index 880eb9ce22c5..5606fe36faf2 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c | |||
@@ -515,7 +515,8 @@ core_initcall(ps3_system_bus_init); | |||
515 | * to the dma address (mapping) of the first page. | 515 | * to the dma address (mapping) of the first page. |
516 | */ | 516 | */ |
517 | static void * ps3_alloc_coherent(struct device *_dev, size_t size, | 517 | static void * ps3_alloc_coherent(struct device *_dev, size_t size, |
518 | dma_addr_t *dma_handle, gfp_t flag) | 518 | dma_addr_t *dma_handle, gfp_t flag, |
519 | struct dma_attrs *attrs) | ||
519 | { | 520 | { |
520 | int result; | 521 | int result; |
521 | struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); | 522 | struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); |
@@ -552,7 +553,7 @@ clean_none: | |||
552 | } | 553 | } |
553 | 554 | ||
554 | static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr, | 555 | static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr, |
555 | dma_addr_t dma_handle) | 556 | dma_addr_t dma_handle, struct dma_attrs *attrs) |
556 | { | 557 | { |
557 | struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); | 558 | struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); |
558 | 559 | ||
@@ -701,8 +702,8 @@ static u64 ps3_dma_get_required_mask(struct device *_dev) | |||
701 | } | 702 | } |
702 | 703 | ||
703 | static struct dma_map_ops ps3_sb_dma_ops = { | 704 | static struct dma_map_ops ps3_sb_dma_ops = { |
704 | .alloc_coherent = ps3_alloc_coherent, | 705 | .alloc = ps3_alloc_coherent, |
705 | .free_coherent = ps3_free_coherent, | 706 | .free = ps3_free_coherent, |
706 | .map_sg = ps3_sb_map_sg, | 707 | .map_sg = ps3_sb_map_sg, |
707 | .unmap_sg = ps3_sb_unmap_sg, | 708 | .unmap_sg = ps3_sb_unmap_sg, |
708 | .dma_supported = ps3_dma_supported, | 709 | .dma_supported = ps3_dma_supported, |
@@ -712,8 +713,8 @@ static struct dma_map_ops ps3_sb_dma_ops = { | |||
712 | }; | 713 | }; |
713 | 714 | ||
714 | static struct dma_map_ops ps3_ioc0_dma_ops = { | 715 | static struct dma_map_ops ps3_ioc0_dma_ops = { |
715 | .alloc_coherent = ps3_alloc_coherent, | 716 | .alloc = ps3_alloc_coherent, |
716 | .free_coherent = ps3_free_coherent, | 717 | .free = ps3_free_coherent, |
717 | .map_sg = ps3_ioc0_map_sg, | 718 | .map_sg = ps3_ioc0_map_sg, |
718 | .unmap_sg = ps3_ioc0_unmap_sg, | 719 | .unmap_sg = ps3_ioc0_unmap_sg, |
719 | .dma_supported = ps3_dma_supported, | 720 | .dma_supported = ps3_dma_supported, |
diff --git a/arch/sh/include/asm/dma-mapping.h b/arch/sh/include/asm/dma-mapping.h index 1a73c3e759a7..8bd965e00a15 100644 --- a/arch/sh/include/asm/dma-mapping.h +++ b/arch/sh/include/asm/dma-mapping.h | |||
@@ -52,25 +52,31 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | |||
52 | return dma_addr == 0; | 52 | return dma_addr == 0; |
53 | } | 53 | } |
54 | 54 | ||
55 | static inline void *dma_alloc_coherent(struct device *dev, size_t size, | 55 | #define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL) |
56 | dma_addr_t *dma_handle, gfp_t gfp) | 56 | |
57 | static inline void *dma_alloc_attrs(struct device *dev, size_t size, | ||
58 | dma_addr_t *dma_handle, gfp_t gfp, | ||
59 | struct dma_attrs *attrs) | ||
57 | { | 60 | { |
58 | struct dma_map_ops *ops = get_dma_ops(dev); | 61 | struct dma_map_ops *ops = get_dma_ops(dev); |
59 | void *memory; | 62 | void *memory; |
60 | 63 | ||
61 | if (dma_alloc_from_coherent(dev, size, dma_handle, &memory)) | 64 | if (dma_alloc_from_coherent(dev, size, dma_handle, &memory)) |
62 | return memory; | 65 | return memory; |
63 | if (!ops->alloc_coherent) | 66 | if (!ops->alloc) |
64 | return NULL; | 67 | return NULL; |
65 | 68 | ||
66 | memory = ops->alloc_coherent(dev, size, dma_handle, gfp); | 69 | memory = ops->alloc(dev, size, dma_handle, gfp, attrs); |
67 | debug_dma_alloc_coherent(dev, size, *dma_handle, memory); | 70 | debug_dma_alloc_coherent(dev, size, *dma_handle, memory); |
68 | 71 | ||
69 | return memory; | 72 | return memory; |
70 | } | 73 | } |
71 | 74 | ||
72 | static inline void dma_free_coherent(struct device *dev, size_t size, | 75 | #define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) |
73 | void *vaddr, dma_addr_t dma_handle) | 76 | |
77 | static inline void dma_free_attrs(struct device *dev, size_t size, | ||
78 | void *vaddr, dma_addr_t dma_handle, | ||
79 | struct dma_attrs *attrs) | ||
74 | { | 80 | { |
75 | struct dma_map_ops *ops = get_dma_ops(dev); | 81 | struct dma_map_ops *ops = get_dma_ops(dev); |
76 | 82 | ||
@@ -78,14 +84,16 @@ static inline void dma_free_coherent(struct device *dev, size_t size, | |||
78 | return; | 84 | return; |
79 | 85 | ||
80 | debug_dma_free_coherent(dev, size, vaddr, dma_handle); | 86 | debug_dma_free_coherent(dev, size, vaddr, dma_handle); |
81 | if (ops->free_coherent) | 87 | if (ops->free) |
82 | ops->free_coherent(dev, size, vaddr, dma_handle); | 88 | ops->free(dev, size, vaddr, dma_handle, attrs); |
83 | } | 89 | } |
84 | 90 | ||
85 | /* arch/sh/mm/consistent.c */ | 91 | /* arch/sh/mm/consistent.c */ |
86 | extern void *dma_generic_alloc_coherent(struct device *dev, size_t size, | 92 | extern void *dma_generic_alloc_coherent(struct device *dev, size_t size, |
87 | dma_addr_t *dma_addr, gfp_t flag); | 93 | dma_addr_t *dma_addr, gfp_t flag, |
94 | struct dma_attrs *attrs); | ||
88 | extern void dma_generic_free_coherent(struct device *dev, size_t size, | 95 | extern void dma_generic_free_coherent(struct device *dev, size_t size, |
89 | void *vaddr, dma_addr_t dma_handle); | 96 | void *vaddr, dma_addr_t dma_handle, |
97 | struct dma_attrs *attrs); | ||
90 | 98 | ||
91 | #endif /* __ASM_SH_DMA_MAPPING_H */ | 99 | #endif /* __ASM_SH_DMA_MAPPING_H */ |
diff --git a/arch/sh/kernel/dma-nommu.c b/arch/sh/kernel/dma-nommu.c index 3c55b87f8b63..5b0bfcda6d0b 100644 --- a/arch/sh/kernel/dma-nommu.c +++ b/arch/sh/kernel/dma-nommu.c | |||
@@ -63,8 +63,8 @@ static void nommu_sync_sg(struct device *dev, struct scatterlist *sg, | |||
63 | #endif | 63 | #endif |
64 | 64 | ||
65 | struct dma_map_ops nommu_dma_ops = { | 65 | struct dma_map_ops nommu_dma_ops = { |
66 | .alloc_coherent = dma_generic_alloc_coherent, | 66 | .alloc = dma_generic_alloc_coherent, |
67 | .free_coherent = dma_generic_free_coherent, | 67 | .free = dma_generic_free_coherent, |
68 | .map_page = nommu_map_page, | 68 | .map_page = nommu_map_page, |
69 | .map_sg = nommu_map_sg, | 69 | .map_sg = nommu_map_sg, |
70 | #ifdef CONFIG_DMA_NONCOHERENT | 70 | #ifdef CONFIG_DMA_NONCOHERENT |
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c index f251b5f27652..b81d9dbf9fef 100644 --- a/arch/sh/mm/consistent.c +++ b/arch/sh/mm/consistent.c | |||
@@ -33,7 +33,8 @@ static int __init dma_init(void) | |||
33 | fs_initcall(dma_init); | 33 | fs_initcall(dma_init); |
34 | 34 | ||
35 | void *dma_generic_alloc_coherent(struct device *dev, size_t size, | 35 | void *dma_generic_alloc_coherent(struct device *dev, size_t size, |
36 | dma_addr_t *dma_handle, gfp_t gfp) | 36 | dma_addr_t *dma_handle, gfp_t gfp, |
37 | struct dma_attrs *attrs) | ||
37 | { | 38 | { |
38 | void *ret, *ret_nocache; | 39 | void *ret, *ret_nocache; |
39 | int order = get_order(size); | 40 | int order = get_order(size); |
@@ -64,7 +65,8 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size, | |||
64 | } | 65 | } |
65 | 66 | ||
66 | void dma_generic_free_coherent(struct device *dev, size_t size, | 67 | void dma_generic_free_coherent(struct device *dev, size_t size, |
67 | void *vaddr, dma_addr_t dma_handle) | 68 | void *vaddr, dma_addr_t dma_handle, |
69 | struct dma_attrs *attrs) | ||
68 | { | 70 | { |
69 | int order = get_order(size); | 71 | int order = get_order(size); |
70 | unsigned long pfn = dma_handle >> PAGE_SHIFT; | 72 | unsigned long pfn = dma_handle >> PAGE_SHIFT; |
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 | ||
29 | static 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 | |
31 | static 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 | ||
40 | static 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 | |
45 | static 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 | ||
49 | static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | 55 | static 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 | ||
282 | static void *dma_4u_alloc_coherent(struct device *dev, size_t size, | 282 | static 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 | ||
332 | static void dma_4u_free_coherent(struct device *dev, size_t size, | 333 | static 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 | ||
827 | static struct dma_map_ops sun4u_dma_ops = { | 829 | static 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 | */ |
263 | static void *sbus_alloc_coherent(struct device *dev, size_t len, | 263 | static 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 | ||
317 | static void sbus_free_coherent(struct device *dev, size_t n, void *p, | 318 | static 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 | ||
409 | struct dma_map_ops sbus_dma_ops = { | 410 | struct 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 | */ |
438 | static void *pci32_alloc_coherent(struct device *dev, size_t len, | 439 | static 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 | */ |
491 | static void pci32_free_coherent(struct device *dev, size_t n, void *p, | 493 | static 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 | ||
647 | struct dma_map_ops pci32_dma_ops = { | 649 | struct 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 | ||
130 | static void *dma_4v_alloc_coherent(struct device *dev, size_t size, | 130 | static 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 | ||
200 | static void dma_4v_free_coherent(struct device *dev, size_t size, void *cpu, | 201 | static 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 | ||
529 | static struct dma_map_ops sun4v_dma_ops = { | 530 | static 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, |
diff --git a/arch/unicore32/include/asm/dma-mapping.h b/arch/unicore32/include/asm/dma-mapping.h index 9258e592f414..366460a81796 100644 --- a/arch/unicore32/include/asm/dma-mapping.h +++ b/arch/unicore32/include/asm/dma-mapping.h | |||
@@ -82,20 +82,26 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask) | |||
82 | return 0; | 82 | return 0; |
83 | } | 83 | } |
84 | 84 | ||
85 | static inline void *dma_alloc_coherent(struct device *dev, size_t size, | 85 | #define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL) |
86 | dma_addr_t *dma_handle, gfp_t flag) | 86 | |
87 | static inline void *dma_alloc_attrs(struct device *dev, size_t size, | ||
88 | dma_addr_t *dma_handle, gfp_t flag, | ||
89 | struct dma_attrs *attrs) | ||
87 | { | 90 | { |
88 | struct dma_map_ops *dma_ops = get_dma_ops(dev); | 91 | struct dma_map_ops *dma_ops = get_dma_ops(dev); |
89 | 92 | ||
90 | return dma_ops->alloc_coherent(dev, size, dma_handle, flag); | 93 | return dma_ops->alloc(dev, size, dma_handle, flag, attrs); |
91 | } | 94 | } |
92 | 95 | ||
93 | static inline void dma_free_coherent(struct device *dev, size_t size, | 96 | #define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) |
94 | void *cpu_addr, dma_addr_t dma_handle) | 97 | |
98 | static inline void dma_free_attrs(struct device *dev, size_t size, | ||
99 | void *cpu_addr, dma_addr_t dma_handle, | ||
100 | struct dma_attrs *attrs) | ||
95 | { | 101 | { |
96 | struct dma_map_ops *dma_ops = get_dma_ops(dev); | 102 | struct dma_map_ops *dma_ops = get_dma_ops(dev); |
97 | 103 | ||
98 | dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); | 104 | dma_ops->free(dev, size, cpu_addr, dma_handle, attrs); |
99 | } | 105 | } |
100 | 106 | ||
101 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) | 107 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) |
diff --git a/arch/unicore32/mm/dma-swiotlb.c b/arch/unicore32/mm/dma-swiotlb.c index bfa9fbb2bbb1..16c08b2143a7 100644 --- a/arch/unicore32/mm/dma-swiotlb.c +++ b/arch/unicore32/mm/dma-swiotlb.c | |||
@@ -17,9 +17,23 @@ | |||
17 | 17 | ||
18 | #include <asm/dma.h> | 18 | #include <asm/dma.h> |
19 | 19 | ||
20 | static void *unicore_swiotlb_alloc_coherent(struct device *dev, size_t size, | ||
21 | dma_addr_t *dma_handle, gfp_t flags, | ||
22 | struct dma_attrs *attrs) | ||
23 | { | ||
24 | return swiotlb_alloc_coherent(dev, size, dma_handle, flags); | ||
25 | } | ||
26 | |||
27 | static void unicore_swiotlb_free_coherent(struct device *dev, size_t size, | ||
28 | void *vaddr, dma_addr_t dma_addr, | ||
29 | struct dma_attrs *attrs) | ||
30 | { | ||
31 | swiotlb_free_coherent(dev, size, vaddr, dma_addr); | ||
32 | } | ||
33 | |||
20 | struct dma_map_ops swiotlb_dma_map_ops = { | 34 | struct dma_map_ops swiotlb_dma_map_ops = { |
21 | .alloc_coherent = swiotlb_alloc_coherent, | 35 | .alloc = unicore_swiotlb_alloc_coherent, |
22 | .free_coherent = swiotlb_free_coherent, | 36 | .free = unicore_swiotlb_free_coherent, |
23 | .map_sg = swiotlb_map_sg_attrs, | 37 | .map_sg = swiotlb_map_sg_attrs, |
24 | .unmap_sg = swiotlb_unmap_sg_attrs, | 38 | .unmap_sg = swiotlb_unmap_sg_attrs, |
25 | .dma_supported = swiotlb_dma_supported, | 39 | .dma_supported = swiotlb_dma_supported, |
diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h index ed3065fd6314..4b4331d71935 100644 --- a/arch/x86/include/asm/dma-mapping.h +++ b/arch/x86/include/asm/dma-mapping.h | |||
@@ -59,7 +59,8 @@ extern int dma_supported(struct device *hwdev, u64 mask); | |||
59 | extern int dma_set_mask(struct device *dev, u64 mask); | 59 | extern int dma_set_mask(struct device *dev, u64 mask); |
60 | 60 | ||
61 | extern void *dma_generic_alloc_coherent(struct device *dev, size_t size, | 61 | extern void *dma_generic_alloc_coherent(struct device *dev, size_t size, |
62 | dma_addr_t *dma_addr, gfp_t flag); | 62 | dma_addr_t *dma_addr, gfp_t flag, |
63 | struct dma_attrs *attrs); | ||
63 | 64 | ||
64 | static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) | 65 | static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) |
65 | { | 66 | { |
@@ -111,9 +112,11 @@ static inline gfp_t dma_alloc_coherent_gfp_flags(struct device *dev, gfp_t gfp) | |||
111 | return gfp; | 112 | return gfp; |
112 | } | 113 | } |
113 | 114 | ||
115 | #define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL) | ||
116 | |||
114 | static inline void * | 117 | static inline void * |
115 | dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | 118 | dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle, |
116 | gfp_t gfp) | 119 | gfp_t gfp, struct dma_attrs *attrs) |
117 | { | 120 | { |
118 | struct dma_map_ops *ops = get_dma_ops(dev); | 121 | struct dma_map_ops *ops = get_dma_ops(dev); |
119 | void *memory; | 122 | void *memory; |
@@ -129,18 +132,21 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
129 | if (!is_device_dma_capable(dev)) | 132 | if (!is_device_dma_capable(dev)) |
130 | return NULL; | 133 | return NULL; |
131 | 134 | ||
132 | if (!ops->alloc_coherent) | 135 | if (!ops->alloc) |
133 | return NULL; | 136 | return NULL; |
134 | 137 | ||
135 | memory = ops->alloc_coherent(dev, size, dma_handle, | 138 | memory = ops->alloc(dev, size, dma_handle, |
136 | dma_alloc_coherent_gfp_flags(dev, gfp)); | 139 | dma_alloc_coherent_gfp_flags(dev, gfp), attrs); |
137 | debug_dma_alloc_coherent(dev, size, *dma_handle, memory); | 140 | debug_dma_alloc_coherent(dev, size, *dma_handle, memory); |
138 | 141 | ||
139 | return memory; | 142 | return memory; |
140 | } | 143 | } |
141 | 144 | ||
142 | static inline void dma_free_coherent(struct device *dev, size_t size, | 145 | #define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) |
143 | void *vaddr, dma_addr_t bus) | 146 | |
147 | static inline void dma_free_attrs(struct device *dev, size_t size, | ||
148 | void *vaddr, dma_addr_t bus, | ||
149 | struct dma_attrs *attrs) | ||
144 | { | 150 | { |
145 | struct dma_map_ops *ops = get_dma_ops(dev); | 151 | struct dma_map_ops *ops = get_dma_ops(dev); |
146 | 152 | ||
@@ -150,8 +156,8 @@ static inline void dma_free_coherent(struct device *dev, size_t size, | |||
150 | return; | 156 | return; |
151 | 157 | ||
152 | debug_dma_free_coherent(dev, size, vaddr, bus); | 158 | debug_dma_free_coherent(dev, size, vaddr, bus); |
153 | if (ops->free_coherent) | 159 | if (ops->free) |
154 | ops->free_coherent(dev, size, vaddr, bus); | 160 | ops->free(dev, size, vaddr, bus, attrs); |
155 | } | 161 | } |
156 | 162 | ||
157 | #endif | 163 | #endif |
diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c index b1e7c7f7a0af..e66311200cbd 100644 --- a/arch/x86/kernel/amd_gart_64.c +++ b/arch/x86/kernel/amd_gart_64.c | |||
@@ -477,7 +477,7 @@ error: | |||
477 | /* allocate and map a coherent mapping */ | 477 | /* allocate and map a coherent mapping */ |
478 | static void * | 478 | static void * |
479 | gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr, | 479 | gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr, |
480 | gfp_t flag) | 480 | gfp_t flag, struct dma_attrs *attrs) |
481 | { | 481 | { |
482 | dma_addr_t paddr; | 482 | dma_addr_t paddr; |
483 | unsigned long align_mask; | 483 | unsigned long align_mask; |
@@ -500,7 +500,8 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr, | |||
500 | } | 500 | } |
501 | __free_pages(page, get_order(size)); | 501 | __free_pages(page, get_order(size)); |
502 | } else | 502 | } else |
503 | return dma_generic_alloc_coherent(dev, size, dma_addr, flag); | 503 | return dma_generic_alloc_coherent(dev, size, dma_addr, flag, |
504 | attrs); | ||
504 | 505 | ||
505 | return NULL; | 506 | return NULL; |
506 | } | 507 | } |
@@ -508,7 +509,7 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr, | |||
508 | /* free a coherent mapping */ | 509 | /* free a coherent mapping */ |
509 | static void | 510 | static void |
510 | gart_free_coherent(struct device *dev, size_t size, void *vaddr, | 511 | gart_free_coherent(struct device *dev, size_t size, void *vaddr, |
511 | dma_addr_t dma_addr) | 512 | dma_addr_t dma_addr, struct dma_attrs *attrs) |
512 | { | 513 | { |
513 | gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, NULL); | 514 | gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, NULL); |
514 | free_pages((unsigned long)vaddr, get_order(size)); | 515 | free_pages((unsigned long)vaddr, get_order(size)); |
@@ -700,8 +701,8 @@ static struct dma_map_ops gart_dma_ops = { | |||
700 | .unmap_sg = gart_unmap_sg, | 701 | .unmap_sg = gart_unmap_sg, |
701 | .map_page = gart_map_page, | 702 | .map_page = gart_map_page, |
702 | .unmap_page = gart_unmap_page, | 703 | .unmap_page = gart_unmap_page, |
703 | .alloc_coherent = gart_alloc_coherent, | 704 | .alloc = gart_alloc_coherent, |
704 | .free_coherent = gart_free_coherent, | 705 | .free = gart_free_coherent, |
705 | .mapping_error = gart_mapping_error, | 706 | .mapping_error = gart_mapping_error, |
706 | }; | 707 | }; |
707 | 708 | ||
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index 6ac5782f4d6b..d0b2fb9ccbb1 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c | |||
@@ -430,7 +430,7 @@ static void calgary_unmap_page(struct device *dev, dma_addr_t dma_addr, | |||
430 | } | 430 | } |
431 | 431 | ||
432 | static void* calgary_alloc_coherent(struct device *dev, size_t size, | 432 | static void* calgary_alloc_coherent(struct device *dev, size_t size, |
433 | dma_addr_t *dma_handle, gfp_t flag) | 433 | dma_addr_t *dma_handle, gfp_t flag, struct dma_attrs *attrs) |
434 | { | 434 | { |
435 | void *ret = NULL; | 435 | void *ret = NULL; |
436 | dma_addr_t mapping; | 436 | dma_addr_t mapping; |
@@ -463,7 +463,8 @@ error: | |||
463 | } | 463 | } |
464 | 464 | ||
465 | static void calgary_free_coherent(struct device *dev, size_t size, | 465 | static void calgary_free_coherent(struct device *dev, size_t size, |
466 | void *vaddr, dma_addr_t dma_handle) | 466 | void *vaddr, dma_addr_t dma_handle, |
467 | struct dma_attrs *attrs) | ||
467 | { | 468 | { |
468 | unsigned int npages; | 469 | unsigned int npages; |
469 | struct iommu_table *tbl = find_iommu_table(dev); | 470 | struct iommu_table *tbl = find_iommu_table(dev); |
@@ -476,8 +477,8 @@ static void calgary_free_coherent(struct device *dev, size_t size, | |||
476 | } | 477 | } |
477 | 478 | ||
478 | static struct dma_map_ops calgary_dma_ops = { | 479 | static struct dma_map_ops calgary_dma_ops = { |
479 | .alloc_coherent = calgary_alloc_coherent, | 480 | .alloc = calgary_alloc_coherent, |
480 | .free_coherent = calgary_free_coherent, | 481 | .free = calgary_free_coherent, |
481 | .map_sg = calgary_map_sg, | 482 | .map_sg = calgary_map_sg, |
482 | .unmap_sg = calgary_unmap_sg, | 483 | .unmap_sg = calgary_unmap_sg, |
483 | .map_page = calgary_map_page, | 484 | .map_page = calgary_map_page, |
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 28e5e06fcba4..3003250ac51d 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c | |||
@@ -96,7 +96,8 @@ void __init pci_iommu_alloc(void) | |||
96 | } | 96 | } |
97 | } | 97 | } |
98 | void *dma_generic_alloc_coherent(struct device *dev, size_t size, | 98 | void *dma_generic_alloc_coherent(struct device *dev, size_t size, |
99 | dma_addr_t *dma_addr, gfp_t flag) | 99 | dma_addr_t *dma_addr, gfp_t flag, |
100 | struct dma_attrs *attrs) | ||
100 | { | 101 | { |
101 | unsigned long dma_mask; | 102 | unsigned long dma_mask; |
102 | struct page *page; | 103 | struct page *page; |
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c index 3af4af810c07..f96050685b46 100644 --- a/arch/x86/kernel/pci-nommu.c +++ b/arch/x86/kernel/pci-nommu.c | |||
@@ -75,7 +75,7 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, | |||
75 | } | 75 | } |
76 | 76 | ||
77 | static void nommu_free_coherent(struct device *dev, size_t size, void *vaddr, | 77 | static void nommu_free_coherent(struct device *dev, size_t size, void *vaddr, |
78 | dma_addr_t dma_addr) | 78 | dma_addr_t dma_addr, struct dma_attrs *attrs) |
79 | { | 79 | { |
80 | free_pages((unsigned long)vaddr, get_order(size)); | 80 | free_pages((unsigned long)vaddr, get_order(size)); |
81 | } | 81 | } |
@@ -96,8 +96,8 @@ static void nommu_sync_sg_for_device(struct device *dev, | |||
96 | } | 96 | } |
97 | 97 | ||
98 | struct dma_map_ops nommu_dma_ops = { | 98 | struct dma_map_ops nommu_dma_ops = { |
99 | .alloc_coherent = dma_generic_alloc_coherent, | 99 | .alloc = dma_generic_alloc_coherent, |
100 | .free_coherent = nommu_free_coherent, | 100 | .free = nommu_free_coherent, |
101 | .map_sg = nommu_map_sg, | 101 | .map_sg = nommu_map_sg, |
102 | .map_page = nommu_map_page, | 102 | .map_page = nommu_map_page, |
103 | .sync_single_for_device = nommu_sync_single_for_device, | 103 | .sync_single_for_device = nommu_sync_single_for_device, |
diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c index 8f972cbddef0..6c483ba98b9c 100644 --- a/arch/x86/kernel/pci-swiotlb.c +++ b/arch/x86/kernel/pci-swiotlb.c | |||
@@ -15,21 +15,30 @@ | |||
15 | int swiotlb __read_mostly; | 15 | int swiotlb __read_mostly; |
16 | 16 | ||
17 | static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, | 17 | static void *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 | { | 20 | { |
20 | void *vaddr; | 21 | void *vaddr; |
21 | 22 | ||
22 | vaddr = dma_generic_alloc_coherent(hwdev, size, dma_handle, flags); | 23 | vaddr = dma_generic_alloc_coherent(hwdev, size, dma_handle, flags, |
24 | attrs); | ||
23 | if (vaddr) | 25 | if (vaddr) |
24 | return vaddr; | 26 | return vaddr; |
25 | 27 | ||
26 | return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags); | 28 | return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags); |
27 | } | 29 | } |
28 | 30 | ||
31 | static void x86_swiotlb_free_coherent(struct device *dev, size_t size, | ||
32 | void *vaddr, dma_addr_t dma_addr, | ||
33 | struct dma_attrs *attrs) | ||
34 | { | ||
35 | swiotlb_free_coherent(dev, size, vaddr, dma_addr); | ||
36 | } | ||
37 | |||
29 | static struct dma_map_ops swiotlb_dma_ops = { | 38 | static struct dma_map_ops swiotlb_dma_ops = { |
30 | .mapping_error = swiotlb_dma_mapping_error, | 39 | .mapping_error = swiotlb_dma_mapping_error, |
31 | .alloc_coherent = x86_swiotlb_alloc_coherent, | 40 | .alloc = x86_swiotlb_alloc_coherent, |
32 | .free_coherent = swiotlb_free_coherent, | 41 | .free = x86_swiotlb_free_coherent, |
33 | .sync_single_for_cpu = swiotlb_sync_single_for_cpu, | 42 | .sync_single_for_cpu = swiotlb_sync_single_for_cpu, |
34 | .sync_single_for_device = swiotlb_sync_single_for_device, | 43 | .sync_single_for_device = swiotlb_sync_single_for_device, |
35 | .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, | 44 | .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, |
diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c index b480d4207a4c..967633ad98c4 100644 --- a/arch/x86/xen/pci-swiotlb-xen.c +++ b/arch/x86/xen/pci-swiotlb-xen.c | |||
@@ -12,8 +12,8 @@ int xen_swiotlb __read_mostly; | |||
12 | 12 | ||
13 | static struct dma_map_ops xen_swiotlb_dma_ops = { | 13 | static struct dma_map_ops xen_swiotlb_dma_ops = { |
14 | .mapping_error = xen_swiotlb_dma_mapping_error, | 14 | .mapping_error = xen_swiotlb_dma_mapping_error, |
15 | .alloc_coherent = xen_swiotlb_alloc_coherent, | 15 | .alloc = xen_swiotlb_alloc_coherent, |
16 | .free_coherent = xen_swiotlb_free_coherent, | 16 | .free = xen_swiotlb_free_coherent, |
17 | .sync_single_for_cpu = xen_swiotlb_sync_single_for_cpu, | 17 | .sync_single_for_cpu = xen_swiotlb_sync_single_for_cpu, |
18 | .sync_single_for_device = xen_swiotlb_sync_single_for_device, | 18 | .sync_single_for_device = xen_swiotlb_sync_single_for_device, |
19 | .sync_sg_for_cpu = xen_swiotlb_sync_sg_for_cpu, | 19 | .sync_sg_for_cpu = xen_swiotlb_sync_sg_for_cpu, |
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index ae2ec929e52f..a5bee8e2dfce 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
@@ -2707,7 +2707,8 @@ static void unmap_sg(struct device *dev, struct scatterlist *sglist, | |||
2707 | * The exported alloc_coherent function for dma_ops. | 2707 | * The exported alloc_coherent function for dma_ops. |
2708 | */ | 2708 | */ |
2709 | static void *alloc_coherent(struct device *dev, size_t size, | 2709 | static void *alloc_coherent(struct device *dev, size_t size, |
2710 | dma_addr_t *dma_addr, gfp_t flag) | 2710 | dma_addr_t *dma_addr, gfp_t flag, |
2711 | struct dma_attrs *attrs) | ||
2711 | { | 2712 | { |
2712 | unsigned long flags; | 2713 | unsigned long flags; |
2713 | void *virt_addr; | 2714 | void *virt_addr; |
@@ -2765,7 +2766,8 @@ out_free: | |||
2765 | * The exported free_coherent function for dma_ops. | 2766 | * The exported free_coherent function for dma_ops. |
2766 | */ | 2767 | */ |
2767 | static void free_coherent(struct device *dev, size_t size, | 2768 | static void free_coherent(struct device *dev, size_t size, |
2768 | void *virt_addr, dma_addr_t dma_addr) | 2769 | void *virt_addr, dma_addr_t dma_addr, |
2770 | struct dma_attrs *attrs) | ||
2769 | { | 2771 | { |
2770 | unsigned long flags; | 2772 | unsigned long flags; |
2771 | struct protection_domain *domain; | 2773 | struct protection_domain *domain; |
@@ -2846,8 +2848,8 @@ static void __init prealloc_protection_domains(void) | |||
2846 | } | 2848 | } |
2847 | 2849 | ||
2848 | static struct dma_map_ops amd_iommu_dma_ops = { | 2850 | static struct dma_map_ops amd_iommu_dma_ops = { |
2849 | .alloc_coherent = alloc_coherent, | 2851 | .alloc = alloc_coherent, |
2850 | .free_coherent = free_coherent, | 2852 | .free = free_coherent, |
2851 | .map_page = map_page, | 2853 | .map_page = map_page, |
2852 | .unmap_page = unmap_page, | 2854 | .unmap_page = unmap_page, |
2853 | .map_sg = map_sg, | 2855 | .map_sg = map_sg, |
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 132f93b05154..f93d5ac8f81c 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -2949,7 +2949,8 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr, | |||
2949 | } | 2949 | } |
2950 | 2950 | ||
2951 | static void *intel_alloc_coherent(struct device *hwdev, size_t size, | 2951 | static void *intel_alloc_coherent(struct device *hwdev, size_t size, |
2952 | dma_addr_t *dma_handle, gfp_t flags) | 2952 | dma_addr_t *dma_handle, gfp_t flags, |
2953 | struct dma_attrs *attrs) | ||
2953 | { | 2954 | { |
2954 | void *vaddr; | 2955 | void *vaddr; |
2955 | int order; | 2956 | int order; |
@@ -2981,7 +2982,7 @@ static void *intel_alloc_coherent(struct device *hwdev, size_t size, | |||
2981 | } | 2982 | } |
2982 | 2983 | ||
2983 | static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr, | 2984 | static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr, |
2984 | dma_addr_t dma_handle) | 2985 | dma_addr_t dma_handle, struct dma_attrs *attrs) |
2985 | { | 2986 | { |
2986 | int order; | 2987 | int order; |
2987 | 2988 | ||
@@ -3126,8 +3127,8 @@ static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr) | |||
3126 | } | 3127 | } |
3127 | 3128 | ||
3128 | struct dma_map_ops intel_dma_ops = { | 3129 | struct dma_map_ops intel_dma_ops = { |
3129 | .alloc_coherent = intel_alloc_coherent, | 3130 | .alloc = intel_alloc_coherent, |
3130 | .free_coherent = intel_free_coherent, | 3131 | .free = intel_free_coherent, |
3131 | .map_sg = intel_map_sg, | 3132 | .map_sg = intel_map_sg, |
3132 | .unmap_sg = intel_unmap_sg, | 3133 | .unmap_sg = intel_unmap_sg, |
3133 | .map_page = intel_map_page, | 3134 | .map_page = intel_map_page, |
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index 19e6a2041371..1afb4fba11b4 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c | |||
@@ -204,7 +204,8 @@ error: | |||
204 | 204 | ||
205 | void * | 205 | void * |
206 | xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size, | 206 | xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size, |
207 | dma_addr_t *dma_handle, gfp_t flags) | 207 | dma_addr_t *dma_handle, gfp_t flags, |
208 | struct dma_attrs *attrs) | ||
208 | { | 209 | { |
209 | void *ret; | 210 | void *ret; |
210 | int order = get_order(size); | 211 | int order = get_order(size); |
@@ -253,7 +254,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_alloc_coherent); | |||
253 | 254 | ||
254 | void | 255 | void |
255 | xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, | 256 | xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, |
256 | dma_addr_t dev_addr) | 257 | dma_addr_t dev_addr, struct dma_attrs *attrs) |
257 | { | 258 | { |
258 | int order = get_order(size); | 259 | int order = get_order(size); |
259 | phys_addr_t phys; | 260 | phys_addr_t phys; |
diff --git a/include/linux/dma-attrs.h b/include/linux/dma-attrs.h index 71ad34eca6e3..547ab568d3ae 100644 --- a/include/linux/dma-attrs.h +++ b/include/linux/dma-attrs.h | |||
@@ -13,6 +13,8 @@ | |||
13 | enum dma_attr { | 13 | enum dma_attr { |
14 | DMA_ATTR_WRITE_BARRIER, | 14 | DMA_ATTR_WRITE_BARRIER, |
15 | DMA_ATTR_WEAK_ORDERING, | 15 | DMA_ATTR_WEAK_ORDERING, |
16 | DMA_ATTR_WRITE_COMBINE, | ||
17 | DMA_ATTR_NON_CONSISTENT, | ||
16 | DMA_ATTR_MAX, | 18 | DMA_ATTR_MAX, |
17 | }; | 19 | }; |
18 | 20 | ||
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 5a736af3cc7a..dfc099e56a66 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h | |||
@@ -9,10 +9,15 @@ | |||
9 | #include <linux/scatterlist.h> | 9 | #include <linux/scatterlist.h> |
10 | 10 | ||
11 | struct dma_map_ops { | 11 | struct dma_map_ops { |
12 | void* (*alloc_coherent)(struct device *dev, size_t size, | 12 | void* (*alloc)(struct device *dev, size_t size, |
13 | dma_addr_t *dma_handle, gfp_t gfp); | 13 | dma_addr_t *dma_handle, gfp_t gfp, |
14 | void (*free_coherent)(struct device *dev, size_t size, | 14 | struct dma_attrs *attrs); |
15 | void *vaddr, dma_addr_t dma_handle); | 15 | void (*free)(struct device *dev, size_t size, |
16 | void *vaddr, dma_addr_t dma_handle, | ||
17 | struct dma_attrs *attrs); | ||
18 | int (*mmap)(struct device *, struct vm_area_struct *, | ||
19 | void *, dma_addr_t, size_t, struct dma_attrs *attrs); | ||
20 | |||
16 | dma_addr_t (*map_page)(struct device *dev, struct page *page, | 21 | dma_addr_t (*map_page)(struct device *dev, struct page *page, |
17 | unsigned long offset, size_t size, | 22 | unsigned long offset, size_t size, |
18 | enum dma_data_direction dir, | 23 | enum dma_data_direction dir, |
diff --git a/include/xen/swiotlb-xen.h b/include/xen/swiotlb-xen.h index 2ea2fdc79c16..4f4d449f00f6 100644 --- a/include/xen/swiotlb-xen.h +++ b/include/xen/swiotlb-xen.h | |||
@@ -7,11 +7,13 @@ extern void xen_swiotlb_init(int verbose); | |||
7 | 7 | ||
8 | extern void | 8 | extern void |
9 | *xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size, | 9 | *xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size, |
10 | dma_addr_t *dma_handle, gfp_t flags); | 10 | dma_addr_t *dma_handle, gfp_t flags, |
11 | struct dma_attrs *attrs); | ||
11 | 12 | ||
12 | extern void | 13 | extern void |
13 | xen_swiotlb_free_coherent(struct device *hwdev, size_t size, | 14 | xen_swiotlb_free_coherent(struct device *hwdev, size_t size, |
14 | void *vaddr, dma_addr_t dma_handle); | 15 | void *vaddr, dma_addr_t dma_handle, |
16 | struct dma_attrs *attrs); | ||
15 | 17 | ||
16 | extern dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page, | 18 | extern dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page, |
17 | unsigned long offset, size_t size, | 19 | unsigned long offset, size_t size, |