2 * Copyright (C) 2013-2015 ARM Limited. All rights reserved.
4 * This program is free software and is provided to you under the terms of the GNU General Public License version 2
5 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
7 * A copy of the licence is included with the program, and can also be obtained from Free Software
8 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
11 #include <linux/list.h>
13 #include <linux/mm_types.h>
15 #include <linux/dma-mapping.h>
16 #include <linux/slab.h>
17 #include <linux/platform_device.h>
20 #include "mali_osk_mali.h"
21 #include "mali_kernel_linux.h"
22 #include "mali_scheduler.h"
24 #include "mali_memory.h"
25 #include "mali_memory_os_alloc.h"
26 #if defined(CONFIG_DMA_SHARED_BUFFER)
27 #include "mali_memory_dma_buf.h"
28 #include "mali_memory_secure.h"
30 #if defined(CONFIG_MALI400_UMP)
31 #include "mali_memory_ump.h"
33 #include "mali_memory_external.h"
34 #include "mali_memory_manager.h"
35 #include "mali_memory_virtual.h"
36 #include "mali_memory_cow.h"
37 #include "mali_memory_block_alloc.h"
38 #include "mali_memory_swap_alloc.h"
43 *function @_mali_free_allocation_mem - free a memory allocation
45 static u32 _mali_free_allocation_mem(mali_mem_allocation *mali_alloc)
47 mali_mem_backend *mem_bkend = NULL;
48 u32 free_pages_nr = 0;
50 struct mali_session_data *session = mali_alloc->session;
51 MALI_DEBUG_PRINT(4, (" _mali_free_allocation_mem, psize =0x%x! \n", mali_alloc->psize));
52 if (0 == mali_alloc->psize)
55 /* Get backend memory & Map on CPU */
56 mutex_lock(&mali_idr_mutex);
57 mem_bkend = idr_find(&mali_backend_idr, mali_alloc->backend_handle);
58 mutex_unlock(&mali_idr_mutex);
59 MALI_DEBUG_ASSERT(NULL != mem_bkend);
61 switch (mem_bkend->type) {
63 free_pages_nr = mali_mem_os_release(mem_bkend);
64 atomic_sub(free_pages_nr, &session->mali_mem_allocated_pages);
67 #if defined(CONFIG_MALI400_UMP)
68 mali_mem_unbind_ump_buf(mem_bkend);
69 atomic_sub(mem_bkend->size / MALI_MMU_PAGE_SIZE, &session->mali_mem_array[mem_bkend->type]);
71 MALI_DEBUG_PRINT(1, ("UMP not supported\n"));
74 case MALI_MEM_DMA_BUF:
75 #if defined(CONFIG_DMA_SHARED_BUFFER)
76 mali_mem_unbind_dma_buf(mem_bkend);
77 atomic_sub(mem_bkend->size / MALI_MMU_PAGE_SIZE, &session->mali_mem_array[mem_bkend->type]);
79 MALI_DEBUG_PRINT(1, ("DMA not supported\n"));
82 case MALI_MEM_EXTERNAL:
83 mali_mem_unbind_ext_buf(mem_bkend);
84 atomic_sub(mem_bkend->size / MALI_MMU_PAGE_SIZE, &session->mali_mem_array[mem_bkend->type]);
88 free_pages_nr = mali_mem_block_release(mem_bkend);
89 atomic_sub(free_pages_nr, &session->mali_mem_allocated_pages);
93 if (mem_bkend->flags & MALI_MEM_BACKEND_FLAG_SWAP_COWED) {
94 free_pages_nr = mali_mem_swap_release(mem_bkend, MALI_TRUE);
96 free_pages_nr = mali_mem_cow_release(mem_bkend, MALI_TRUE);
98 atomic_sub(free_pages_nr, &session->mali_mem_allocated_pages);
101 free_pages_nr = mali_mem_swap_release(mem_bkend, MALI_TRUE);
102 atomic_sub(free_pages_nr, &session->mali_mem_allocated_pages);
103 atomic_sub(free_pages_nr, &session->mali_mem_array[mem_bkend->type]);
105 case MALI_MEM_SECURE:
106 #if defined(CONFIG_DMA_SHARED_BUFFER)
107 free_pages_nr = mali_mem_secure_release(mem_bkend);
108 atomic_sub(free_pages_nr, &session->mali_mem_allocated_pages);
110 MALI_DEBUG_PRINT(1, ("DMA not supported for mali secure memory\n"));
114 MALI_DEBUG_PRINT(1, ("mem type %d is not in the mali_mem_type enum.\n", mem_bkend->type));
118 /*Remove backend memory idex */
119 mutex_lock(&mali_idr_mutex);
120 idr_remove(&mali_backend_idr, mali_alloc->backend_handle);
121 mutex_unlock(&mali_idr_mutex);
124 /* remove memory allocation */
125 mali_vma_offset_remove(&session->allocation_mgr, &mali_alloc->mali_vma_node);
126 mali_mem_allocation_struct_destory(mali_alloc);
127 return free_pages_nr;
131 * ref_count for allocation
133 u32 mali_allocation_unref(struct mali_mem_allocation **alloc)
135 u32 free_pages_nr = 0;
136 mali_mem_allocation *mali_alloc = *alloc;
138 if (0 == _mali_osk_atomic_dec_return(&mali_alloc->mem_alloc_refcount)) {
139 free_pages_nr = _mali_free_allocation_mem(mali_alloc);
141 return free_pages_nr;
144 void mali_allocation_ref(struct mali_mem_allocation *alloc)
146 _mali_osk_atomic_inc(&alloc->mem_alloc_refcount);
149 void mali_free_session_allocations(struct mali_session_data *session)
151 struct mali_mem_allocation *entry, *next;
153 MALI_DEBUG_PRINT(4, (" mali_free_session_allocations! \n"));
155 list_for_each_entry_safe(entry, next, &session->allocation_mgr.head, list) {
156 mali_allocation_unref(&entry);