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>
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,
.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,
};
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);
};
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,
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)
{
.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,
};