static int start_streaming(struct vb2_queue *q, unsigned int count) { struct fimc_lite *fimc = q->drv_priv; int ret; fimc->frame_count = 0; ret = fimc_lite_hw_init(fimc); if (ret) { fimc_lite_reinit(fimc, false); return ret; } set_bit(ST_FLITE_PENDING, &fimc->state); if (!list_empty(&fimc->active_buf_q) && !test_and_set_bit(ST_FLITE_STREAM, &fimc->state)) { flite_hw_capture_start(fimc); if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state)) fimc_pipeline_call(fimc, set_stream, &fimc->pipeline, 1); } if (debug > 0) flite_hw_dump_regs(fimc, __func__); return 0; }
static int start_streaming(struct vb2_queue *q, unsigned int count) { struct fimc_lite *fimc = q->drv_priv; unsigned long flags; int ret; spin_lock_irqsave(&fimc->slock, flags); fimc->buf_index = 0; fimc->frame_count = 0; spin_unlock_irqrestore(&fimc->slock, flags); ret = fimc_lite_hw_init(fimc, false); if (ret) { fimc_lite_reinit(fimc, false); return ret; } set_bit(ST_FLITE_PENDING, &fimc->state); if (!list_empty(&fimc->active_buf_q) && !test_and_set_bit(ST_FLITE_STREAM, &fimc->state)) { flite_hw_capture_start(fimc); if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state)) fimc_pipeline_call(&fimc->ve, set_stream, 1); } if (debug > 0) flite_hw_dump_regs(fimc, __func__); return 0; }
static int fimc_lite_resume(struct device *dev) { struct fimc_lite *fimc = dev_get_drvdata(dev); struct flite_buffer *buf; unsigned long flags; int i; spin_lock_irqsave(&fimc->slock, flags); if (!test_and_clear_bit(ST_LPM, &fimc->state) || !test_bit(ST_FLITE_IN_USE, &fimc->state)) { spin_unlock_irqrestore(&fimc->slock, flags); return 0; } flite_hw_reset(fimc); spin_unlock_irqrestore(&fimc->slock, flags); if (!test_and_clear_bit(ST_FLITE_SUSPENDED, &fimc->state)) return 0; INIT_LIST_HEAD(&fimc->active_buf_q); fimc_pipeline_call(fimc, open, &fimc->pipeline, &fimc->vfd.entity, false); fimc_lite_hw_init(fimc); clear_bit(ST_FLITE_SUSPENDED, &fimc->state); for (i = 0; i < fimc->reqbufs_count; i++) { if (list_empty(&fimc->pending_buf_q)) break; buf = fimc_lite_pending_queue_pop(fimc); buffer_queue(&buf->vb); } return 0; }
static int fimc_lite_subdev_s_stream(struct v4l2_subdev *sd, int on) { struct fimc_lite *fimc = v4l2_get_subdevdata(sd); unsigned long flags; int ret; /* * Find sensor subdev linked to FIMC-LITE directly or through * MIPI-CSIS. This is required for configuration where FIMC-LITE * is used as a subdev only and feeds data internally to FIMC-IS. * The pipeline links are protected through entity.stream_count * so there is no need to take the media graph mutex here. */ fimc->sensor = fimc_find_remote_sensor(&sd->entity); if (atomic_read(&fimc->out_path) != FIMC_IO_ISP) return -ENOIOCTLCMD; mutex_lock(&fimc->lock); if (on) { flite_hw_reset(fimc); ret = fimc_lite_hw_init(fimc, true); if (!ret) { spin_lock_irqsave(&fimc->slock, flags); flite_hw_capture_start(fimc); spin_unlock_irqrestore(&fimc->slock, flags); } } else { set_bit(ST_FLITE_OFF, &fimc->state); spin_lock_irqsave(&fimc->slock, flags); flite_hw_capture_stop(fimc); spin_unlock_irqrestore(&fimc->slock, flags); ret = wait_event_timeout(fimc->irq_queue, !test_bit(ST_FLITE_OFF, &fimc->state), msecs_to_jiffies(200)); if (ret == 0) v4l2_err(sd, "s_stream(0) timeout\n"); clear_bit(ST_FLITE_RUN, &fimc->state); } mutex_unlock(&fimc->lock); return ret; }