diff options
-rw-r--r-- | drivers/gpu/drm/ttm/ttm_page_alloc.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 9d9d92945f8c..737a2a2e46a5 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c | |||
@@ -683,14 +683,22 @@ int ttm_get_pages(struct list_head *pages, int flags, | |||
683 | gfp_flags |= GFP_HIGHUSER; | 683 | gfp_flags |= GFP_HIGHUSER; |
684 | 684 | ||
685 | for (r = 0; r < count; ++r) { | 685 | for (r = 0; r < count; ++r) { |
686 | p = alloc_page(gfp_flags); | 686 | if ((flags & TTM_PAGE_FLAG_DMA32) && dma_address) { |
687 | void *addr; | ||
688 | addr = dma_alloc_coherent(NULL, PAGE_SIZE, | ||
689 | &dma_address[r], | ||
690 | gfp_flags); | ||
691 | if (addr == NULL) | ||
692 | return -ENOMEM; | ||
693 | p = virt_to_page(addr); | ||
694 | } else | ||
695 | p = alloc_page(gfp_flags); | ||
687 | if (!p) { | 696 | if (!p) { |
688 | 697 | ||
689 | printk(KERN_ERR TTM_PFX | 698 | printk(KERN_ERR TTM_PFX |
690 | "Unable to allocate page."); | 699 | "Unable to allocate page."); |
691 | return -ENOMEM; | 700 | return -ENOMEM; |
692 | } | 701 | } |
693 | |||
694 | list_add(&p->lru, pages); | 702 | list_add(&p->lru, pages); |
695 | } | 703 | } |
696 | return 0; | 704 | return 0; |
@@ -738,12 +746,24 @@ void ttm_put_pages(struct list_head *pages, unsigned page_count, int flags, | |||
738 | unsigned long irq_flags; | 746 | unsigned long irq_flags; |
739 | struct ttm_page_pool *pool = ttm_get_pool(flags, cstate); | 747 | struct ttm_page_pool *pool = ttm_get_pool(flags, cstate); |
740 | struct page *p, *tmp; | 748 | struct page *p, *tmp; |
749 | unsigned r; | ||
741 | 750 | ||
742 | if (pool == NULL) { | 751 | if (pool == NULL) { |
743 | /* No pool for this memory type so free the pages */ | 752 | /* No pool for this memory type so free the pages */ |
744 | 753 | ||
754 | r = page_count-1; | ||
745 | list_for_each_entry_safe(p, tmp, pages, lru) { | 755 | list_for_each_entry_safe(p, tmp, pages, lru) { |
746 | __free_page(p); | 756 | if ((flags & TTM_PAGE_FLAG_DMA32) && dma_address) { |
757 | void *addr = page_address(p); | ||
758 | WARN_ON(!addr || !dma_address[r]); | ||
759 | if (addr) | ||
760 | dma_free_coherent(NULL, PAGE_SIZE, | ||
761 | addr, | ||
762 | dma_address[r]); | ||
763 | dma_address[r] = 0; | ||
764 | } else | ||
765 | __free_page(p); | ||
766 | r--; | ||
747 | } | 767 | } |
748 | /* Make the pages list empty */ | 768 | /* Make the pages list empty */ |
749 | INIT_LIST_HEAD(pages); | 769 | INIT_LIST_HEAD(pages); |