From 6a3ea1ba7add2342c4889f28f3049ff90cd5d732 Mon Sep 17 00:00:00 2001 From: Herman Chen Date: Tue, 3 Aug 2021 19:52:05 +0800 Subject: [PATCH] video: rockchip: mpp: Add process/wait/worker Add new function pointer for process task, wait task result and task worker thread. Signed-off-by: Herman Chen Change-Id: Ib0b23c90083b9acab6a8eec8db0871304dbb72ca --- drivers/video/rockchip/mpp/mpp_common.c | 106 +++++++++++++++++------- drivers/video/rockchip/mpp/mpp_common.h | 33 +++++++- 2 files changed, 106 insertions(+), 33 deletions(-) diff --git a/drivers/video/rockchip/mpp/mpp_common.c b/drivers/video/rockchip/mpp/mpp_common.c index 9114241ae455..343e71a0442e 100644 --- a/drivers/video/rockchip/mpp/mpp_common.c +++ b/drivers/video/rockchip/mpp/mpp_common.c @@ -8,6 +8,9 @@ * Ding Wei, leo.ding@rock-chips.com * */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -274,15 +277,8 @@ static struct mpp_session *mpp_session_init(void) return session; } -int mpp_session_deinit(struct mpp_session *session) +static void mpp_session_deinit_default(struct mpp_session *session) { - u32 task_count = atomic_read(&session->task_count); - - mpp_dbg_session("session %p:%d task %d release\n", - session, session->index, task_count); - if (task_count) - return -1; - if (session->mpp) { struct mpp_dev *mpp = session->mpp; @@ -308,6 +304,21 @@ int mpp_session_deinit(struct mpp_session *session) } list_del_init(&session->session_link); +} + +int mpp_session_deinit(struct mpp_session *session) +{ + u32 task_count = atomic_read(&session->task_count); + + mpp_dbg_session("session %p:%d task %d release\n", + session, session->index, task_count); + if (task_count) + return -1; + + if (likely(session->deinit)) + session->deinit(session); + else + pr_err("invalid NULL session deinit function\n"); mpp_dbg_session("session %p:%d deinit\n", session, session->index); @@ -473,14 +484,14 @@ static void mpp_task_timeout_work(struct work_struct *work_s) mpp_taskqueue_pop_running(mpp->queue, task); } -static int mpp_process_task(struct mpp_session *session, - struct mpp_task_msgs *msgs) +static int mpp_process_task_default(struct mpp_session *session, + struct mpp_task_msgs *msgs) { struct mpp_task *task = NULL; struct mpp_dev *mpp = session->mpp; - if (!mpp) { - mpp_err("pid %d not find clinet %d\n", + if (unlikely(!mpp)) { + mpp_err("pid %d clinet %d found invalid process function\n", session->pid, session->device_type); return -EINVAL; } @@ -518,6 +529,16 @@ static int mpp_process_task(struct mpp_session *session, return 0; } +static int mpp_process_task(struct mpp_session *session, + struct mpp_task_msgs *msgs) +{ + if (likely(session->process_task)) + return session->process_task(session, msgs); + + pr_err("invalid NULL process task function\n"); + return -EINVAL; +} + struct reset_control * mpp_reset_control_get(struct mpp_dev *mpp, enum MPP_RESET_TYPE type, const char *name) { @@ -728,15 +749,15 @@ done: } } -static int mpp_wait_result(struct mpp_session *session, - struct mpp_task_msgs *msgs) +static int mpp_wait_result_default(struct mpp_session *session, + struct mpp_task_msgs *msgs) { int ret; struct mpp_task *task; struct mpp_dev *mpp = session->mpp; - if (!mpp) { - mpp_err("pid %d not find clinet %d\n", + if (unlikely(!mpp)) { + mpp_err("pid %d clinet %d found invalid wait result function\n", session->pid, session->device_type); return -EINVAL; } @@ -791,7 +812,7 @@ static int mpp_wait_result(struct mpp_session *session, task, task->task_index); ret = -ETIMEDOUT; } else { - return mpp_wait_result(session, msgs); + return mpp_wait_result_default(session, msgs); } } @@ -802,6 +823,16 @@ static int mpp_wait_result(struct mpp_session *session, return ret; } +static int mpp_wait_result(struct mpp_session *session, + struct mpp_task_msgs *msgs) +{ + if (likely(session->wait_result)) + return session->wait_result(session, msgs); + + pr_err("invalid NULL wait result function\n"); + return -EINVAL; +} + static int mpp_attach_service(struct mpp_dev *mpp, struct device *dev) { u32 taskqueue_node = 0; @@ -1078,8 +1109,20 @@ static int mpp_process_request(struct mpp_session *session, session->device_type = (enum MPP_DEVICE_TYPE)client_type; session->dma = mpp_dma_session_create(mpp->dev, mpp->session_max_buffers); session->mpp = mpp; + if (mpp->dev_ops) { + if (mpp->dev_ops->process_task) + session->process_task = + mpp->dev_ops->process_task; + + if (mpp->dev_ops->wait_result) + session->wait_result = + mpp->dev_ops->wait_result; + + if (mpp->dev_ops->deinit) + session->deinit = mpp->dev_ops->deinit; + } session->index = atomic_fetch_inc(&mpp->session_index); - if (mpp->dev_ops->init_session) { + if (mpp->dev_ops && mpp->dev_ops->init_session) { ret = mpp->dev_ops->init_session(session); if (ret) return ret; @@ -1330,6 +1373,9 @@ static int mpp_dev_open(struct inode *inode, struct file *filp) list_add_tail(&session->service_link, &srv->session_list); mutex_unlock(&srv->session_lock); } + session->process_task = mpp_process_task_default; + session->wait_result = mpp_wait_result_default; + session->deinit = mpp_session_deinit_default; filp->private_data = (void *)session; mpp_debug_leave(); @@ -1754,18 +1800,6 @@ int mpp_dev_probe(struct mpp_dev *mpp, mpp->kworker_task = kthread_run(kthread_worker_fn, &mpp->worker, "%s", np->name); - /* read link table capacity */ - ret = of_property_read_u32(np, "rockchip,task-capacity", - &mpp->task_capacity); - if (ret) { - mpp->task_capacity = 1; - kthread_init_work(&mpp->work, mpp_task_try_run); - } else { - dev_info(dev, "%d task capacity link mode detected\n", - mpp->task_capacity); - kthread_init_work(&mpp->work, NULL); - } - /* Get and attach to service */ ret = mpp_attach_service(mpp, dev); if (ret) { @@ -1777,6 +1811,18 @@ int mpp_dev_probe(struct mpp_dev *mpp, mpp->hw_ops = mpp->var->hw_ops; mpp->dev_ops = mpp->var->dev_ops; + /* read link table capacity */ + ret = of_property_read_u32(np, "rockchip,task-capacity", + &mpp->task_capacity); + if (ret) + mpp->task_capacity = 1; + else + dev_info(dev, "%d task capacity link mode detected\n", + mpp->task_capacity); + + kthread_init_work(&mpp->work, mpp->dev_ops->task_worker ? + mpp->dev_ops->task_worker : mpp_task_try_run); + atomic_set(&mpp->reset_request, 0); atomic_set(&mpp->session_index, 0); atomic_set(&mpp->task_count, 0); diff --git a/drivers/video/rockchip/mpp/mpp_common.h b/drivers/video/rockchip/mpp/mpp_common.h index 1e4d84415bc0..75c78c9e340e 100644 --- a/drivers/video/rockchip/mpp/mpp_common.h +++ b/drivers/video/rockchip/mpp/mpp_common.h @@ -355,6 +355,18 @@ struct mpp_session { struct list_head session_link; /* private data */ void *priv; + + /* + * session handler from mpp_dev_ops + * process_task - handle messages of sending task + * wait_result - handle messages of polling task + * deinit - handle session deinit + */ + int (*process_task)(struct mpp_session *session, + struct mpp_task_msgs *msgs); + int (*wait_result)(struct mpp_session *session, + struct mpp_task_msgs *msgs); + void (*deinit)(struct mpp_session *session); }; /* task state in work thread */ @@ -367,6 +379,11 @@ enum mpp_task_state { TASK_STATE_FINISH = 5, TASK_STATE_TIMEOUT = 6, TASK_STATE_DONE = 7, + + TASK_STATE_PREPARE = 8, + TASK_STATE_ABORT = 9, + TASK_STATE_ABORT_READY = 10, + TASK_STATE_PROC_DONE = 11, }; /* The context for the a task */ @@ -464,6 +481,7 @@ struct mpp_service { /* lock for session list */ struct mutex session_lock; struct list_head session_list; + u32 session_count; }; /* @@ -502,11 +520,19 @@ struct mpp_hw_ops { * @result Read status to userspace. * @free_task Release the resource allocate which alloc. * @ioctl Special cammand from userspace. - * @open Open a instance for hardware when set client. - * @release Specific instance release operation for hardware. - * @free Specific instance free operation for hardware. + * @init_session extra initialization on session init. + * @free_session extra cleanup on session deinit. + * @dump_session information dump for session. + * @dump_dev information dump for hardware device. */ struct mpp_dev_ops { + int (*process_task)(struct mpp_session *session, + struct mpp_task_msgs *msgs); + int (*wait_result)(struct mpp_session *session, + struct mpp_task_msgs *msgs); + void (*deinit)(struct mpp_session *session); + void (*task_worker)(struct kthread_work *work_s); + void *(*alloc_task)(struct mpp_session *session, struct mpp_task_msgs *msgs); void *(*prepare)(struct mpp_dev *mpp, struct mpp_task *task); @@ -522,6 +548,7 @@ struct mpp_dev_ops { int (*init_session)(struct mpp_session *session); int (*free_session)(struct mpp_session *session); int (*dump_session)(struct mpp_session *session, struct seq_file *seq); + int (*dump_dev)(struct mpp_dev *mpp); }; struct mpp_taskqueue *mpp_taskqueue_init(struct device *dev);