aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2009-11-19 16:12:17 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-11-24 12:41:35 -0500
commit31ebf94435f74294523683867fe0b89000e61521 (patch)
tree57f587da490f9c8bbf987d4165a5ede7f7ad5d63
parentebd7a845fa4332da3ebcbe8cf1b09bb43413420e (diff)
ARM: dma-mapping: Factor out noMMU dma buffer allocation code
This entirely separates the DMA coherent buffer remapping code from the allocation code, and gets rid of the duplicate copy in the !MMU section. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Acked-by: Greg Ungerer <gerg@uclinux.org>
-rw-r--r--arch/arm/mm/dma-mapping.c45
1 files changed, 15 insertions, 30 deletions
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 3a8e527c774c..707d81247630 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -183,27 +183,13 @@ static int __init consistent_init(void)
183core_initcall(consistent_init); 183core_initcall(consistent_init);
184 184
185static void * 185static void *
186__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, 186__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
187 pgprot_t prot)
188{ 187{
189 struct page *page;
190 struct arm_vmregion *c; 188 struct arm_vmregion *c;
191 189
192 size = PAGE_ALIGN(size);
193
194 page = __dma_alloc_buffer(dev, size, gfp);
195 if (!page)
196 goto no_page;
197
198 if (arch_is_coherent()) {
199 *handle = page_to_dma(dev, page);
200 return page_address(page);
201 }
202
203 if (!consistent_pte[0]) { 190 if (!consistent_pte[0]) {
204 printk(KERN_ERR "%s: not initialised\n", __func__); 191 printk(KERN_ERR "%s: not initialised\n", __func__);
205 dump_stack(); 192 dump_stack();
206 __dma_free_buffer(page, size);
207 return NULL; 193 return NULL;
208 } 194 }
209 195
@@ -220,11 +206,6 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
220 pte = consistent_pte[idx] + off; 206 pte = consistent_pte[idx] + off;
221 c->vm_pages = page; 207 c->vm_pages = page;
222 208
223 /*
224 * Set the "dma handle"
225 */
226 *handle = page_to_dma(dev, page);
227
228 do { 209 do {
229 BUG_ON(!pte_none(*pte)); 210 BUG_ON(!pte_none(*pte));
230 211
@@ -244,11 +225,6 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
244 225
245 return (void *)c->vm_start; 226 return (void *)c->vm_start;
246 } 227 }
247
248 if (page)
249 __dma_free_buffer(page, size);
250 no_page:
251 *handle = ~0;
252 return NULL; 228 return NULL;
253} 229}
254 230
@@ -315,11 +291,17 @@ static void __dma_free_remap(void *cpu_addr, size_t size)
315 291
316#else /* !CONFIG_MMU */ 292#else /* !CONFIG_MMU */
317 293
294#define __dma_alloc_remap(page, size, gfp, prot) page_address(page)
295#define __dma_free_remap(addr, size) do { } while (0)
296
297#endif /* CONFIG_MMU */
298
318static void * 299static void *
319__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, 300__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
320 pgprot_t prot) 301 pgprot_t prot)
321{ 302{
322 struct page *page; 303 struct page *page;
304 void *addr;
323 305
324 *handle = ~0; 306 *handle = ~0;
325 size = PAGE_ALIGN(size); 307 size = PAGE_ALIGN(size);
@@ -328,13 +310,16 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
328 if (!page) 310 if (!page)
329 return NULL; 311 return NULL;
330 312
331 *handle = page_to_dma(dev, page); 313 if (!arch_is_coherent())
332 return page_address(page); 314 addr = __dma_alloc_remap(page, size, gfp, prot);
333} 315 else
316 addr = page_address(page);
334 317
335#define __dma_free_remap(addr, size) do { } while (0) 318 if (addr)
319 *handle = page_to_dma(dev, page);
336 320
337#endif /* CONFIG_MMU */ 321 return addr;
322}
338 323
339/* 324/*
340 * Allocate DMA-coherent memory space and return both the kernel remapped 325 * Allocate DMA-coherent memory space and return both the kernel remapped