aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/dma-mapping.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2009-11-26 11:19:58 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-02-15 10:22:20 -0500
commita9c9147eb9b1dba0ce567a41897c7773b4d1b0bc (patch)
tree178938c909f4717c2e599d6f3de954d7ee8a7f21 /arch/arm/mm/dma-mapping.c
parent93f1d629e22b08642eb713ad96ac2cb9ade0641c (diff)
ARM: dma-mapping: provide per-cpu type map/unmap functions
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Tested-By: Santosh Shilimkar <santosh.shilimkar@ti.com>
Diffstat (limited to 'arch/arm/mm/dma-mapping.c')
-rw-r--r--arch/arm/mm/dma-mapping.c29
1 files changed, 12 insertions, 17 deletions
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 0d68d2c83cda..efa8efa33f5e 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -406,35 +406,31 @@ EXPORT_SYMBOL(dma_free_coherent);
406 */ 406 */
407static void dma_cache_maint(const void *start, size_t size, int direction) 407static void dma_cache_maint(const void *start, size_t size, int direction)
408{ 408{
409 void (*inner_op)(const void *, const void *);
410 void (*outer_op)(unsigned long, unsigned long); 409 void (*outer_op)(unsigned long, unsigned long);
411 410
412 BUG_ON(!virt_addr_valid(start) || !virt_addr_valid(start + size - 1));
413
414 switch (direction) { 411 switch (direction) {
415 case DMA_FROM_DEVICE: /* invalidate only */ 412 case DMA_FROM_DEVICE: /* invalidate only */
416 inner_op = dmac_inv_range;
417 outer_op = outer_inv_range; 413 outer_op = outer_inv_range;
418 break; 414 break;
419 case DMA_TO_DEVICE: /* writeback only */ 415 case DMA_TO_DEVICE: /* writeback only */
420 inner_op = dmac_clean_range;
421 outer_op = outer_clean_range; 416 outer_op = outer_clean_range;
422 break; 417 break;
423 case DMA_BIDIRECTIONAL: /* writeback and invalidate */ 418 case DMA_BIDIRECTIONAL: /* writeback and invalidate */
424 inner_op = dmac_flush_range;
425 outer_op = outer_flush_range; 419 outer_op = outer_flush_range;
426 break; 420 break;
427 default: 421 default:
428 BUG(); 422 BUG();
429 } 423 }
430 424
431 inner_op(start, start + size);
432 outer_op(__pa(start), __pa(start) + size); 425 outer_op(__pa(start), __pa(start) + size);
433} 426}
434 427
435void ___dma_single_cpu_to_dev(const void *kaddr, size_t size, 428void ___dma_single_cpu_to_dev(const void *kaddr, size_t size,
436 enum dma_data_direction dir) 429 enum dma_data_direction dir)
437{ 430{
431 BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));
432
433 dmac_map_area(kaddr, size, dir);
438 dma_cache_maint(kaddr, size, dir); 434 dma_cache_maint(kaddr, size, dir);
439} 435}
440EXPORT_SYMBOL(___dma_single_cpu_to_dev); 436EXPORT_SYMBOL(___dma_single_cpu_to_dev);
@@ -442,12 +438,15 @@ EXPORT_SYMBOL(___dma_single_cpu_to_dev);
442void ___dma_single_dev_to_cpu(const void *kaddr, size_t size, 438void ___dma_single_dev_to_cpu(const void *kaddr, size_t size,
443 enum dma_data_direction dir) 439 enum dma_data_direction dir)
444{ 440{
445 /* nothing to do */ 441 BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));
442
443 dmac_unmap_area(kaddr, size, dir);
446} 444}
447EXPORT_SYMBOL(___dma_single_dev_to_cpu); 445EXPORT_SYMBOL(___dma_single_dev_to_cpu);
448 446
449static void dma_cache_maint_page(struct page *page, unsigned long offset, 447static void dma_cache_maint_page(struct page *page, unsigned long offset,
450 size_t size, void (*op)(const void *, const void *)) 448 size_t size, enum dma_data_direction dir,
449 void (*op)(const void *, size_t, int))
451{ 450{
452 /* 451 /*
453 * A single sg entry may refer to multiple physically contiguous 452 * A single sg entry may refer to multiple physically contiguous
@@ -471,12 +470,12 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset,
471 vaddr = kmap_high_get(page); 470 vaddr = kmap_high_get(page);
472 if (vaddr) { 471 if (vaddr) {
473 vaddr += offset; 472 vaddr += offset;
474 op(vaddr, vaddr + len); 473 op(vaddr, len, dir);
475 kunmap_high(page); 474 kunmap_high(page);
476 } 475 }
477 } else { 476 } else {
478 vaddr = page_address(page) + offset; 477 vaddr = page_address(page) + offset;
479 op(vaddr, vaddr + len); 478 op(vaddr, len, dir);
480 } 479 }
481 offset = 0; 480 offset = 0;
482 page++; 481 page++;
@@ -488,27 +487,23 @@ void ___dma_page_cpu_to_dev(struct page *page, unsigned long off,
488 size_t size, enum dma_data_direction dir) 487 size_t size, enum dma_data_direction dir)
489{ 488{
490 unsigned long paddr; 489 unsigned long paddr;
491 void (*inner_op)(const void *, const void *);
492 void (*outer_op)(unsigned long, unsigned long); 490 void (*outer_op)(unsigned long, unsigned long);
493 491
494 switch (direction) { 492 switch (direction) {
495 case DMA_FROM_DEVICE: /* invalidate only */ 493 case DMA_FROM_DEVICE: /* invalidate only */
496 inner_op = dmac_inv_range;
497 outer_op = outer_inv_range; 494 outer_op = outer_inv_range;
498 break; 495 break;
499 case DMA_TO_DEVICE: /* writeback only */ 496 case DMA_TO_DEVICE: /* writeback only */
500 inner_op = dmac_clean_range;
501 outer_op = outer_clean_range; 497 outer_op = outer_clean_range;
502 break; 498 break;
503 case DMA_BIDIRECTIONAL: /* writeback and invalidate */ 499 case DMA_BIDIRECTIONAL: /* writeback and invalidate */
504 inner_op = dmac_flush_range;
505 outer_op = outer_flush_range; 500 outer_op = outer_flush_range;
506 break; 501 break;
507 default: 502 default:
508 BUG(); 503 BUG();
509 } 504 }
510 505
511 dma_cache_maint_page(page, off, size, inner_op); 506 dma_cache_maint_page(page, off, size, dir, dmac_map_area);
512 507
513 paddr = page_to_phys(page) + off; 508 paddr = page_to_phys(page) + off;
514 outer_op(paddr, paddr + size); 509 outer_op(paddr, paddr + size);
@@ -518,7 +513,7 @@ EXPORT_SYMBOL(___dma_page_cpu_to_dev);
518void ___dma_page_dev_to_cpu(struct page *page, unsigned long off, 513void ___dma_page_dev_to_cpu(struct page *page, unsigned long off,
519 size_t size, enum dma_data_direction dir) 514 size_t size, enum dma_data_direction dir)
520{ 515{
521 /* nothing to do */ 516 dma_cache_maint_page(page, off, size, dir, dmac_unmap_area);
522} 517}
523EXPORT_SYMBOL(___dma_page_dev_to_cpu); 518EXPORT_SYMBOL(___dma_page_dev_to_cpu);
524 519