2 * Support for Intel Camera Imaging ISP subsystem.
3 * Copyright (c) 2015, Intel Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 #include "ia_css_refcount.h"
16 #include "memory_access/memory_access.h"
17 #include "sh_css_defs.h"
19 #include "platform_support.h"
21 #include "assert_support.h"
23 #include "ia_css_debug.h"
25 /* TODO: enable for other memory aswell
26 now only for hrt_vaddress */
27 struct ia_css_refcount_entry {
33 struct ia_css_refcount_list {
35 struct ia_css_refcount_entry *items;
38 static struct ia_css_refcount_list myrefcount;
40 static struct ia_css_refcount_entry *refcount_find_entry(hrt_vaddress ptr,
47 if (!myrefcount.items) {
48 ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
49 "refcount_find_entry(): Ref count not initiliazed!\n");
53 for (i = 0; i < myrefcount.size; i++) {
54 if ((&myrefcount.items[i])->data == 0) {
57 return &myrefcount.items[i];
60 if ((&myrefcount.items[i])->data == ptr) {
62 return &myrefcount.items[i];
68 enum ia_css_err ia_css_refcount_init(uint32_t size)
70 enum ia_css_err err = IA_CSS_SUCCESS;
73 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
74 "ia_css_refcount_init(): Size of 0 for Ref count init!\n");
75 return IA_CSS_ERR_INVALID_ARGUMENTS;
77 if (myrefcount.items) {
78 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
79 "ia_css_refcount_init(): Ref count is already initialized\n");
80 return IA_CSS_ERR_INTERNAL_ERROR;
83 sh_css_malloc(sizeof(struct ia_css_refcount_entry) * size);
84 if (!myrefcount.items)
85 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
86 if (err == IA_CSS_SUCCESS) {
87 memset(myrefcount.items, 0,
88 sizeof(struct ia_css_refcount_entry) * size);
89 myrefcount.size = size;
94 void ia_css_refcount_uninit(void)
96 struct ia_css_refcount_entry *entry;
99 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
100 "ia_css_refcount_uninit() entry\n");
101 for (i = 0; i < myrefcount.size; i++) {
102 /* driver verifier tool has issues with &arr[i]
103 and prefers arr + i; as these are actually equivalent
104 the line below uses + i
106 entry = myrefcount.items + i;
107 if (entry->data != mmgr_NULL) {
108 /* ia_css_debug_dtrace(IA_CSS_DBG_TRACE,
109 "ia_css_refcount_uninit: freeing (%x)\n",
111 hmm_free(entry->data);
112 entry->data = mmgr_NULL;
117 sh_css_free(myrefcount.items);
118 myrefcount.items = NULL;
120 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
121 "ia_css_refcount_uninit() leave\n");
124 hrt_vaddress ia_css_refcount_increment(s32 id, hrt_vaddress ptr)
126 struct ia_css_refcount_entry *entry;
128 if (ptr == mmgr_NULL)
131 entry = refcount_find_entry(ptr, false);
133 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
134 "ia_css_refcount_increment(%x) 0x%x\n", id, ptr);
137 entry = refcount_find_entry(ptr, true);
144 if (entry->id != id) {
145 ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
146 "ia_css_refcount_increment(): Ref count IDS do not match!\n");
150 if (entry->data == ptr)
152 else if (entry->data == mmgr_NULL) {
161 bool ia_css_refcount_decrement(s32 id, hrt_vaddress ptr)
163 struct ia_css_refcount_entry *entry;
165 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
166 "ia_css_refcount_decrement(%x) 0x%x\n", id, ptr);
168 if (ptr == mmgr_NULL)
171 entry = refcount_find_entry(ptr, false);
174 if (entry->id != id) {
175 ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
176 "ia_css_refcount_decrement(): Ref count IDS do not match!\n");
179 if (entry->count > 0) {
181 if (entry->count == 0) {
182 /* ia_css_debug_dtrace(IA_CSS_DBEUG_TRACE,
183 "ia_css_refcount_decrement: freeing\n");*/
185 entry->data = mmgr_NULL;
192 /* SHOULD NOT HAPPEN: ptr not managed by refcount, or not
195 IA_CSS_ERROR("id %x, ptr 0x%x entry %p entry->id %x entry->count %d\n",
196 id, ptr, entry, entry->id, entry->count);
198 IA_CSS_ERROR("entry NULL\n");
204 bool ia_css_refcount_is_single(hrt_vaddress ptr)
206 struct ia_css_refcount_entry *entry;
208 if (ptr == mmgr_NULL)
211 entry = refcount_find_entry(ptr, false);
214 return (entry->count == 1);
219 void ia_css_refcount_clear(s32 id, clear_func clear_func_ptr)
221 struct ia_css_refcount_entry *entry;
225 assert(clear_func_ptr);
226 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_refcount_clear(%x)\n",
229 for (i = 0; i < myrefcount.size; i++) {
230 /* driver verifier tool has issues with &arr[i]
231 and prefers arr + i; as these are actually equivalent
232 the line below uses + i
234 entry = myrefcount.items + i;
235 if ((entry->data != mmgr_NULL) && (entry->id == id)) {
236 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
237 "ia_css_refcount_clear: %x: 0x%x\n",
239 if (clear_func_ptr) {
240 /* clear using provided function */
241 clear_func_ptr(entry->data);
243 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
244 "ia_css_refcount_clear: using hmm_free: no clear_func\n");
245 hmm_free(entry->data);
248 if (entry->count != 0) {
249 IA_CSS_WARNING("Ref count for entry %x is not zero!", entry->id);
252 assert(entry->count == 0);
254 entry->data = mmgr_NULL;
260 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
261 "ia_css_refcount_clear(%x): cleared %d\n", id,
265 bool ia_css_refcount_is_valid(hrt_vaddress ptr)
267 struct ia_css_refcount_entry *entry;
269 if (ptr == mmgr_NULL)
272 entry = refcount_find_entry(ptr, false);