diff options
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 | ||
