Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2c896851 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: reqmgr: Change for using workqueue from interrupt context" into msm-4.9

parents d72077c4 9f40471c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3017,7 +3017,7 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf)

	/* Create Worker for ife_hw_mgr with 10 tasks */
	rc = cam_req_mgr_workq_create("cam_ife_worker", 10,
			&g_ife_hw_mgr.workq);
			&g_ife_hw_mgr.workq, CRM_WORKQ_USAGE_NON_IRQ);

	if (rc < 0) {
		pr_err("%s: Unable to create worker\n", __func__);
+2 −1
Original line number Diff line number Diff line
@@ -1813,7 +1813,8 @@ int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info)
	/* Create worker for current link */
	snprintf(buf, sizeof(buf), "%x-%x",
		link_info->session_hdl, link->link_hdl);
	rc = cam_req_mgr_workq_create(buf, CRM_WORKQ_NUM_TASKS, &link->workq);
	rc = cam_req_mgr_workq_create(buf, CRM_WORKQ_NUM_TASKS,
		&link->workq, CRM_WORKQ_USAGE_NON_IRQ);
	if (rc < 0) {
		CRM_ERR("FATAL: unable to create worker");
		__cam_req_mgr_destroy_link_info(link);
+25 −7
Original line number Diff line number Diff line
@@ -12,16 +12,30 @@

#include "cam_req_mgr_workq.h"

#define WORKQ_ACQUIRE_LOCK(workq, flags) {\
	if ((workq)->in_irq) \
		spin_lock_irqsave(&(workq)->lock_bh, (flags)); \
	else \
		spin_lock_bh(&(workq)->lock_bh); \
}

#define WORKQ_RELEASE_LOCK(workq, flags) {\
	if ((workq)->in_irq) \
		spin_unlock_irqrestore(&(workq)->lock_bh, (flags)); \
	else	\
		spin_unlock_bh(&(workq)->lock_bh); \
}

struct crm_workq_task *cam_req_mgr_workq_get_task(
	struct cam_req_mgr_core_workq *workq)
{
	struct crm_workq_task *task = NULL;
	unsigned long flags = 0;

	if (!workq)
		return NULL;

	spin_lock_bh(&workq->lock_bh);
	WORKQ_ACQUIRE_LOCK(workq, flags);
	if (list_empty(&workq->task.empty_head))
		goto end;

@@ -33,7 +47,8 @@ struct crm_workq_task *cam_req_mgr_workq_get_task(
	}

end:
	spin_unlock_bh(&workq->lock_bh);
	WORKQ_RELEASE_LOCK(workq, flags);

	return task;
}

@@ -41,8 +56,9 @@ static void cam_req_mgr_workq_put_task(struct crm_workq_task *task)
{
	struct cam_req_mgr_core_workq *workq =
		(struct cam_req_mgr_core_workq *)task->parent;
	unsigned long flags = 0;

	spin_lock_bh(&workq->lock_bh);
	WORKQ_ACQUIRE_LOCK(workq, flags);
	list_del_init(&task->entry);
	task->cancel = 0;
	task->process_cb = NULL;
@@ -50,7 +66,7 @@ static void cam_req_mgr_workq_put_task(struct crm_workq_task *task)
	list_add_tail(&task->entry,
		&workq->task.empty_head);
	atomic_add(1, &workq->task.free_cnt);
	spin_unlock_bh(&workq->lock_bh);
	WORKQ_RELEASE_LOCK(workq, flags);
}

/**
@@ -131,6 +147,7 @@ int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task,
{
	int rc = 0;
	struct cam_req_mgr_core_workq *workq = NULL;
	unsigned long flags = 0;

	if (!task) {
		CRM_WARN("NULL task pointer can not schedule");
@@ -159,10 +176,10 @@ int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task,
		(prio < CRM_TASK_PRIORITY_MAX && prio >= CRM_TASK_PRIORITY_0)
		? prio : CRM_TASK_PRIORITY_0;

	spin_lock_bh(&workq->lock_bh);
	WORKQ_ACQUIRE_LOCK(workq, flags);
	list_add_tail(&task->entry,
		&workq->task.process_head[task->priority]);
	spin_unlock_bh(&workq->lock_bh);
	WORKQ_RELEASE_LOCK(workq, flags);

	atomic_add(1, &workq->task.pending_cnt);
	CRM_DBG("enq task %pK pending_cnt %d",
@@ -175,7 +192,7 @@ int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task,
}

int cam_req_mgr_workq_create(char *name, int32_t num_tasks,
	struct cam_req_mgr_core_workq **workq)
	struct cam_req_mgr_core_workq **workq, enum crm_workq_context in_irq)
{
	int32_t i;
	struct crm_workq_task  *task;
@@ -210,6 +227,7 @@ int cam_req_mgr_workq_create(char *name, int32_t num_tasks,
		for (i = CRM_TASK_PRIORITY_0; i < CRM_TASK_PRIORITY_MAX; i++)
			INIT_LIST_HEAD(&crm_workq->task.process_head[i]);
		INIT_LIST_HEAD(&crm_workq->task.empty_head);
		crm_workq->in_irq = in_irq;
		crm_workq->task.num_task = num_tasks;
		crm_workq->task.pool = (struct crm_workq_task *)
			kzalloc(sizeof(struct crm_workq_task) *
+16 −6
Original line number Diff line number Diff line
@@ -25,9 +25,16 @@

/* Task priorities, lower the number higher the priority*/
enum crm_task_priority {
	CRM_TASK_PRIORITY_0 = 0,
	CRM_TASK_PRIORITY_1 = 1,
	CRM_TASK_PRIORITY_MAX = 2,
	CRM_TASK_PRIORITY_0,
	CRM_TASK_PRIORITY_1,
	CRM_TASK_PRIORITY_MAX,
};

/* workqueue will be used from irq context or not */
enum crm_workq_context {
	CRM_WORKQ_USAGE_NON_IRQ,
	CRM_WORKQ_USAGE_IRQ,
	CRM_WORKQ_USAGE_INVALID,
};

/** struct crm_workq_task
@@ -58,7 +65,8 @@ struct crm_workq_task {
 * @work       : work token used by workqueue
 * @job        : workqueue internal job struct
 * task -
 * @lock       : lock for task structs
 * @lock_bh    : lock for task structs
 * @in_irq     : set true if workque can be used in irq context
 * @free_cnt   : num of free/available tasks
 * @empty_head : list  head of available taska which can be used
 *               or acquired in order to enqueue a task to workq
@@ -70,6 +78,7 @@ struct cam_req_mgr_core_workq {
	struct work_struct         work;
	struct workqueue_struct   *job;
	spinlock_t                 lock_bh;
	uint32_t                   in_irq;

	/* tasks */
	struct {
@@ -91,11 +100,12 @@ struct cam_req_mgr_core_workq {
 *             of session handle and link handle
 * @num_task : Num_tasks to be allocated for workq
 * @workq    : Double pointer worker
 * @in_irq   : Set to one if workq might be used in irq context
 * This function will allocate and create workqueue and pass
 * the workq pointer to caller.
 */
int cam_req_mgr_workq_create(char *name, int32_t num_tasks,
	struct cam_req_mgr_core_workq **workq);
	struct cam_req_mgr_core_workq **workq, enum crm_workq_context in_irq);

/**
 * cam_req_mgr_workq_destroy()
+2 −2
Original line number Diff line number Diff line
@@ -1904,14 +1904,14 @@ int cam_icp_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl)
	}

	rc = cam_req_mgr_workq_create("icp_command_queue", ICP_WORKQ_NUM_TASK,
					&icp_hw_mgr.cmd_work);
		&icp_hw_mgr.cmd_work, CRM_WORKQ_USAGE_NON_IRQ);
	if (rc < 0) {
		pr_err("unable to create a worker\n");
		goto cmd_work_failed;
	}

	rc = cam_req_mgr_workq_create("icp_message_queue", ICP_WORKQ_NUM_TASK,
					&icp_hw_mgr.msg_work);
		&icp_hw_mgr.msg_work, CRM_WORKQ_USAGE_IRQ);
	if (rc < 0) {
		pr_err("unable to create a worker\n");
		goto msg_work_failed;