mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
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:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user