msm: mpq8064: Separate q/dq buffer for VCAP de-interlacing mode
This change fixes a crash when running VCAP in de-interlace mode.
The problem was noticed in the introduction of kernel 3.4. VCAP
was improperly using the videobuf2 framework APIs. Since VCAP is
already reliant on queue structure provided by videobuf2 framework,
we created our own basic version of the qbuf and dqbuf calls that
have some similarities to the videobuf2 framework. This addition
was necessary since we are calling qbuf from a kernel work thread.
Since moving to kernel 3.4 there has been a change in videobuf2
qbuf that dereferences the current process.s mm_struct, from a
kernel work thread this struct is NULL, which was causing a crash.
When we are de-interlacing a captured video we are cycling the
buffers internally in the driver, which is why we needed to create
our own q/dq buffer functionality.
Change-Id: Id51b775ae7f0a58bbac8a581e07fa02417802a30
Signed-off-by: Terence Hampson <thampson@codeaurora.org>
diff --git a/drivers/media/video/vcap_vp.c b/drivers/media/video/vcap_vp.c
index 1b503ba..db38902 100644
--- a/drivers/media/video/vcap_vp.c
+++ b/drivers/media/video/vcap_vp.c
@@ -117,21 +117,21 @@
struct vcap_buffer *buf_vp;
int rc;
- p.type = V4L2_BUF_TYPE_INTERLACED_IN_DECODER;
p.memory = V4L2_MEMORY_USERPTR;
/* This loop exits when there is no more buffers left */
while (1) {
+ p.type = V4L2_BUF_TYPE_INTERLACED_IN_DECODER;
if (!vp_work->cd->streaming)
return;
- rc = vb2_dqbuf(&vp_work->cd->vp_in_vidq, &p, O_NONBLOCK);
+ rc = vcvp_dqbuf(&vp_work->cd->vp_in_vidq, &p);
if (rc < 0)
return;
vb_vc = vp_work->cd->vc_vidq.bufs[p.index];
if (NULL == vb_vc) {
dprintk(1, "%s: buffer is NULL\n", __func__);
- vb2_qbuf(&vp_work->cd->vp_in_vidq, &p);
+ vcvp_qbuf(&vp_work->cd->vp_in_vidq, &p);
return;
}
buf_vc = container_of(vb_vc, struct vcap_buffer, vb);
@@ -139,7 +139,7 @@
vb_vp = vp_work->cd->vp_in_vidq.bufs[p.index];
if (NULL == vb_vp) {
dprintk(1, "%s: buffer is NULL\n", __func__);
- vb2_qbuf(&vp_work->cd->vp_in_vidq, &p);
+ vcvp_qbuf(&vp_work->cd->vp_in_vidq, &p);
return;
}
buf_vp = container_of(vb_vp, struct vcap_buffer, vb);
@@ -150,7 +150,7 @@
p.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
/* This call should not fail */
- rc = vb2_qbuf(&vp_work->cd->vc_vidq, &p);
+ rc = vcvp_qbuf(&vp_work->cd->vc_vidq, &p);
if (rc < 0) {
dprintk(1, "%s: qbuf to vc failed\n", __func__);
buf_vp->ion_handle = buf_vc->ion_handle;
@@ -158,7 +158,7 @@
buf_vc->ion_handle = NULL;
buf_vc->paddr = 0;
p.type = V4L2_BUF_TYPE_INTERLACED_IN_DECODER;
- vb2_qbuf(&vp_work->cd->vp_in_vidq, &p);
+ vcvp_qbuf(&vp_work->cd->vp_in_vidq, &p);
}
}
}