aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2013-06-26 08:49:44 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2013-09-17 10:32:37 -0400
commit4aa806b771d16b810771d86ce23c4c3160888db3 (patch)
tree5450d1495c1ffbb6d852df44002b95de275deb3f
parent272b98c6455f00884f0350f775c5342358ebb73f (diff)
DMA-API: provide a helper to set both DMA and coherent DMA masks
Provide a helper to set both the DMA and coherent DMA masks to the same value - this avoids duplicated code in a number of drivers, sometimes with buggy error handling, and also allows us identify which drivers do things differently. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--Documentation/DMA-API-HOWTO.txt37
-rw-r--r--Documentation/DMA-API.txt8
-rw-r--r--include/linux/dma-mapping.h14
3 files changed, 44 insertions, 15 deletions
diff --git a/Documentation/DMA-API-HOWTO.txt b/Documentation/DMA-API-HOWTO.txt
index 14129f149a75..5e983031cc11 100644
--- a/Documentation/DMA-API-HOWTO.txt
+++ b/Documentation/DMA-API-HOWTO.txt
@@ -101,14 +101,23 @@ style to do this even if your device holds the default setting,
101because this shows that you did think about these issues wrt. your 101because this shows that you did think about these issues wrt. your
102device. 102device.
103 103
104The query is performed via a call to dma_set_mask(): 104The query is performed via a call to dma_set_mask_and_coherent():
105 105
106 int dma_set_mask(struct device *dev, u64 mask); 106 int dma_set_mask_and_coherent(struct device *dev, u64 mask);
107 107
108The query for consistent allocations is performed via a call to 108which will query the mask for both streaming and coherent APIs together.
109dma_set_coherent_mask(): 109If you have some special requirements, then the following two separate
110queries can be used instead:
110 111
111 int dma_set_coherent_mask(struct device *dev, u64 mask); 112 The query for streaming mappings is performed via a call to
113 dma_set_mask():
114
115 int dma_set_mask(struct device *dev, u64 mask);
116
117 The query for consistent allocations is performed via a call
118 to dma_set_coherent_mask():
119
120 int dma_set_coherent_mask(struct device *dev, u64 mask);
112 121
113Here, dev is a pointer to the device struct of your device, and mask 122Here, dev is a pointer to the device struct of your device, and mask
114is a bit mask describing which bits of an address your device 123is a bit mask describing which bits of an address your device
@@ -137,7 +146,7 @@ exactly why.
137 146
138The standard 32-bit addressing device would do something like this: 147The standard 32-bit addressing device would do something like this:
139 148
140 if (dma_set_mask(dev, DMA_BIT_MASK(32))) { 149 if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32))) {
141 printk(KERN_WARNING 150 printk(KERN_WARNING
142 "mydev: No suitable DMA available.\n"); 151 "mydev: No suitable DMA available.\n");
143 goto ignore_this_device; 152 goto ignore_this_device;
@@ -171,22 +180,20 @@ the case would look like this:
171 180
172 int using_dac, consistent_using_dac; 181 int using_dac, consistent_using_dac;
173 182
174 if (!dma_set_mask(dev, DMA_BIT_MASK(64))) { 183 if (!dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) {
175 using_dac = 1; 184 using_dac = 1;
176 consistent_using_dac = 1; 185 consistent_using_dac = 1;
177 dma_set_coherent_mask(dev, DMA_BIT_MASK(64)); 186 } else if (!dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32))) {
178 } else if (!dma_set_mask(dev, DMA_BIT_MASK(32))) {
179 using_dac = 0; 187 using_dac = 0;
180 consistent_using_dac = 0; 188 consistent_using_dac = 0;
181 dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
182 } else { 189 } else {
183 printk(KERN_WARNING 190 printk(KERN_WARNING
184 "mydev: No suitable DMA available.\n"); 191 "mydev: No suitable DMA available.\n");
185 goto ignore_this_device; 192 goto ignore_this_device;
186 } 193 }
187 194
188dma_set_coherent_mask() will always be able to set the same or a 195The coherent coherent mask will always be able to set the same or a
189smaller mask as dma_set_mask(). However for the rare case that a 196smaller mask as the streaming mask. However for the rare case that a
190device driver only uses consistent allocations, one would have to 197device driver only uses consistent allocations, one would have to
191check the return value from dma_set_coherent_mask(). 198check the return value from dma_set_coherent_mask().
192 199
@@ -199,9 +206,9 @@ address you might do something like:
199 goto ignore_this_device; 206 goto ignore_this_device;
200 } 207 }
201 208
202When dma_set_mask() is successful, and returns zero, the kernel saves 209When dma_set_mask() or dma_set_mask_and_coherent() is successful, and
203away this mask you have provided. The kernel will use this 210returns zero, the kernel saves away this mask you have provided. The
204information later when you make DMA mappings. 211kernel will use this information later when you make DMA mappings.
205 212
206There is a case which we are aware of at this time, which is worth 213There is a case which we are aware of at this time, which is worth
207mentioning in this documentation. If your device supports multiple 214mentioning in this documentation. If your device supports multiple
diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt
index 78a6c569d204..e865279cec58 100644
--- a/Documentation/DMA-API.txt
+++ b/Documentation/DMA-API.txt
@@ -142,6 +142,14 @@ internal API for use by the platform than an external API for use by
142driver writers. 142driver writers.
143 143
144int 144int
145dma_set_mask_and_coherent(struct device *dev, u64 mask)
146
147Checks to see if the mask is possible and updates the device
148streaming and coherent DMA mask parameters if it is.
149
150Returns: 0 if successful and a negative error if not.
151
152int
145dma_set_mask(struct device *dev, u64 mask) 153dma_set_mask(struct device *dev, u64 mask)
146 154
147Checks to see if the mask is possible and updates the device 155Checks to see if the mask is possible and updates the device
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 3a8d0a2af607..ec951f98e3d9 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -97,6 +97,20 @@ static inline int dma_set_coherent_mask(struct device *dev, u64 mask)
97} 97}
98#endif 98#endif
99 99
100/*
101 * Set both the DMA mask and the coherent DMA mask to the same thing.
102 * Note that we don't check the return value from dma_set_coherent_mask()
103 * as the DMA API guarantees that the coherent DMA mask can be set to
104 * the same or smaller than the streaming DMA mask.
105 */
106static inline int dma_set_mask_and_coherent(struct device *dev, u64 mask)
107{
108 int rc = dma_set_mask(dev, mask);
109 if (rc == 0)
110 dma_set_coherent_mask(dev, mask);
111 return rc;
112}
113
100extern u64 dma_get_required_mask(struct device *dev); 114extern u64 dma_get_required_mask(struct device *dev);
101 115
102static inline unsigned int dma_get_max_seg_size(struct device *dev) 116static inline unsigned int dma_get_max_seg_size(struct device *dev)