diff options
| -rw-r--r-- | drivers/gpu/ion/ion_chunk_heap.c | 34 | 
1 files changed, 32 insertions, 2 deletions
diff --git a/drivers/gpu/ion/ion_chunk_heap.c b/drivers/gpu/ion/ion_chunk_heap.c index 7f482b62547..cc824f3a81d 100644 --- a/drivers/gpu/ion/ion_chunk_heap.c +++ b/drivers/gpu/ion/ion_chunk_heap.c @@ -140,6 +140,10 @@ static struct ion_heap_ops chunk_heap_ops = {  struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data)  {  	struct ion_chunk_heap *chunk_heap; +	struct vm_struct *vm_struct; +	pgprot_t pgprot = pgprot_writecombine(PAGE_KERNEL); +	int i, ret; +  	chunk_heap = kzalloc(sizeof(struct ion_chunk_heap), GFP_KERNEL);  	if (!chunk_heap) @@ -149,12 +153,30 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data)  	chunk_heap->pool = gen_pool_create(get_order(chunk_heap->chunk_size) +  					   PAGE_SHIFT, -1);  	if (!chunk_heap->pool) { -		kfree(chunk_heap); -		return ERR_PTR(-ENOMEM); +		ret = -ENOMEM; +		goto error_gen_pool_create;  	}  	chunk_heap->base = heap_data->base;  	chunk_heap->size = heap_data->size;  	chunk_heap->allocated = 0; + +	vm_struct = get_vm_area(PAGE_SIZE, VM_ALLOC); +	if (!vm_struct) { +		ret = -ENOMEM; +		goto error; +	} +	for (i = 0; i < chunk_heap->size; i += PAGE_SIZE) { +		struct page *page = phys_to_page(chunk_heap->base + i); +		struct page **pages = &page; + +		ret = map_vm_area(vm_struct, pgprot, &pages); +		if (ret) +			goto error_map_vm_area; +		memset(vm_struct->addr, 0, PAGE_SIZE); +		unmap_kernel_range((unsigned long)vm_struct->addr, PAGE_SIZE); +	} +	free_vm_area(vm_struct); +  	__dma_page_cpu_to_dev(phys_to_page(heap_data->base), 0, heap_data->size,  			      DMA_BIDIRECTIONAL);  	gen_pool_add(chunk_heap->pool, chunk_heap->base, heap_data->size, -1); @@ -165,6 +187,14 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data)  		heap_data->size, heap_data->align);  	return &chunk_heap->heap; + +error_map_vm_area: +	free_vm_area(vm_struct); +error: +	gen_pool_destroy(chunk_heap->pool); +error_gen_pool_create: +	kfree(chunk_heap); +	return ERR_PTR(ret);  }  void ion_chunk_heap_destroy(struct ion_heap *heap)  |