aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_workq.c
diff options
context:
space:
mode:
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.c65
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;