diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-11-26 11:19:58 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-02-15 10:22:20 -0500 |
commit | a9c9147eb9b1dba0ce567a41897c7773b4d1b0bc (patch) | |
tree | 178938c909f4717c2e599d6f3de954d7ee8a7f21 /arch/arm/mm/dma-mapping.c | |
parent | 93f1d629e22b08642eb713ad96ac2cb9ade0641c (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.c | 29 |
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 | */ |
407 | static void dma_cache_maint(const void *start, size_t size, int direction) | 407 | static 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 | ||
435 | void ___dma_single_cpu_to_dev(const void *kaddr, size_t size, | 428 | void ___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 | } |
440 | EXPORT_SYMBOL(___dma_single_cpu_to_dev); | 436 | EXPORT_SYMBOL(___dma_single_cpu_to_dev); |
@@ -442,12 +438,15 @@ EXPORT_SYMBOL(___dma_single_cpu_to_dev); | |||
442 | void ___dma_single_dev_to_cpu(const void *kaddr, size_t size, | 438 | void ___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 | } |
447 | EXPORT_SYMBOL(___dma_single_dev_to_cpu); | 445 | EXPORT_SYMBOL(___dma_single_dev_to_cpu); |
448 | 446 | ||
449 | static void dma_cache_maint_page(struct page *page, unsigned long offset, | 447 | static 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); | |||
518 | void ___dma_page_dev_to_cpu(struct page *page, unsigned long off, | 513 | void ___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 | } |
523 | EXPORT_SYMBOL(___dma_page_dev_to_cpu); | 518 | EXPORT_SYMBOL(___dma_page_dev_to_cpu); |
524 | 519 | ||