From da6f4621d7e20f95ce18be933be08ef151f69427 Mon Sep 17 00:00:00 2001 From: Jianqun Xu Date: Sun, 25 Apr 2021 09:51:07 +0800 Subject: [PATCH] staging: ion: ion_system_heap implement ION_FLAG_DMA32 Change-Id: I580b9cc9f256252b16bbb1211a116bf31c9eacd8 Signed-off-by: Jianqun Xu --- drivers/staging/android/ion/ion_system_heap.c | 53 +++++++++++++++++-- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 6f73363c2282..f2eb41f24100 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -43,14 +43,19 @@ static inline unsigned int order_to_size(int order) struct ion_system_heap { struct ion_heap heap; struct ion_page_pool *pools[NUM_ORDERS]; + struct ion_page_pool *dma32_pools[NUM_ORDERS]; }; static struct page *alloc_buffer_page(struct ion_system_heap *heap, struct ion_buffer *buffer, - unsigned long order) + unsigned long order, + unsigned long flags) { struct ion_page_pool *pool = heap->pools[order_to_index(order)]; + if (flags & ION_FLAG_DMA32) + pool = heap->dma32_pools[order_to_index(order)]; + return ion_page_pool_alloc(pool); } @@ -74,7 +79,8 @@ static void free_buffer_page(struct ion_system_heap *heap, static struct page *alloc_largest_available(struct ion_system_heap *heap, struct ion_buffer *buffer, unsigned long size, - unsigned int max_order) + unsigned int max_order, + unsigned long flags) { struct page *page; int i; @@ -85,7 +91,7 @@ static struct page *alloc_largest_available(struct ion_system_heap *heap, if (max_order < orders[i]) continue; - page = alloc_buffer_page(heap, buffer, orders[i]); + page = alloc_buffer_page(heap, buffer, orders[i], flags); if (!page) continue; @@ -127,7 +133,7 @@ static int ion_system_heap_allocate(struct ion_heap *heap, i = 0; while (size_remaining > 0) { page = alloc_largest_available(sys_heap, buffer, size_remaining, - max_order); + max_order, flags); if (!page) goto free_pages; @@ -286,6 +292,17 @@ static int ion_system_heap_debug_show(struct ion_heap *heap, struct seq_file *s, pool->low_count, pool->order, (PAGE_SIZE << pool->order) * pool->low_count); } + seq_puts(s, "dma32 pools\n"); + for (i = 0; i < NUM_ORDERS; i++) { + pool = sys_heap->dma32_pools[i]; + + seq_printf(s, "%d order %u highmem pages %lu total\n", + pool->high_count, pool->order, + (PAGE_SIZE << pool->order) * pool->high_count); + seq_printf(s, "%d order %u lowmem pages %lu total\n", + pool->low_count, pool->order, + (PAGE_SIZE << pool->order) * pool->low_count); + } return 0; } @@ -322,6 +339,29 @@ err_create_pool: return -ENOMEM; } +static int ion_system_heap_create_dma32_pools(struct ion_page_pool **pools) +{ + int i; + + for (i = 0; i < NUM_ORDERS; i++) { + struct ion_page_pool *pool; + gfp_t gfp_flags = low_order_gfp_flags; + + if (orders[i] > 4) + gfp_flags = high_order_gfp_flags; + + pool = ion_page_pool_create(gfp_flags | GFP_DMA32, orders[i]); + if (!pool) + goto err_create_pool; + pools[i] = pool; + } + return 0; + +err_create_pool: + ion_system_heap_destroy_pools(pools); + return -ENOMEM; +} + static struct ion_heap *__ion_system_heap_create(void) { struct ion_system_heap *heap; @@ -336,9 +376,14 @@ static struct ion_heap *__ion_system_heap_create(void) if (ion_system_heap_create_pools(heap->pools)) goto free_heap; + if (ion_system_heap_create_dma32_pools(heap->dma32_pools)) + goto free_dma32_heap; + heap->heap.debug_show = ion_system_heap_debug_show; return &heap->heap; +free_dma32_heap: + ion_system_heap_destroy_pools(heap->pools); free_heap: kfree(heap); return ERR_PTR(-ENOMEM);