summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuinn Jensen <quinn.jensen@freescale.com>2007-10-24 21:20:56 -0600
committerQuinn Jensen <quinn.jensen@freescale.com>2007-10-24 21:20:56 -0600
commit331e051a04d3d1a5195566698aa3f384f289f80f (patch)
treeb24b86ffe5aa30cd143db2fb9ee7cd096ec0497b
parentab0623cb532304b507552f4004e7492de531e816 (diff)
CR 34440439: Under heavy load v4l2 ioctls sometimes return error (EINTR
Patch for CR 34440439: Under heavy load v4l2 ioctls sometimes return error (EINTR or ETIME). This patch fixes vpu v4l2 interrupt code to be more robust. Applies to linux 2.6.22 kernel for MX platforms. Ported to 2.6.22 by Ross Wille http://www.bitshrine.org/gpp/linux-2.6.22-mx-CR-34440439-Under-heavy-load-v4l2-ioctls-s.patch
-rw-r--r--drivers/media/video/mxc/capture/mx27_v4l2_capture.c23
-rw-r--r--drivers/media/video/mxc/output/mx27_v4l2_output.c9
-rw-r--r--drivers/media/video/mxc/output/mxc_v4l2_output.c18
-rw-r--r--drivers/mxc/vpu/mxc_vpu.c9
4 files changed, 46 insertions, 13 deletions
diff --git a/drivers/media/video/mxc/capture/mx27_v4l2_capture.c b/drivers/media/video/mxc/capture/mx27_v4l2_capture.c
index f1b90f9591a2..0655d8409ce3 100644
--- a/drivers/media/video/mxc/capture/mx27_v4l2_capture.c
+++ b/drivers/media/video/mxc/capture/mx27_v4l2_capture.c
@@ -43,6 +43,10 @@ static int csi_mclk_flag_backup;
static int video_nr = -1;
static cam_data *g_cam;
+static int dq_intr_cnt=0;
+static int dq_timeout_cnt=0;
+static int empty_wq_cnt=0;
+
/*!
* Free frame buffers
*
@@ -651,12 +655,15 @@ static int mxc_v4l_dqueue(cam_data * cam, struct v4l2_buffer *buf)
if (!wait_event_interruptible_timeout(cam->enc_queue,
cam->enc_counter != 0, 10 * HZ)) {
- printk(KERN_ERR "mxc_v4l_dqueue timeout enc_counter %x\n",
- cam->enc_counter);
+ if(dq_timeout_cnt == 0)
+ printk(KERN_ERR "mxc_v4l_dqueue timeout enc_counter %x\n",
+ cam->enc_counter);
+ dq_timeout_cnt++;
return -ETIME;
} else if (signal_pending(current)) {
- printk(KERN_ERR "mxc_v4l_dqueue() interrupt received\n");
- mxc_free_frames(cam);
+ if(dq_intr_cnt == 0)
+ printk(KERN_ERR "mxc_v4l_dqueue() interrupt received\n");
+ dq_intr_cnt++;
return -ERESTARTSYS;
}
@@ -718,6 +725,9 @@ static int mxc_v4l_open(struct inode *inode, struct file *file)
cam_data *cam = dev->priv;
int err = 0;
+ dq_intr_cnt = 0;
+ dq_timeout_cnt = 0;
+ empty_wq_cnt = 0;
if (!cam) {
pr_info("Internal error, cam_data not found!\n");
return -ENODEV;
@@ -1817,7 +1827,10 @@ static void camera_callback(u32 mask, void *dev)
return;
if (list_empty(&cam->working_q)) {
- printk(KERN_ERR "camera_callback: working queue empty\n");
+ if (empty_wq_cnt == 0) {
+ printk(KERN_ERR "camera_callback: working queue empty\n");
+ }
+ empty_wq_cnt++;
return;
}
diff --git a/drivers/media/video/mxc/output/mx27_v4l2_output.c b/drivers/media/video/mxc/output/mx27_v4l2_output.c
index 15b54e5c9cfe..7afac05bf1c3 100644
--- a/drivers/media/video/mxc/output/mx27_v4l2_output.c
+++ b/drivers/media/video/mxc/output/mx27_v4l2_output.c
@@ -59,6 +59,8 @@ uint32_t g_buf_output_cnt;
uint32_t g_buf_q_cnt;
uint32_t g_buf_dq_cnt;
+static int dq_intr_cnt = 0;
+
#ifdef CONFIG_VIDEO_MXC_OUTPUT_FBSYNC
static uint32_t g_output_fb = -1;
static uint32_t g_fb_enabled = 0;
@@ -727,6 +729,7 @@ static int mxc_v4l2out_open(struct inode *inode, struct file *file)
vout_data *vout = video_get_drvdata(dev);
int err;
+ dq_intr_cnt = 0;
if (!vout) {
pr_info("Internal error, vout_data not found!\n");
return -ENODEV;
@@ -1026,8 +1029,10 @@ mxc_v4l2out_do_ioctl(struct inode *inode, struct file *file,
retval = -ETIME;
break;
} else if (signal_pending(current)) {
- pr_debug("VIDIOC_DQBUF: interrupt received\n");
- vout->state = STATE_STREAM_STOPPING;
+ if(dq_intr_cnt == 0)
+ pr_debug("VIDIOC_DQBUF: interrupt received\n");
+ dq_intr_cnt++;
+ // vout->state = STATE_STREAM_STOPPING;
retval = -ERESTARTSYS;
break;
}
diff --git a/drivers/media/video/mxc/output/mxc_v4l2_output.c b/drivers/media/video/mxc/output/mxc_v4l2_output.c
index 772bf4473348..6f0fc6477fdd 100644
--- a/drivers/media/video/mxc/output/mxc_v4l2_output.c
+++ b/drivers/media/video/mxc/output/mxc_v4l2_output.c
@@ -64,6 +64,9 @@ uint32_t g_buf_output_cnt;
uint32_t g_buf_q_cnt;
uint32_t g_buf_dq_cnt;
+static int dq_intr_cnt=0;
+static int dq_timeout_cnt=0;
+
#define QUEUE_SIZE (MAX_FRAME_NUM + 1)
static __inline int queue_size(v4l_queue * q)
{
@@ -960,6 +963,8 @@ static int mxc_v4l2out_open(struct inode *inode, struct file *file)
vout_data *vout = video_get_drvdata(dev);
int err;
+ dq_intr_cnt = 0;
+ dq_timeout_cnt = 0;
if (!vout) {
return -ENODEV;
}
@@ -1251,13 +1256,18 @@ mxc_v4l2out_do_ioctl(struct inode *inode, struct file *file,
queue_size(&vout->
done_q)
!= 0, 10 * HZ)) {
- dev_dbg(vdev->dev, "VIDIOC_DQBUF: timeout\n");
+ if(dq_timeout_cnt == 0){
+ dev_dbg(vdev->dev, "VIDIOC_DQBUF: timeout\n");
+ }
+ dq_timeout++;
retval = -ETIME;
break;
} else if (signal_pending(current)) {
- dev_dbg(vdev->dev,
- "VIDIOC_DQBUF: interrupt received\n");
- vout->state = STATE_STREAM_STOPPING;
+ if (dq_intr_cnt == 0) {
+ dev_dbg(vdev->dev,
+ "VIDIOC_DQBUF: interrupt received\n");
+ }
+ dq_intr_cnt++
retval = -ERESTARTSYS;
break;
}
diff --git a/drivers/mxc/vpu/mxc_vpu.c b/drivers/mxc/vpu/mxc_vpu.c
index be9e443f83a8..d78b4700f531 100644
--- a/drivers/mxc/vpu/mxc_vpu.c
+++ b/drivers/mxc/vpu/mxc_vpu.c
@@ -66,6 +66,7 @@ static struct clk *vpu_clk;
/* implement the blocking ioctl */
static int codec_done = 0;
static wait_queue_head_t vpu_queue;
+static int wait_intr_cnt = 0;
/*!
* Private function to free buffers
@@ -257,10 +258,14 @@ static int vpu_ioctl(struct inode *inode, struct file *filp, u_int cmd,
msecs_to_jiffies(timeout))) {
printk(KERN_WARNING "VPU blocking: timeout.\n");
ret = -ETIME;
+ return ret;
} else if (signal_pending(current)) {
- printk(KERN_WARNING
- "VPU interrupt received.\n");
+ if (wait_intr_cnt == 0) {
+ printk(KERN_WARNING "VPU interrupt received.\n");
+ }
+ wait_intr_cnt++;
ret = -ERESTARTSYS;
+ return ret;
}
codec_done = 0;