diff options
-rw-r--r-- | arch/x86/kernel/pci-gart_64.c | 43 |
1 files changed, 20 insertions, 23 deletions
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index 7e08e466b8ad..25c94fb96d74 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c | |||
@@ -487,31 +487,28 @@ static void * | |||
487 | gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr, | 487 | gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr, |
488 | gfp_t flag) | 488 | gfp_t flag) |
489 | { | 489 | { |
490 | void *vaddr; | ||
491 | dma_addr_t paddr; | 490 | dma_addr_t paddr; |
492 | unsigned long align_mask; | 491 | unsigned long align_mask; |
493 | u64 dma_mask = dma_alloc_coherent_mask(dev, flag); | 492 | struct page *page; |
494 | 493 | ||
495 | vaddr = (void *)__get_free_pages(flag | __GFP_ZERO, get_order(size)); | 494 | if (force_iommu && !(flag & GFP_DMA)) { |
496 | if (!vaddr) | 495 | flag &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32); |
497 | return NULL; | 496 | page = alloc_pages(flag | __GFP_ZERO, get_order(size)); |
498 | 497 | if (!page) | |
499 | paddr = virt_to_phys(vaddr); | 498 | return NULL; |
500 | if (is_buffer_dma_capable(dma_mask, paddr, size)) { | 499 | |
501 | *dma_addr = paddr; | 500 | align_mask = (1UL << get_order(size)) - 1; |
502 | return vaddr; | 501 | paddr = dma_map_area(dev, page_to_phys(page), size, |
503 | } | 502 | DMA_BIDIRECTIONAL, align_mask); |
504 | 503 | ||
505 | align_mask = (1UL << get_order(size)) - 1; | 504 | flush_gart(); |
506 | 505 | if (paddr != bad_dma_address) { | |
507 | *dma_addr = dma_map_area(dev, paddr, size, DMA_BIDIRECTIONAL, | 506 | *dma_addr = paddr; |
508 | align_mask); | 507 | return page_address(page); |
509 | flush_gart(); | 508 | } |
510 | 509 | __free_pages(page, get_order(size)); | |
511 | if (*dma_addr != bad_dma_address) | 510 | } else |
512 | return vaddr; | 511 | return dma_generic_alloc_coherent(dev, size, dma_addr, flag); |
513 | |||
514 | free_pages((unsigned long)vaddr, get_order(size)); | ||
515 | 512 | ||
516 | return NULL; | 513 | return NULL; |
517 | } | 514 | } |