unsigned long flags;
int ret;
+ /* Allocate scratch buffer. */
+ vin->scratch = dma_alloc_coherent(vin->dev, vin->format.sizeimage,
+ &vin->scratch_phys, GFP_KERNEL);
+ if (!vin->scratch) {
+ spin_lock_irqsave(&vin->qlock, flags);
+ return_all_buffers(vin, VB2_BUF_STATE_QUEUED);
+ spin_unlock_irqrestore(&vin->qlock, flags);
+ vin_err(vin, "Failed to allocate scratch buffer\n");
+ return -ENOMEM;
+ }
+
sd = vin_to_source(vin);
v4l2_subdev_call(sd, video, s_stream, 1);
spin_unlock_irqrestore(&vin->qlock, flags);
+ if (ret)
+ dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch,
+ vin->scratch_phys);
+
return ret;
}
/* disable interrupts */
rvin_disable_interrupts(vin);
+
+ /* Free scratch buffer. */
+ dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch,
+ vin->scratch_phys);
}
static const struct vb2_ops rvin_qops = {
*
* @lock: protects @queue
* @queue: vb2 buffers queue
+ * @scratch: cpu address for scratch buffer
+ * @scratch_phys: physical address of the scratch buffer
*
* @qlock: protects @queue_buf, @buf_list, @continuous, @sequence
* @state
struct mutex lock;
struct vb2_queue queue;
+ void *scratch;
+ dma_addr_t scratch_phys;
spinlock_t qlock;
struct vb2_v4l2_buffer *queue_buf[HW_BUFFER_NUM];