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 <herman.chen@rock-chips.com>
Change-Id: Ib0b23c90083b9acab6a8eec8db0871304dbb72ca
This commit is contained in:
Herman Chen
2021-08-03 19:52:05 +08:00
committed by Tao Huang
parent 167b70d89d
commit 6a3ea1ba7a
2 changed files with 106 additions and 33 deletions

View File

@@ -8,6 +8,9 @@
* Ding Wei, leo.ding@rock-chips.com
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
@@ -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);

View File

@@ -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);