1f5fbb83fSMauro Carvalho Chehab // SPDX-License-Identifier: GPL-2.0
29d4fa1a1SMauro Carvalho Chehab /*
39d4fa1a1SMauro Carvalho Chehab  * Support for Intel Camera Imaging ISP subsystem.
49d4fa1a1SMauro Carvalho Chehab  * Copyright (c) 2010-2015, Intel Corporation.
59d4fa1a1SMauro Carvalho Chehab  *
69d4fa1a1SMauro Carvalho Chehab  * This program is free software; you can redistribute it and/or modify it
79d4fa1a1SMauro Carvalho Chehab  * under the terms and conditions of the GNU General Public License,
89d4fa1a1SMauro Carvalho Chehab  * version 2, as published by the Free Software Foundation.
99d4fa1a1SMauro Carvalho Chehab  *
109d4fa1a1SMauro Carvalho Chehab  * This program is distributed in the hope it will be useful, but WITHOUT
119d4fa1a1SMauro Carvalho Chehab  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
129d4fa1a1SMauro Carvalho Chehab  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
139d4fa1a1SMauro Carvalho Chehab  * more details.
149d4fa1a1SMauro Carvalho Chehab  */
159d4fa1a1SMauro Carvalho Chehab 
1608fef4faSMauro Carvalho Chehab #include "hmm.h"
179d4fa1a1SMauro Carvalho Chehab #include "ia_css_rmgr.h"
189d4fa1a1SMauro Carvalho Chehab 
199d4fa1a1SMauro Carvalho Chehab #include <type_support.h>
209d4fa1a1SMauro Carvalho Chehab #include <assert_support.h>
219d4fa1a1SMauro Carvalho Chehab #include <platform_support.h> /* memset */
229d4fa1a1SMauro Carvalho Chehab #include <ia_css_debug.h>
239d4fa1a1SMauro Carvalho Chehab 
249d4fa1a1SMauro Carvalho Chehab /*
259d4fa1a1SMauro Carvalho Chehab  * @brief VBUF resource handles
269d4fa1a1SMauro Carvalho Chehab  */
279d4fa1a1SMauro Carvalho Chehab #define NUM_HANDLES 1000
289d4fa1a1SMauro Carvalho Chehab static struct ia_css_rmgr_vbuf_handle handle_table[NUM_HANDLES];
299d4fa1a1SMauro Carvalho Chehab 
309d4fa1a1SMauro Carvalho Chehab /*
319d4fa1a1SMauro Carvalho Chehab  * @brief VBUF resource pool - refpool
329d4fa1a1SMauro Carvalho Chehab  */
338776682cSPhilipp Gerlesberger static struct ia_css_rmgr_vbuf_pool refpool;
349d4fa1a1SMauro Carvalho Chehab 
359d4fa1a1SMauro Carvalho Chehab /*
369d4fa1a1SMauro Carvalho Chehab  * @brief VBUF resource pool - writepool
379d4fa1a1SMauro Carvalho Chehab  */
389d4fa1a1SMauro Carvalho Chehab static struct ia_css_rmgr_vbuf_pool writepool = {
398776682cSPhilipp Gerlesberger 	.copy_on_write	= true,
409d4fa1a1SMauro Carvalho Chehab };
419d4fa1a1SMauro Carvalho Chehab 
429d4fa1a1SMauro Carvalho Chehab /*
439d4fa1a1SMauro Carvalho Chehab  * @brief VBUF resource pool - hmmbufferpool
449d4fa1a1SMauro Carvalho Chehab  */
459d4fa1a1SMauro Carvalho Chehab static struct ia_css_rmgr_vbuf_pool hmmbufferpool = {
468776682cSPhilipp Gerlesberger 	.copy_on_write	= true,
478776682cSPhilipp Gerlesberger 	.recycle	= true,
488776682cSPhilipp Gerlesberger 	.size		= 32,
499d4fa1a1SMauro Carvalho Chehab };
509d4fa1a1SMauro Carvalho Chehab 
519d4fa1a1SMauro Carvalho Chehab struct ia_css_rmgr_vbuf_pool *vbuf_ref = &refpool;
529d4fa1a1SMauro Carvalho Chehab struct ia_css_rmgr_vbuf_pool *vbuf_write = &writepool;
539d4fa1a1SMauro Carvalho Chehab struct ia_css_rmgr_vbuf_pool *hmm_buffer_pool = &hmmbufferpool;
549d4fa1a1SMauro Carvalho Chehab 
559d4fa1a1SMauro Carvalho Chehab /*
569d4fa1a1SMauro Carvalho Chehab  * @brief Initialize the reference count (host, vbuf)
579d4fa1a1SMauro Carvalho Chehab  */
rmgr_refcount_init_vbuf(void)589d4fa1a1SMauro Carvalho Chehab static void rmgr_refcount_init_vbuf(void)
599d4fa1a1SMauro Carvalho Chehab {
609d4fa1a1SMauro Carvalho Chehab 	/* initialize the refcount table */
619d4fa1a1SMauro Carvalho Chehab 	memset(&handle_table, 0, sizeof(handle_table));
629d4fa1a1SMauro Carvalho Chehab }
639d4fa1a1SMauro Carvalho Chehab 
649d4fa1a1SMauro Carvalho Chehab /*
659d4fa1a1SMauro Carvalho Chehab  * @brief Retain the reference count for a handle (host, vbuf)
669d4fa1a1SMauro Carvalho Chehab  *
679d4fa1a1SMauro Carvalho Chehab  * @param handle	The pointer to the handle
689d4fa1a1SMauro Carvalho Chehab  */
ia_css_rmgr_refcount_retain_vbuf(struct ia_css_rmgr_vbuf_handle ** handle)699d4fa1a1SMauro Carvalho Chehab void ia_css_rmgr_refcount_retain_vbuf(struct ia_css_rmgr_vbuf_handle **handle)
709d4fa1a1SMauro Carvalho Chehab {
719d4fa1a1SMauro Carvalho Chehab 	int i;
729d4fa1a1SMauro Carvalho Chehab 	struct ia_css_rmgr_vbuf_handle *h;
739d4fa1a1SMauro Carvalho Chehab 
749d4fa1a1SMauro Carvalho Chehab 	if ((!handle) || (!*handle)) {
759d4fa1a1SMauro Carvalho Chehab 		IA_CSS_LOG("Invalid inputs");
769d4fa1a1SMauro Carvalho Chehab 		return;
779d4fa1a1SMauro Carvalho Chehab 	}
789d4fa1a1SMauro Carvalho Chehab 	/* new vbuf to count on */
799d4fa1a1SMauro Carvalho Chehab 	if ((*handle)->count == 0) {
809d4fa1a1SMauro Carvalho Chehab 		h = *handle;
819d4fa1a1SMauro Carvalho Chehab 		*handle = NULL;
829d4fa1a1SMauro Carvalho Chehab 		for (i = 0; i < NUM_HANDLES; i++) {
839d4fa1a1SMauro Carvalho Chehab 			if (handle_table[i].count == 0) {
849d4fa1a1SMauro Carvalho Chehab 				*handle = &handle_table[i];
859d4fa1a1SMauro Carvalho Chehab 				break;
869d4fa1a1SMauro Carvalho Chehab 			}
879d4fa1a1SMauro Carvalho Chehab 		}
889d4fa1a1SMauro Carvalho Chehab 		/* if the loop dus not break and *handle == NULL
89d0f749f6SPhilipp Gerlesberger 		 * this is an error handle and report it.
909d4fa1a1SMauro Carvalho Chehab 		 */
919d4fa1a1SMauro Carvalho Chehab 		if (!*handle) {
929d4fa1a1SMauro Carvalho Chehab 			ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
939d4fa1a1SMauro Carvalho Chehab 					    "ia_css_i_host_refcount_retain_vbuf() failed to find empty slot!\n");
949d4fa1a1SMauro Carvalho Chehab 			return;
959d4fa1a1SMauro Carvalho Chehab 		}
969d4fa1a1SMauro Carvalho Chehab 		(*handle)->vptr = h->vptr;
979d4fa1a1SMauro Carvalho Chehab 		(*handle)->size = h->size;
989d4fa1a1SMauro Carvalho Chehab 	}
999d4fa1a1SMauro Carvalho Chehab 	(*handle)->count++;
1009d4fa1a1SMauro Carvalho Chehab }
1019d4fa1a1SMauro Carvalho Chehab 
1029d4fa1a1SMauro Carvalho Chehab /*
1039d4fa1a1SMauro Carvalho Chehab  * @brief Release the reference count for a handle (host, vbuf)
1049d4fa1a1SMauro Carvalho Chehab  *
1059d4fa1a1SMauro Carvalho Chehab  * @param handle	The pointer to the handle
1069d4fa1a1SMauro Carvalho Chehab  */
ia_css_rmgr_refcount_release_vbuf(struct ia_css_rmgr_vbuf_handle ** handle)1079d4fa1a1SMauro Carvalho Chehab void ia_css_rmgr_refcount_release_vbuf(struct ia_css_rmgr_vbuf_handle **handle)
1089d4fa1a1SMauro Carvalho Chehab {
1099d4fa1a1SMauro Carvalho Chehab 	if ((!handle) || ((*handle) == NULL) || (((*handle)->count) == 0)) {
110673d128aSPhilipp Gerlesberger 		ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, "%s invalid arguments!\n", __func__);
1119d4fa1a1SMauro Carvalho Chehab 		return;
1129d4fa1a1SMauro Carvalho Chehab 	}
1139d4fa1a1SMauro Carvalho Chehab 	/* decrease reference count */
1149d4fa1a1SMauro Carvalho Chehab 	(*handle)->count--;
1159d4fa1a1SMauro Carvalho Chehab 	/* remove from admin */
1169d4fa1a1SMauro Carvalho Chehab 	if ((*handle)->count == 0) {
1179d4fa1a1SMauro Carvalho Chehab 		(*handle)->vptr = 0x0;
1189d4fa1a1SMauro Carvalho Chehab 		(*handle)->size = 0;
1199d4fa1a1SMauro Carvalho Chehab 		*handle = NULL;
1209d4fa1a1SMauro Carvalho Chehab 	}
1219d4fa1a1SMauro Carvalho Chehab }
1229d4fa1a1SMauro Carvalho Chehab 
1239d4fa1a1SMauro Carvalho Chehab /*
1249d4fa1a1SMauro Carvalho Chehab  * @brief Initialize the resource pool (host, vbuf)
1259d4fa1a1SMauro Carvalho Chehab  *
1269d4fa1a1SMauro Carvalho Chehab  * @param pool	The pointer to the pool
1279d4fa1a1SMauro Carvalho Chehab  */
ia_css_rmgr_init_vbuf(struct ia_css_rmgr_vbuf_pool * pool)12841022d35SMauro Carvalho Chehab int ia_css_rmgr_init_vbuf(struct ia_css_rmgr_vbuf_pool *pool)
1299d4fa1a1SMauro Carvalho Chehab {
13041022d35SMauro Carvalho Chehab 	int err = 0;
1319d4fa1a1SMauro Carvalho Chehab 	size_t bytes_needed;
1329d4fa1a1SMauro Carvalho Chehab 
1339d4fa1a1SMauro Carvalho Chehab 	rmgr_refcount_init_vbuf();
1349d4fa1a1SMauro Carvalho Chehab 	assert(pool);
1359d4fa1a1SMauro Carvalho Chehab 	if (!pool)
13641022d35SMauro Carvalho Chehab 		return -EINVAL;
1379d4fa1a1SMauro Carvalho Chehab 	/* initialize the recycle pool if used */
1389d4fa1a1SMauro Carvalho Chehab 	if (pool->recycle && pool->size) {
1399d4fa1a1SMauro Carvalho Chehab 		/* allocate memory for storing the handles */
1409d4fa1a1SMauro Carvalho Chehab 		bytes_needed =
1419d4fa1a1SMauro Carvalho Chehab 		    sizeof(void *) *
1429d4fa1a1SMauro Carvalho Chehab 		    pool->size;
1439955d906SMauro Carvalho Chehab 		pool->handles = kvmalloc(bytes_needed, GFP_KERNEL);
1449d4fa1a1SMauro Carvalho Chehab 		if (pool->handles)
1459d4fa1a1SMauro Carvalho Chehab 			memset(pool->handles, 0, bytes_needed);
1469d4fa1a1SMauro Carvalho Chehab 		else
14741022d35SMauro Carvalho Chehab 			err = -ENOMEM;
1489d4fa1a1SMauro Carvalho Chehab 	} else {
1499d4fa1a1SMauro Carvalho Chehab 		/* just in case, set the size to 0 */
1509d4fa1a1SMauro Carvalho Chehab 		pool->size = 0;
1519d4fa1a1SMauro Carvalho Chehab 		pool->handles = NULL;
1529d4fa1a1SMauro Carvalho Chehab 	}
1539d4fa1a1SMauro Carvalho Chehab 	return err;
1549d4fa1a1SMauro Carvalho Chehab }
1559d4fa1a1SMauro Carvalho Chehab 
1569d4fa1a1SMauro Carvalho Chehab /*
1579d4fa1a1SMauro Carvalho Chehab  * @brief Uninitialize the resource pool (host, vbuf)
1589d4fa1a1SMauro Carvalho Chehab  *
1599d4fa1a1SMauro Carvalho Chehab  * @param pool	The pointer to the pool
1609d4fa1a1SMauro Carvalho Chehab  */
ia_css_rmgr_uninit_vbuf(struct ia_css_rmgr_vbuf_pool * pool)1619d4fa1a1SMauro Carvalho Chehab void ia_css_rmgr_uninit_vbuf(struct ia_css_rmgr_vbuf_pool *pool)
1629d4fa1a1SMauro Carvalho Chehab {
1639d4fa1a1SMauro Carvalho Chehab 	u32 i;
1649d4fa1a1SMauro Carvalho Chehab 
165673d128aSPhilipp Gerlesberger 	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "%s\n", __func__);
1669d4fa1a1SMauro Carvalho Chehab 	if (!pool) {
167673d128aSPhilipp Gerlesberger 		ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, "%s NULL argument\n", __func__);
1689d4fa1a1SMauro Carvalho Chehab 		return;
1699d4fa1a1SMauro Carvalho Chehab 	}
1709d4fa1a1SMauro Carvalho Chehab 	if (pool->handles) {
1719d4fa1a1SMauro Carvalho Chehab 		/* free the hmm buffers */
1729d4fa1a1SMauro Carvalho Chehab 		for (i = 0; i < pool->size; i++) {
1739d4fa1a1SMauro Carvalho Chehab 			if (pool->handles[i]) {
1749d4fa1a1SMauro Carvalho Chehab 				ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1759d4fa1a1SMauro Carvalho Chehab 						    "   freeing/releasing %x (count=%d)\n",
1769d4fa1a1SMauro Carvalho Chehab 						    pool->handles[i]->vptr,
1779d4fa1a1SMauro Carvalho Chehab 						    pool->handles[i]->count);
1789d4fa1a1SMauro Carvalho Chehab 				/* free memory */
1799d4fa1a1SMauro Carvalho Chehab 				hmm_free(pool->handles[i]->vptr);
1809d4fa1a1SMauro Carvalho Chehab 				/* remove from refcount admin */
1816cef8028SPhilipp Gerlesberger 				ia_css_rmgr_refcount_release_vbuf(&pool->handles[i]);
1829d4fa1a1SMauro Carvalho Chehab 			}
1839d4fa1a1SMauro Carvalho Chehab 		}
1849d4fa1a1SMauro Carvalho Chehab 		/* now free the pool handles list */
1859955d906SMauro Carvalho Chehab 		kvfree(pool->handles);
1869d4fa1a1SMauro Carvalho Chehab 		pool->handles = NULL;
1879d4fa1a1SMauro Carvalho Chehab 	}
1889d4fa1a1SMauro Carvalho Chehab }
1899d4fa1a1SMauro Carvalho Chehab 
1909d4fa1a1SMauro Carvalho Chehab /*
1919d4fa1a1SMauro Carvalho Chehab  * @brief Push a handle to the pool
1929d4fa1a1SMauro Carvalho Chehab  *
1939d4fa1a1SMauro Carvalho Chehab  * @param pool		The pointer to the pool
1949d4fa1a1SMauro Carvalho Chehab  * @param handle	The pointer to the handle
1959d4fa1a1SMauro Carvalho Chehab  */
1969d4fa1a1SMauro Carvalho Chehab static
rmgr_push_handle(struct ia_css_rmgr_vbuf_pool * pool,struct ia_css_rmgr_vbuf_handle ** handle)1979d4fa1a1SMauro Carvalho Chehab void rmgr_push_handle(struct ia_css_rmgr_vbuf_pool *pool,
1989d4fa1a1SMauro Carvalho Chehab 		      struct ia_css_rmgr_vbuf_handle **handle)
1999d4fa1a1SMauro Carvalho Chehab {
2009d4fa1a1SMauro Carvalho Chehab 	u32 i;
2019d4fa1a1SMauro Carvalho Chehab 	bool succes = false;
2029d4fa1a1SMauro Carvalho Chehab 
2039d4fa1a1SMauro Carvalho Chehab 	assert(pool);
2049d4fa1a1SMauro Carvalho Chehab 	assert(pool->recycle);
2059d4fa1a1SMauro Carvalho Chehab 	assert(pool->handles);
2069d4fa1a1SMauro Carvalho Chehab 	assert(handle);
2079d4fa1a1SMauro Carvalho Chehab 	for (i = 0; i < pool->size; i++) {
2089d4fa1a1SMauro Carvalho Chehab 		if (!pool->handles[i]) {
2099d4fa1a1SMauro Carvalho Chehab 			ia_css_rmgr_refcount_retain_vbuf(handle);
2109d4fa1a1SMauro Carvalho Chehab 			pool->handles[i] = *handle;
2119d4fa1a1SMauro Carvalho Chehab 			succes = true;
2129d4fa1a1SMauro Carvalho Chehab 			break;
2139d4fa1a1SMauro Carvalho Chehab 		}
2149d4fa1a1SMauro Carvalho Chehab 	}
2159d4fa1a1SMauro Carvalho Chehab 	assert(succes);
2169d4fa1a1SMauro Carvalho Chehab }
2179d4fa1a1SMauro Carvalho Chehab 
2189d4fa1a1SMauro Carvalho Chehab /*
2199d4fa1a1SMauro Carvalho Chehab  * @brief Pop a handle from the pool
2209d4fa1a1SMauro Carvalho Chehab  *
2219d4fa1a1SMauro Carvalho Chehab  * @param pool		The pointer to the pool
2229d4fa1a1SMauro Carvalho Chehab  * @param handle	The pointer to the handle
2239d4fa1a1SMauro Carvalho Chehab  */
2249d4fa1a1SMauro Carvalho Chehab static
rmgr_pop_handle(struct ia_css_rmgr_vbuf_pool * pool,struct ia_css_rmgr_vbuf_handle ** handle)2259d4fa1a1SMauro Carvalho Chehab void rmgr_pop_handle(struct ia_css_rmgr_vbuf_pool *pool,
2269d4fa1a1SMauro Carvalho Chehab 		     struct ia_css_rmgr_vbuf_handle **handle)
2279d4fa1a1SMauro Carvalho Chehab {
2289d4fa1a1SMauro Carvalho Chehab 	u32 i;
2299d4fa1a1SMauro Carvalho Chehab 
2309d4fa1a1SMauro Carvalho Chehab 	assert(pool);
2319d4fa1a1SMauro Carvalho Chehab 	assert(pool->recycle);
2329d4fa1a1SMauro Carvalho Chehab 	assert(pool->handles);
2339d4fa1a1SMauro Carvalho Chehab 	assert(handle);
2349d4fa1a1SMauro Carvalho Chehab 	assert(*handle);
2359d4fa1a1SMauro Carvalho Chehab 	for (i = 0; i < pool->size; i++) {
2369d4fa1a1SMauro Carvalho Chehab 		if ((pool->handles[i]) &&
2379d4fa1a1SMauro Carvalho Chehab 		    (pool->handles[i]->size == (*handle)->size)) {
2389d4fa1a1SMauro Carvalho Chehab 			*handle = pool->handles[i];
2399d4fa1a1SMauro Carvalho Chehab 			pool->handles[i] = NULL;
2409d4fa1a1SMauro Carvalho Chehab 			/* dont release, we are returning it...
241d0f749f6SPhilipp Gerlesberger 			 * ia_css_rmgr_refcount_release_vbuf(handle);
242d0f749f6SPhilipp Gerlesberger 			 */
243852a53a0SMauro Carvalho Chehab 			return;
2449d4fa1a1SMauro Carvalho Chehab 		}
2459d4fa1a1SMauro Carvalho Chehab 	}
2469d4fa1a1SMauro Carvalho Chehab }
2479d4fa1a1SMauro Carvalho Chehab 
2489d4fa1a1SMauro Carvalho Chehab /*
2499d4fa1a1SMauro Carvalho Chehab  * @brief Acquire a handle from the pool (host, vbuf)
2509d4fa1a1SMauro Carvalho Chehab  *
2519d4fa1a1SMauro Carvalho Chehab  * @param pool		The pointer to the pool
2529d4fa1a1SMauro Carvalho Chehab  * @param handle	The pointer to the handle
2539d4fa1a1SMauro Carvalho Chehab  */
ia_css_rmgr_acq_vbuf(struct ia_css_rmgr_vbuf_pool * pool,struct ia_css_rmgr_vbuf_handle ** handle)2549d4fa1a1SMauro Carvalho Chehab void ia_css_rmgr_acq_vbuf(struct ia_css_rmgr_vbuf_pool *pool,
2559d4fa1a1SMauro Carvalho Chehab 			  struct ia_css_rmgr_vbuf_handle **handle)
2569d4fa1a1SMauro Carvalho Chehab {
2579d4fa1a1SMauro Carvalho Chehab 	if ((!pool) || (!handle) || (!*handle)) {
2589d4fa1a1SMauro Carvalho Chehab 		IA_CSS_LOG("Invalid inputs");
2599d4fa1a1SMauro Carvalho Chehab 		return;
2609d4fa1a1SMauro Carvalho Chehab 	}
2619d4fa1a1SMauro Carvalho Chehab 
2629d4fa1a1SMauro Carvalho Chehab 	if (pool->copy_on_write) {
263*1713dcebSHans de Goede 		struct ia_css_rmgr_vbuf_handle *new_handle;
264*1713dcebSHans de Goede 		struct ia_css_rmgr_vbuf_handle h = { 0 };
265*1713dcebSHans de Goede 
2669d4fa1a1SMauro Carvalho Chehab 		/* only one reference, reuse (no new retain) */
2679d4fa1a1SMauro Carvalho Chehab 		if ((*handle)->count == 1)
2689d4fa1a1SMauro Carvalho Chehab 			return;
2699d4fa1a1SMauro Carvalho Chehab 		/* more than one reference, release current buffer */
2709d4fa1a1SMauro Carvalho Chehab 		if ((*handle)->count > 1) {
2719d4fa1a1SMauro Carvalho Chehab 			/* store current values */
2729d4fa1a1SMauro Carvalho Chehab 			h.vptr = 0x0;
2739d4fa1a1SMauro Carvalho Chehab 			h.size = (*handle)->size;
2749d4fa1a1SMauro Carvalho Chehab 			/* release ref to current buffer */
2759d4fa1a1SMauro Carvalho Chehab 			ia_css_rmgr_refcount_release_vbuf(handle);
276*1713dcebSHans de Goede 			new_handle = &h;
277*1713dcebSHans de Goede 		} else {
278*1713dcebSHans de Goede 			new_handle = *handle;
2799d4fa1a1SMauro Carvalho Chehab 		}
2809d4fa1a1SMauro Carvalho Chehab 		/* get new buffer for needed size */
281*1713dcebSHans de Goede 		if (new_handle->vptr == 0x0) {
2829d4fa1a1SMauro Carvalho Chehab 			if (pool->recycle) {
2839d4fa1a1SMauro Carvalho Chehab 				/* try and pop from pool */
284*1713dcebSHans de Goede 				rmgr_pop_handle(pool, &new_handle);
2859d4fa1a1SMauro Carvalho Chehab 			}
286*1713dcebSHans de Goede 			if (new_handle->vptr == 0x0) {
2879d4fa1a1SMauro Carvalho Chehab 				/* we need to allocate */
288*1713dcebSHans de Goede 				new_handle->vptr = hmm_alloc(new_handle->size);
2899d4fa1a1SMauro Carvalho Chehab 			} else {
2909d4fa1a1SMauro Carvalho Chehab 				/* we popped a buffer */
291*1713dcebSHans de Goede 				*handle = new_handle;
2929d4fa1a1SMauro Carvalho Chehab 				return;
2939d4fa1a1SMauro Carvalho Chehab 			}
2949d4fa1a1SMauro Carvalho Chehab 		}
295*1713dcebSHans de Goede 		/* Note that new_handle will change to an internally maintained one */
296*1713dcebSHans de Goede 		ia_css_rmgr_refcount_retain_vbuf(&new_handle);
297*1713dcebSHans de Goede 		*handle = new_handle;
298*1713dcebSHans de Goede 		return;
2999d4fa1a1SMauro Carvalho Chehab 	}
3009d4fa1a1SMauro Carvalho Chehab 	/* Note that handle will change to an internally maintained one */
3019d4fa1a1SMauro Carvalho Chehab 	ia_css_rmgr_refcount_retain_vbuf(handle);
3029d4fa1a1SMauro Carvalho Chehab }
3039d4fa1a1SMauro Carvalho Chehab 
3049d4fa1a1SMauro Carvalho Chehab /*
3059d4fa1a1SMauro Carvalho Chehab  * @brief Release a handle to the pool (host, vbuf)
3069d4fa1a1SMauro Carvalho Chehab  *
3079d4fa1a1SMauro Carvalho Chehab  * @param pool		The pointer to the pool
3089d4fa1a1SMauro Carvalho Chehab  * @param handle	The pointer to the handle
3099d4fa1a1SMauro Carvalho Chehab  */
ia_css_rmgr_rel_vbuf(struct ia_css_rmgr_vbuf_pool * pool,struct ia_css_rmgr_vbuf_handle ** handle)3109d4fa1a1SMauro Carvalho Chehab void ia_css_rmgr_rel_vbuf(struct ia_css_rmgr_vbuf_pool *pool,
3119d4fa1a1SMauro Carvalho Chehab 			  struct ia_css_rmgr_vbuf_handle **handle)
3129d4fa1a1SMauro Carvalho Chehab {
3139d4fa1a1SMauro Carvalho Chehab 	if ((!pool) || (!handle) || (!*handle)) {
3149d4fa1a1SMauro Carvalho Chehab 		IA_CSS_LOG("Invalid inputs");
3159d4fa1a1SMauro Carvalho Chehab 		return;
3169d4fa1a1SMauro Carvalho Chehab 	}
3179d4fa1a1SMauro Carvalho Chehab 	/* release the handle */
3189d4fa1a1SMauro Carvalho Chehab 	if ((*handle)->count == 1) {
3199d4fa1a1SMauro Carvalho Chehab 		if (!pool->recycle) {
3209d4fa1a1SMauro Carvalho Chehab 			/* non recycling pool, free mem */
3219d4fa1a1SMauro Carvalho Chehab 			hmm_free((*handle)->vptr);
3229d4fa1a1SMauro Carvalho Chehab 		} else {
3239d4fa1a1SMauro Carvalho Chehab 			/* recycle to pool */
3249d4fa1a1SMauro Carvalho Chehab 			rmgr_push_handle(pool, handle);
3259d4fa1a1SMauro Carvalho Chehab 		}
3269d4fa1a1SMauro Carvalho Chehab 	}
3279d4fa1a1SMauro Carvalho Chehab 	ia_css_rmgr_refcount_release_vbuf(handle);
3289d4fa1a1SMauro Carvalho Chehab 	*handle = NULL;
3299d4fa1a1SMauro Carvalho Chehab }
330