Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3562c43be8cfd6e300508d7c33acebf3369eacd3
Commit:     3562c43be8cfd6e300508d7c33acebf3369eacd3
Parent:     da80be21362376443c6ee9918dfff408e83e0c39
Author:     Hans Verkuil <[EMAIL PROTECTED]>
AuthorDate: Sat Aug 18 11:46:05 2007 -0300
Committer:  Mauro Carvalho Chehab <[EMAIL PROTECTED]>
CommitDate: Tue Oct 9 22:05:31 2007 -0300

    V4L/DVB (6045): ivtv: fix handling of INITIALIZE_INPUT fw call
    
    The CX2341X_ENC_INITIALIZE_INPUT firmware call requires careful handling,
    otherwise the computer can freeze or the top-third of the screen can start
    flickering. This patch ensures that CX2341X_ENC_INITIALIZE_INPUT is called
    at the right time and in the right way.
    
    In addition the stop capture handling was improved so that the last pending
    DMA transfer is also processed. Otherwise this would be the first data that
    arrived when a new capture was started which is not what you want.
    
    Signed-off-by: Hans Verkuil <[EMAIL PROTECTED]>
    Signed-off-by: Mauro Carvalho Chehab <[EMAIL PROTECTED]>
---
 drivers/media/video/ivtv/ivtv-fileops.c |   19 +++++++++++--------
 drivers/media/video/ivtv/ivtv-ioctl.c   |    3 +++
 drivers/media/video/ivtv/ivtv-streams.c |   28 +++++-----------------------
 3 files changed, 19 insertions(+), 31 deletions(-)

diff --git a/drivers/media/video/ivtv/ivtv-fileops.c 
b/drivers/media/video/ivtv/ivtv-fileops.c
index 9e867b5..908e640 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -892,12 +892,20 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
                        return -EBUSY;
                }
 
+               if (!test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
+                       if (atomic_read(&itv->capturing) > 0) {
+                               /* switching to radio while capture is
+                                  in progress is not polite */
+                               kfree(item);
+                               return -EBUSY;
+                       }
+               }
+               /* Mark that the radio is being used. */
+               set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
                /* We have the radio */
                ivtv_mute(itv);
                /* Switch tuner to radio */
                ivtv_call_i2c_clients(itv, AUDC_SET_RADIO, NULL);
-               /* Mark that the radio is being used. */
-               set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
                /* Select the correct audio input (i.e. radio tuner) */
                ivtv_audio_set_io(itv);
                if (itv->hw_flags & IVTV_HW_SAA711X)
@@ -931,13 +939,8 @@ void ivtv_mute(struct ivtv *itv)
 
 void ivtv_unmute(struct ivtv *itv)
 {
-       /* initialize or refresh input */
-       if (atomic_read(&itv->capturing) == 0)
-               ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0);
-
-       ivtv_msleep_timeout(100, 0);
-
        if (atomic_read(&itv->capturing)) {
+               ivtv_msleep_timeout(100, 0);
                ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12);
                ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 0);
        }
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c 
b/drivers/media/video/ivtv/ivtv-ioctl.c
index cee6c55..734f2d2 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -906,6 +906,9 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, 
unsigned int cmd, void
                        IVTV_DEBUG_INFO("Input unchanged\n");
                        break;
                }
+               if (atomic_read(&itv->capturing) > 0) {
+                       return -EBUSY;
+               }
                IVTV_DEBUG_INFO("Changing input from %d to %d\n",
                                itv->active_input, inp);
 
diff --git a/drivers/media/video/ivtv/ivtv-streams.c 
b/drivers/media/video/ivtv/ivtv-streams.c
index 405e2e3..0582b9d 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -554,9 +554,10 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
                clear_bit(IVTV_F_I_EOS, &itv->i_flags);
 
                /* Initialize Digitizer for Capture */
+               itv->video_dec_func(itv, VIDIOC_STREAMOFF, 0);
+               ivtv_msleep_timeout(300, 1);
                ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0);
-
-               ivtv_msleep_timeout(100, 0);
+               itv->video_dec_func(itv, VIDIOC_STREAMON, 0);
        }
 
        /* begin_capture */
@@ -713,7 +714,6 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int 
gop_end)
        int cap_type;
        unsigned long then;
        int stopmode;
-       u32 data[CX2341X_MBOX_MAX_DATA];
 
        if (s->v4l2dev == NULL)
                return -EINVAL;
@@ -793,27 +793,9 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, 
int gop_end)
                }
 
                then = jiffies;
-               /* Make sure DMA is complete */
-               add_wait_queue(&s->waitq, &wait);
-               do {
-                       /* check if DMA is pending */
-                       if ((s->type == IVTV_ENC_STREAM_TYPE_MPG) &&    /* MPG 
Only */
-                           (read_reg(IVTV_REG_DMASTATUS) & 0x02)) {
-                               /* Check for last DMA */
-                               ivtv_vapi_result(itv, data, 
CX2341X_ENC_GET_SEQ_END, 2, 0, 0);
-
-                               if (data[0] == 1) {
-                                       IVTV_DEBUG_DMA("%s: Last DMA of size 
0x%08x\n", s->name, data[1]);
-                                       break;
-                               }
-                       } else if (read_reg(IVTV_REG_DMASTATUS) & 0x02) {
-                               break;
-                       }
-               } while (!ivtv_msleep_timeout(10, 1) &&
-                        then + msecs_to_jiffies(2000) > jiffies);
 
-               set_current_state(TASK_RUNNING);
-               remove_wait_queue(&s->waitq, &wait);
+               /* Handle any pending interrupts */
+               ivtv_msleep_timeout(100, 1);
        }
 
        atomic_dec(&itv->capturing);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to