aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/tidspbridge/rmgr/drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/tidspbridge/rmgr/drv.c')
-rw-r--r--drivers/staging/tidspbridge/rmgr/drv.c146
1 files changed, 47 insertions, 99 deletions
diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c
index c8d9d2551ff0..8a8dea6efeda 100644
--- a/drivers/staging/tidspbridge/rmgr/drv.c
+++ b/drivers/staging/tidspbridge/rmgr/drv.c
@@ -211,70 +211,40 @@ int drv_proc_insert_strm_res_element(void *stream_obj,
(struct strm_res_object **)strm_res;
struct process_context *ctxt = (struct process_context *)process_ctxt;
int status = 0;
- struct strm_res_object *temp_strm_res = NULL;
+ int retval;
*pstrm_res = kzalloc(sizeof(struct strm_res_object), GFP_KERNEL);
- if (*pstrm_res == NULL)
+ if (*pstrm_res == NULL) {
status = -EFAULT;
+ goto func_end;
+ }
- if (!status) {
- if (mutex_lock_interruptible(&ctxt->strm_mutex)) {
- kfree(*pstrm_res);
- return -EPERM;
+ (*pstrm_res)->hstream = stream_obj;
+ retval = idr_get_new(ctxt->stream_id, *pstrm_res,
+ &(*pstrm_res)->id);
+ if (retval == -EAGAIN) {
+ if (!idr_pre_get(ctxt->stream_id, GFP_KERNEL)) {
+ pr_err("%s: OUT OF MEMORY\n", __func__);
+ status = -ENOMEM;
+ goto func_end;
}
- (*pstrm_res)->hstream = stream_obj;
- if (ctxt->pstrm_list != NULL) {
- temp_strm_res = ctxt->pstrm_list;
- while (temp_strm_res->next != NULL)
- temp_strm_res = temp_strm_res->next;
- temp_strm_res->next = *pstrm_res;
- } else {
- ctxt->pstrm_list = *pstrm_res;
- }
- mutex_unlock(&ctxt->strm_mutex);
+ retval = idr_get_new(ctxt->stream_id, *pstrm_res,
+ &(*pstrm_res)->id);
}
- return status;
-}
-
-/* Release Stream resource element context
-* This function called after the actual resource is freed
- */
-int drv_proc_remove_strm_res_element(void *strm_res, void *process_ctxt)
-{
- struct strm_res_object *pstrm_res = (struct strm_res_object *)strm_res;
- struct process_context *ctxt = (struct process_context *)process_ctxt;
- struct strm_res_object *temp_strm_res;
- int status = 0;
-
- if (mutex_lock_interruptible(&ctxt->strm_mutex))
- return -EPERM;
- temp_strm_res = ctxt->pstrm_list;
-
- if (ctxt->pstrm_list == pstrm_res) {
- ctxt->pstrm_list = pstrm_res->next;
- } else {
- while (temp_strm_res && temp_strm_res->next != pstrm_res)
- temp_strm_res = temp_strm_res->next;
- if (temp_strm_res == NULL)
- status = -ENOENT;
- else
- temp_strm_res->next = pstrm_res->next;
+ if (retval) {
+ pr_err("%s: FAILED, IDR is FULL\n", __func__);
+ status = -EPERM;
}
- mutex_unlock(&ctxt->strm_mutex);
- kfree(pstrm_res);
+
+func_end:
return status;
}
-/* Release all Stream resources and its context
-* This is called from .bridge_release.
- */
-int drv_remove_all_strm_res_elements(void *process_ctxt)
+static int drv_proc_free_strm_res(int id, void *p, void *process_ctxt)
{
- struct process_context *ctxt = (struct process_context *)process_ctxt;
- int status = 0;
- struct strm_res_object *strm_res = NULL;
- struct strm_res_object *strm_tmp = NULL;
+ struct process_context *ctxt = process_ctxt;
+ struct strm_res_object *strm_res = p;
struct stream_info strm_info;
struct dsp_streaminfo user;
u8 **ap_buffer = NULL;
@@ -283,60 +253,38 @@ int drv_remove_all_strm_res_elements(void *process_ctxt)
u32 dw_arg;
s32 ul_buf_size;
- strm_tmp = ctxt->pstrm_list;
- while (strm_tmp) {
- strm_res = strm_tmp;
- strm_tmp = strm_tmp->next;
- if (strm_res->num_bufs) {
- ap_buffer = kmalloc((strm_res->num_bufs *
- sizeof(u8 *)), GFP_KERNEL);
- if (ap_buffer) {
- status = strm_free_buffer(strm_res->hstream,
- ap_buffer,
- strm_res->num_bufs,
- ctxt);
- kfree(ap_buffer);
- }
+ if (strm_res->num_bufs) {
+ ap_buffer = kmalloc((strm_res->num_bufs *
+ sizeof(u8 *)), GFP_KERNEL);
+ if (ap_buffer) {
+ strm_free_buffer(strm_res,
+ ap_buffer,
+ strm_res->num_bufs,
+ ctxt);
+ kfree(ap_buffer);
}
- strm_info.user_strm = &user;
- user.number_bufs_in_stream = 0;
- strm_get_info(strm_res->hstream, &strm_info, sizeof(strm_info));
- while (user.number_bufs_in_stream--)
- strm_reclaim(strm_res->hstream, &buf_ptr, &ul_bytes,
- (u32 *) &ul_buf_size, &dw_arg);
- status = strm_close(strm_res->hstream, ctxt);
}
- return status;
+ strm_info.user_strm = &user;
+ user.number_bufs_in_stream = 0;
+ strm_get_info(strm_res->hstream, &strm_info, sizeof(strm_info));
+ while (user.number_bufs_in_stream--)
+ strm_reclaim(strm_res->hstream, &buf_ptr, &ul_bytes,
+ (u32 *) &ul_buf_size, &dw_arg);
+ strm_close(strm_res, ctxt);
+ return 0;
}
-/* Getting the stream resource element */
-int drv_get_strm_res_element(void *stream_obj, void *strm_resources,
- void *process_ctxt)
+/* Release all Stream resources and its context
+* This is called from .bridge_release.
+ */
+int drv_remove_all_strm_res_elements(void *process_ctxt)
{
- struct strm_res_object **strm_res =
- (struct strm_res_object **)strm_resources;
- struct process_context *ctxt = (struct process_context *)process_ctxt;
- int status = 0;
- struct strm_res_object *temp_strm2 = NULL;
- struct strm_res_object *temp_strm;
-
- if (mutex_lock_interruptible(&ctxt->strm_mutex))
- return -EPERM;
-
- temp_strm = ctxt->pstrm_list;
- while ((temp_strm != NULL) && (temp_strm->hstream != stream_obj)) {
- temp_strm2 = temp_strm;
- temp_strm = temp_strm->next;
- }
-
- mutex_unlock(&ctxt->strm_mutex);
+ struct process_context *ctxt = process_ctxt;
- if (temp_strm != NULL)
- *strm_res = temp_strm;
- else
- status = -ENOENT;
+ idr_for_each(ctxt->stream_id, drv_proc_free_strm_res, ctxt);
+ idr_destroy(ctxt->stream_id);
- return status;
+ return 0;
}
/* Updating the stream resource element */