summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/platform/coda/coda-common.c85
-rw-r--r--drivers/media/platform/coda/coda.h13
2 files changed, 63 insertions, 35 deletions
diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c
index dc60bbfd6eb..07c132485d8 100644
--- a/drivers/media/platform/coda/coda-common.c
+++ b/drivers/media/platform/coda/coda-common.c
@@ -800,7 +800,7 @@ static const struct v4l2_ioctl_ops coda_ioctl_ops = {
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};
-static int coda_start_decoding(struct coda_ctx *ctx);
+static int __coda_start_decoding(struct coda_ctx *ctx);
static inline int coda_get_bitstream_payload(struct coda_ctx *ctx)
{
@@ -976,7 +976,7 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
/* Run coda_start_decoding (again) if not yet initialized */
if (!ctx->initialized) {
- int ret = coda_start_decoding(ctx);
+ int ret = __coda_start_decoding(ctx);
if (ret < 0) {
v4l2_err(&dev->v4l2_dev, "failed to start decoding\n");
v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx);
@@ -1041,7 +1041,7 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
return 0;
}
-static void coda_prepare_encode(struct coda_ctx *ctx)
+static int coda_prepare_encode(struct coda_ctx *ctx)
{
struct coda_q_data *q_data_src, *q_data_dst;
struct vb2_buffer *src_buf, *dst_buf;
@@ -1183,6 +1183,8 @@ static void coda_prepare_encode(struct coda_ctx *ctx)
ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG;
coda_write(dev, ctx->bit_stream_param, CODA_REG_BIT_BIT_STREAM_PARAM);
}
+
+ return 0;
}
static void coda_device_run(void *m2m_priv)
@@ -1233,16 +1235,12 @@ static void coda_pic_run_work(struct work_struct *work)
mutex_lock(&ctx->buffer_mutex);
mutex_lock(&dev->coda_mutex);
- if (ctx->inst_type == CODA_INST_DECODER) {
- ret = coda_prepare_decode(ctx);
- if (ret < 0) {
- mutex_unlock(&dev->coda_mutex);
- mutex_unlock(&ctx->buffer_mutex);
- /* job_finish scheduled by prepare_decode */
- return;
- }
- } else {
- coda_prepare_encode(ctx);
+ ret = ctx->ops->prepare_run(ctx);
+ if (ret < 0 && ctx->inst_type == CODA_INST_DECODER) {
+ mutex_unlock(&dev->coda_mutex);
+ mutex_unlock(&ctx->buffer_mutex);
+ /* job_finish scheduled by prepare_decode */
+ return;
}
if (dev->devtype->product != CODA_DX6)
@@ -1260,10 +1258,7 @@ static void coda_pic_run_work(struct work_struct *work)
coda_hw_reset(ctx);
} else if (!ctx->aborting) {
- if (ctx->inst_type == CODA_INST_DECODER)
- coda_finish_decode(ctx);
- else
- coda_finish_encode(ctx);
+ ctx->ops->finish_run(ctx);
}
if (ctx->aborting || (!ctx->streamon_cap && !ctx->streamon_out))
@@ -1846,7 +1841,7 @@ err:
return ret;
}
-static int coda_start_decoding(struct coda_ctx *ctx)
+static int __coda_start_decoding(struct coda_ctx *ctx)
{
struct coda_q_data *q_data_src, *q_data_dst;
u32 bitstream_buf, bitstream_size;
@@ -2037,6 +2032,18 @@ static int coda_start_decoding(struct coda_ctx *ctx)
return 0;
}
+static int coda_start_decoding(struct coda_ctx *ctx)
+{
+ struct coda_dev *dev = ctx->dev;
+ int ret;
+
+ mutex_lock(&dev->coda_mutex);
+ ret = __coda_start_decoding(ctx);
+ mutex_unlock(&dev->coda_mutex);
+
+ return ret;
+}
+
static int coda_encode_header(struct coda_ctx *ctx, struct vb2_buffer *buf,
int header_code, u8 *header, int *size)
{
@@ -2081,7 +2088,6 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
{
struct coda_ctx *ctx = vb2_get_drv_priv(q);
struct v4l2_device *v4l2_dev = &ctx->dev->v4l2_dev;
- struct coda_dev *dev = ctx->dev;
struct coda_q_data *q_data_src, *q_data_dst;
u32 dst_fourcc;
int ret = 0;
@@ -2133,16 +2139,12 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
if (ret < 0)
return ret;
+ ret = ctx->ops->start_streaming(ctx);
if (ctx->inst_type == CODA_INST_DECODER) {
- mutex_lock(&dev->coda_mutex);
- ret = coda_start_decoding(ctx);
- mutex_unlock(&dev->coda_mutex);
if (ret == -EAGAIN)
return 0;
else if (ret < 0)
return ret;
- } else {
- ret = coda_start_encoding(ctx);
}
ctx->initialized = 1;
@@ -2737,10 +2739,9 @@ static int coda_next_free_instance(struct coda_dev *dev)
return idx;
}
-static int coda_open(struct file *file, enum coda_inst_type inst_type)
+static int coda_open(struct file *file, enum coda_inst_type inst_type,
+ const struct coda_context_ops *ctx_ops)
{
- int (*queue_init)(void *priv, struct vb2_queue *src_vq,
- struct vb2_queue *dst_vq);
struct coda_dev *dev = video_drvdata(file);
struct coda_ctx *ctx = NULL;
char *name;
@@ -2763,9 +2764,10 @@ static int coda_open(struct file *file, enum coda_inst_type inst_type)
kfree(name);
ctx->inst_type = inst_type;
+ ctx->ops = ctx_ops;
init_completion(&ctx->completion);
INIT_WORK(&ctx->pic_run_work, coda_pic_run_work);
- INIT_WORK(&ctx->seq_end_work, coda_seq_end_work);
+ INIT_WORK(&ctx->seq_end_work, ctx->ops->seq_end_work);
v4l2_fh_init(&ctx->fh, video_devdata(file));
file->private_data = &ctx->fh;
v4l2_fh_add(&ctx->fh);
@@ -2796,11 +2798,8 @@ static int coda_open(struct file *file, enum coda_inst_type inst_type)
goto err_clk_ahb;
set_default_params(ctx);
- if (inst_type == CODA_INST_ENCODER)
- queue_init = coda_encoder_queue_init;
- else
- queue_init = coda_decoder_queue_init;
- ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, queue_init);
+ ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx,
+ ctx->ops->queue_init);
if (IS_ERR(ctx->fh.m2m_ctx)) {
ret = PTR_ERR(ctx->fh.m2m_ctx);
@@ -2871,14 +2870,30 @@ err_coda_max:
return ret;
}
+struct coda_context_ops coda_encode_ops = {
+ .queue_init = coda_encoder_queue_init,
+ .start_streaming = coda_start_encoding,
+ .prepare_run = coda_prepare_encode,
+ .finish_run = coda_finish_encode,
+ .seq_end_work = coda_seq_end_work,
+};
+
+struct coda_context_ops coda_decode_ops = {
+ .queue_init = coda_decoder_queue_init,
+ .start_streaming = coda_start_decoding,
+ .prepare_run = coda_prepare_decode,
+ .finish_run = coda_finish_decode,
+ .seq_end_work = coda_seq_end_work
+};
+
static int coda_encoder_open(struct file *file)
{
- return coda_open(file, CODA_INST_ENCODER);
+ return coda_open(file, CODA_INST_ENCODER, &coda_encode_ops);
}
static int coda_decoder_open(struct file *file)
{
- return coda_open(file, CODA_INST_DECODER);
+ return coda_open(file, CODA_INST_DECODER, &coda_decode_ops);
}
static int coda_release(struct file *file)
diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h
index aafd1869004..c98270c2532 100644
--- a/drivers/media/platform/coda/coda.h
+++ b/drivers/media/platform/coda/coda.h
@@ -164,6 +164,18 @@ struct gdi_tiled_map {
#define GDI_LINEAR_FRAME_MAP 0
};
+struct coda_ctx;
+
+struct coda_context_ops {
+ int (*queue_init)(void *priv, struct vb2_queue *src_vq,
+ struct vb2_queue *dst_vq);
+ int (*start_streaming)(struct coda_ctx *ctx);
+ int (*prepare_run)(struct coda_ctx *ctx);
+ void (*finish_run)(struct coda_ctx *ctx);
+ void (*seq_end_work)(struct work_struct *work);
+ void (*release)(struct coda_ctx *ctx);
+};
+
struct coda_ctx {
struct coda_dev *dev;
struct mutex buffer_mutex;
@@ -171,6 +183,7 @@ struct coda_ctx {
struct work_struct pic_run_work;
struct work_struct seq_end_work;
struct completion completion;
+ const struct coda_context_ops *ops;
int aborting;
int initialized;
int streamon_out;