diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index dc60bbfd6ebc..07c132485d8f 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 @@ static int coda_alloc_context_buffers(struct coda_ctx *ctx, 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 @@ static int coda_open(struct file *file, enum coda_inst_type inst_type) 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 aafd1869004b..c98270c2532a 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;