]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
media: tegra_camera: add start streaming call
authorBryan Wu <pengw@nvidia.com>
Thu, 9 Jul 2015 18:49:32 +0000 (11:49 -0700)
committermobile promotions <svcmobile_promotions@nvidia.com>
Thu, 16 Jul 2015 03:17:47 +0000 (20:17 -0700)
Queueing buffer might happen before starting streaming. So any queueing
buffer operation before starting streaming shouldn't trigger real
capture but just queue the buffer. After starting streaming, it will
wake up kernel workqueue to start real capture.

Bug 1639982

Change-Id: Iaf4c4a5eb599d112e7ef266b0f1770f27b26ebef
Signed-off-by: Bryan Wu <pengw@nvidia.com>
Reviewed-on: http://git-master/r/768663
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Jihoon Bang <jbang@nvidia.com>
Reviewed-by: David Wang (SW-TEGRA) <davidw@nvidia.com>
drivers/media/platform/soc_camera/tegra_camera/common.c
drivers/media/platform/soc_camera/tegra_camera/common.h
drivers/media/platform/soc_camera/tegra_camera/vi2.c

index f29e8a221497889bd1d6d950de3f2395afe38baf..d3bb3ea2f6b89570c37711dd51e0947fe7c88692 100644 (file)
@@ -380,6 +380,20 @@ static void tegra_camera_videobuf_release(struct vb2_buffer *vb)
                cam->ops->videobuf_release(cam, icd, buf);
 }
 
+static int tegra_camera_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+       struct soc_camera_device *icd = container_of(q,
+                                                    struct soc_camera_device,
+                                                    vb2_vidq);
+       struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+       struct tegra_camera *cam = ici->priv;
+
+       if (cam->ops->start_streaming)
+               return cam->ops->start_streaming(cam, icd, count);
+
+       return 0;
+}
+
 static int tegra_camera_stop_streaming(struct vb2_queue *q)
 {
        struct soc_camera_device *icd = container_of(q,
@@ -414,6 +428,7 @@ static struct vb2_ops tegra_camera_videobuf_ops = {
        .buf_init       = tegra_camera_videobuf_init,
        .buf_prepare    = tegra_camera_videobuf_prepare,
        .buf_cleanup    = tegra_camera_videobuf_release,
+       .start_streaming = tegra_camera_start_streaming,
        .stop_streaming = tegra_camera_stop_streaming,
        .buf_queue      = tegra_camera_videobuf_queue,
 };
index 345a7ff1a9614760dc6ccc33394ce2a603b02e60..28555b7b9ba68cb2141c5d30d193350aa97fb4a0 100644 (file)
@@ -86,6 +86,9 @@ struct tegra_camera_ops {
        void (*videobuf_release)(struct tegra_camera *cam,
                               struct soc_camera_device *icd,
                               struct tegra_camera_buffer *buf);
+       int (*start_streaming)(struct tegra_camera *cam,
+                              struct soc_camera_device *icd,
+                              unsigned int count);
        int (*stop_streaming)(struct tegra_camera *cam,
                               struct soc_camera_device *icd);
 };
index 94509d6031787702797f94a32daf795007e6cdac..7bec559a4f90145dcdf3b633e44ba1867759f8b5 100644 (file)
@@ -893,8 +893,10 @@ static void vi2_videobuf_queue(struct tegra_camera *cam,
 
        spin_lock_irq(&chan->videobuf_queue_lock);
        list_add_tail(&buf->queue, &chan->capture);
-       schedule_work(&chan->work);
        spin_unlock_irq(&chan->videobuf_queue_lock);
+
+       if (vb2_is_streaming(buf->vb.vb2_queue))
+               schedule_work(&chan->work);
 }
 
 static void vi2_videobuf_release(struct tegra_camera *cam,
@@ -924,6 +926,19 @@ static void vi2_videobuf_release(struct tegra_camera *cam,
        mutex_unlock(&chan->work_mutex);
 }
 
+static int vi2_start_streaming(struct tegra_camera *cam,
+                              struct soc_camera_device *icd,
+                              unsigned int count)
+{
+       struct vi2_camera *vi2_cam = (struct vi2_camera *)cam;
+       int port = icd_to_port(icd);
+       struct vi2_channel *chan = &vi2_cam->channels[port];
+
+       schedule_work(&chan->work);
+
+       return 0;
+}
+
 static int vi2_stop_streaming(struct tegra_camera *cam,
                              struct soc_camera_device *icd)
 {
@@ -1343,6 +1358,7 @@ struct tegra_camera_ops vi2_ops = {
        .s_mbus_fmt             = vi2_s_mbus_fmt,
        .videobuf_queue         = vi2_videobuf_queue,
        .videobuf_release       = vi2_videobuf_release,
+       .start_streaming        = vi2_start_streaming,
        .stop_streaming         = vi2_stop_streaming,
 };