diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.c b/drivers/media/platform/vivid/vivid-kthread-cap.c index 003319d7816d..60a4939ec49f 100644 --- a/drivers/media/platform/vivid/vivid-kthread-cap.c +++ b/drivers/media/platform/vivid/vivid-kthread-cap.c @@ -793,10 +793,13 @@ static int vivid_thread_vid_cap(void *data) for (;;) { try_to_freeze(); + if (!dev->vid_cap_streaming && !dev->vbi_cap_streaming) + break; if (kthread_should_stop()) break; - mutex_lock(&dev->mutex); + if (mutex_lock_interruptible(&dev->mutex)) + continue; cur_jiffies = jiffies; if (dev->cap_seq_resync) { dev->jiffies_vid_cap = cur_jiffies; @@ -895,17 +898,18 @@ int vivid_start_generating_vid_cap(struct vivid_dev *dev, bool *pstreaming) dev->vid_cap_seq_start = dev->seq_wrap * 128; dev->vbi_cap_seq_start = dev->seq_wrap * 128; + *pstreaming = true; dev->kthread_vid_cap = kthread_run(vivid_thread_vid_cap, dev, "%s-vid-cap", dev->v4l2_dev.name); if (IS_ERR(dev->kthread_vid_cap)) { int err = PTR_ERR(dev->kthread_vid_cap); + *pstreaming = false; dev->kthread_vid_cap = NULL; v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n"); return err; } - *pstreaming = true; vivid_grab_controls(dev, true); dprintk(dev, 1, "returning from %s\n", __func__); @@ -956,8 +960,8 @@ void vivid_stop_generating_vid_cap(struct vivid_dev *dev, bool *pstreaming) /* shutdown control thread */ vivid_grab_controls(dev, false); - mutex_unlock(&dev->mutex); + /* interrupt the mutex_lock_interruptible in the thread */ + send_sig(SIGINT, dev->kthread_vid_cap, 0); kthread_stop(dev->kthread_vid_cap); dev->kthread_vid_cap = NULL; - mutex_lock(&dev->mutex); } diff --git a/drivers/media/platform/vivid/vivid-kthread-out.c b/drivers/media/platform/vivid/vivid-kthread-out.c index ce5bcda2348c..a9f1af4d1768 100644 --- a/drivers/media/platform/vivid/vivid-kthread-out.c +++ b/drivers/media/platform/vivid/vivid-kthread-out.c @@ -140,10 +140,13 @@ static int vivid_thread_vid_out(void *data) for (;;) { try_to_freeze(); + if (!dev->vid_out_streaming && !dev->vbi_out_streaming) + break; if (kthread_should_stop()) break; - mutex_lock(&dev->mutex); + if (mutex_lock_interruptible(&dev->mutex)) + continue; cur_jiffies = jiffies; if (dev->out_seq_resync) { dev->jiffies_vid_out = cur_jiffies; @@ -301,8 +304,8 @@ void vivid_stop_generating_vid_out(struct vivid_dev *dev, bool *pstreaming) /* shutdown control thread */ vivid_grab_controls(dev, false); - mutex_unlock(&dev->mutex); + /* interrupt the mutex_lock_interruptible in the thread */ + send_sig(SIGINT, dev->kthread_vid_out, 0); kthread_stop(dev->kthread_vid_out); dev->kthread_vid_out = NULL; - mutex_lock(&dev->mutex); }