diff options
Diffstat (limited to 'drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_workq.c')
-rw-r--r-- | drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_workq.c | 65 |
1 files changed, 28 insertions, 37 deletions
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_workq.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_workq.c index 966b573b5493..3798ef8e6d5f 100644 --- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_workq.c +++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_workq.c @@ -59,11 +59,11 @@ static void cam_req_mgr_workq_put_task(struct crm_workq_task *task) (struct cam_req_mgr_core_workq *)task->parent; unsigned long flags = 0; - WORKQ_ACQUIRE_LOCK(workq, flags); list_del_init(&task->entry); task->cancel = 0; task->process_cb = NULL; task->priv = NULL; + WORKQ_ACQUIRE_LOCK(workq, flags); list_add_tail(&task->entry, &workq->task.empty_head); atomic_add(1, &workq->task.free_cnt); @@ -127,28 +127,6 @@ static void cam_req_mgr_process_workq(struct work_struct *w) } } -void crm_workq_clear_q(struct cam_req_mgr_core_workq *workq) -{ - int32_t i = CRM_TASK_PRIORITY_0; - struct crm_workq_task *task, *task_save; - - CAM_DBG(CAM_CRM, "pending_cnt %d", - atomic_read(&workq->task.pending_cnt)); - - while (i < CRM_TASK_PRIORITY_MAX) { - if (!list_empty(&workq->task.process_head[i])) { - list_for_each_entry_safe(task, task_save, - &workq->task.process_head[i], entry) { - cam_req_mgr_workq_put_task(task); - CAM_WARN(CAM_CRM, "flush task %pK, %d, cnt %d", - task, i, atomic_read( - &workq->task.free_cnt)); - } - } - i++; - } -} - int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task, void *priv, int32_t prio) { @@ -167,10 +145,6 @@ int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task, rc = -EINVAL; goto end; } - if (!workq->job) { - rc = -EINVAL; - goto end; - } if (task->cancel == 1) { cam_req_mgr_workq_put_task(task); @@ -184,24 +158,30 @@ int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task, ? prio : CRM_TASK_PRIORITY_0; WORKQ_ACQUIRE_LOCK(workq, flags); + if (!workq->job) { + rc = -EINVAL; + WORKQ_RELEASE_LOCK(workq, flags); + goto end; + } + list_add_tail(&task->entry, &workq->task.process_head[task->priority]); - WORKQ_RELEASE_LOCK(workq, flags); atomic_add(1, &workq->task.pending_cnt); CAM_DBG(CAM_CRM, "enq task %pK pending_cnt %d", task, atomic_read(&workq->task.pending_cnt)); queue_work(workq->job, &workq->work); - + WORKQ_RELEASE_LOCK(workq, flags); end: return rc; } int cam_req_mgr_workq_create(char *name, int32_t num_tasks, - struct cam_req_mgr_core_workq **workq, enum crm_workq_context in_irq) + struct cam_req_mgr_core_workq **workq, enum crm_workq_context in_irq, + int flags) { - int32_t i; + int32_t i, wq_flags = 0, max_active_tasks = 0; struct crm_workq_task *task; struct cam_req_mgr_core_workq *crm_workq = NULL; char buf[128] = "crm_workq-"; @@ -213,10 +193,17 @@ int cam_req_mgr_workq_create(char *name, int32_t num_tasks, if (crm_workq == NULL) return -ENOMEM; + wq_flags |= WQ_UNBOUND; + if (flags & CAM_WORKQ_FLAG_HIGH_PRIORITY) + wq_flags |= WQ_HIGHPRI; + + if (flags & CAM_WORKQ_FLAG_SERIAL) + max_active_tasks = 1; + strlcat(buf, name, sizeof(buf)); CAM_DBG(CAM_CRM, "create workque crm_workq-%s", name); crm_workq->job = alloc_workqueue(buf, - WQ_HIGHPRI | WQ_UNBOUND, 0, NULL); + wq_flags, max_active_tasks, NULL); if (!crm_workq->job) { kfree(crm_workq); return -ENOMEM; @@ -252,8 +239,7 @@ int cam_req_mgr_workq_create(char *name, int32_t num_tasks, task = &crm_workq->task.pool[i]; task->parent = (void *)crm_workq; /* Put all tasks in free pool */ - list_add_tail(&task->entry, - &crm_workq->task.process_head[CRM_TASK_PRIORITY_0]); + INIT_LIST_HEAD(&task->entry); cam_req_mgr_workq_put_task(task); } *workq = crm_workq; @@ -266,13 +252,18 @@ int cam_req_mgr_workq_create(char *name, int32_t num_tasks, void cam_req_mgr_workq_destroy(struct cam_req_mgr_core_workq **crm_workq) { + unsigned long flags = 0; + struct workqueue_struct *job; CAM_DBG(CAM_CRM, "destroy workque %pK", crm_workq); if (*crm_workq) { - crm_workq_clear_q(*crm_workq); + WORKQ_ACQUIRE_LOCK(*crm_workq, flags); if ((*crm_workq)->job) { - destroy_workqueue((*crm_workq)->job); + job = (*crm_workq)->job; (*crm_workq)->job = NULL; - } + WORKQ_RELEASE_LOCK(*crm_workq, flags); + destroy_workqueue(job); + } else + WORKQ_RELEASE_LOCK(*crm_workq, flags); kfree((*crm_workq)->task.pool); kfree(*crm_workq); *crm_workq = NULL; |