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 == NULL) {
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++) {
55 if ((&myrefcount.items[i])->data == 0) {
58 return &myrefcount.items[i];
61 if ((&myrefcount.items[i])->data == ptr) {
63 return &myrefcount.items[i];
69 enum ia_css_err ia_css_refcount_init(uint32_t size)
71 enum ia_css_err err = IA_CSS_SUCCESS;
74 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
75 "ia_css_refcount_init(): Size of 0 for Ref count init!\n");
76 return IA_CSS_ERR_INVALID_ARGUMENTS;
78 if (myrefcount.items != NULL) {
79 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
80 "ia_css_refcount_init(): Ref count is already initialized\n");
81 return IA_CSS_ERR_INTERNAL_ERROR;
84 sh_css_malloc(sizeof(struct ia_css_refcount_entry) * size);
85 if (!myrefcount.items)
86 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
87 if (err == IA_CSS_SUCCESS) {
88 memset(myrefcount.items, 0,
89 sizeof(struct ia_css_refcount_entry) * size);
90 myrefcount.size = size;
95 void ia_css_refcount_uninit(void)
97 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(int32_t 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);
138 assert(entry != NULL);
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(int32_t 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");
206 bool ia_css_refcount_is_single(hrt_vaddress ptr)
208 struct ia_css_refcount_entry *entry;
210 if (ptr == mmgr_NULL)
213 entry = refcount_find_entry(ptr, false);
216 return (entry->count == 1);
221 void ia_css_refcount_clear(int32_t id, clear_func clear_func_ptr)
223 struct ia_css_refcount_entry *entry;
227 assert(clear_func_ptr != NULL);
228 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_refcount_clear(%x)\n",
231 for (i = 0; i < myrefcount.size; i++) {
232 /* driver verifier tool has issues with &arr[i]
233 and prefers arr + i; as these are actually equivalent
234 the line below uses + i
236 entry = myrefcount.items + i;
237 if ((entry->data != mmgr_NULL) && (entry->id == id)) {
238 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
239 "ia_css_refcount_clear:"
240 " %x: 0x%x\n", id, entry->data);
241 if (clear_func_ptr) {
242 /* clear using provided function */
243 clear_func_ptr(entry->data);
245 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
246 "ia_css_refcount_clear: "
249 hmm_free(entry->data);
254 assert(entry->count == 0);
256 if (entry->count != 0) {
257 IA_CSS_WARNING("Ref count for entry %x is not zero!", entry->id);
259 entry->data = mmgr_NULL;
265 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
266 "ia_css_refcount_clear(%x): cleared %d\n", id,
270 bool ia_css_refcount_is_valid(hrt_vaddress ptr)
272 struct ia_css_refcount_entry *entry;
274 if (ptr == mmgr_NULL)
277 entry = refcount_find_entry(ptr, false);
279 return entry != NULL;