Lines Matching full:cru

3  * Driver for Renesas RZ/G2L CRU
22 #include "rzg2l-cru.h"
23 #include "rzg2l-cru-regs.h"
45 static void rzg2l_cru_write(struct rzg2l_cru_dev *cru, u32 offset, u32 value) in rzg2l_cru_write() argument
47 iowrite32(value, cru->base + offset); in rzg2l_cru_write()
50 static u32 rzg2l_cru_read(struct rzg2l_cru_dev *cru, u32 offset) in rzg2l_cru_read() argument
52 return ioread32(cru->base + offset); in rzg2l_cru_read()
56 static void return_unused_buffers(struct rzg2l_cru_dev *cru, in return_unused_buffers() argument
63 spin_lock_irqsave(&cru->qlock, flags); in return_unused_buffers()
64 for (i = 0; i < cru->num_buf; i++) { in return_unused_buffers()
65 if (cru->queue_buf[i]) { in return_unused_buffers()
66 vb2_buffer_done(&cru->queue_buf[i]->vb2_buf, in return_unused_buffers()
68 cru->queue_buf[i] = NULL; in return_unused_buffers()
72 list_for_each_entry_safe(buf, node, &cru->buf_list, list) { in return_unused_buffers()
76 spin_unlock_irqrestore(&cru->qlock, flags); in return_unused_buffers()
83 struct rzg2l_cru_dev *cru = vb2_get_drv_priv(vq); in rzg2l_cru_queue_setup() local
87 return sizes[0] < cru->format.sizeimage ? -EINVAL : 0; in rzg2l_cru_queue_setup()
90 sizes[0] = cru->format.sizeimage; in rzg2l_cru_queue_setup()
97 struct rzg2l_cru_dev *cru = vb2_get_drv_priv(vb->vb2_queue); in rzg2l_cru_buffer_prepare() local
98 unsigned long size = cru->format.sizeimage; in rzg2l_cru_buffer_prepare()
101 dev_err(cru->dev, "buffer too small (%lu < %lu)\n", in rzg2l_cru_buffer_prepare()
114 struct rzg2l_cru_dev *cru = vb2_get_drv_priv(vb->vb2_queue); in rzg2l_cru_buffer_queue() local
117 spin_lock_irqsave(&cru->qlock, flags); in rzg2l_cru_buffer_queue()
119 list_add_tail(to_buf_list(vbuf), &cru->buf_list); in rzg2l_cru_buffer_queue()
121 spin_unlock_irqrestore(&cru->qlock, flags); in rzg2l_cru_buffer_queue()
124 static void rzg2l_cru_set_slot_addr(struct rzg2l_cru_dev *cru, in rzg2l_cru_set_slot_addr() argument
135 rzg2l_cru_write(cru, AMnMBxADDRL(slot), addr); in rzg2l_cru_set_slot_addr()
136 rzg2l_cru_write(cru, AMnMBxADDRH(slot), 0); in rzg2l_cru_set_slot_addr()
145 static void rzg2l_cru_fill_hw_slot(struct rzg2l_cru_dev *cru, int slot) in rzg2l_cru_fill_hw_slot() argument
152 if (WARN_ON(cru->queue_buf[slot])) in rzg2l_cru_fill_hw_slot()
155 dev_dbg(cru->dev, "Filling HW slot: %d\n", slot); in rzg2l_cru_fill_hw_slot()
157 if (list_empty(&cru->buf_list)) { in rzg2l_cru_fill_hw_slot()
158 cru->queue_buf[slot] = NULL; in rzg2l_cru_fill_hw_slot()
159 phys_addr = cru->scratch_phys; in rzg2l_cru_fill_hw_slot()
162 buf = list_entry(cru->buf_list.next, in rzg2l_cru_fill_hw_slot()
166 cru->queue_buf[slot] = vbuf; in rzg2l_cru_fill_hw_slot()
172 rzg2l_cru_set_slot_addr(cru, slot, phys_addr); in rzg2l_cru_fill_hw_slot()
175 static void rzg2l_cru_initialize_axi(struct rzg2l_cru_dev *cru) in rzg2l_cru_initialize_axi() argument
184 rzg2l_cru_write(cru, AMnMBVALID, AMnMBVALID_MBVALID(cru->num_buf - 1)); in rzg2l_cru_initialize_axi()
186 for (slot = 0; slot < cru->num_buf; slot++) in rzg2l_cru_initialize_axi()
187 rzg2l_cru_fill_hw_slot(cru, slot); in rzg2l_cru_initialize_axi()
190 amnaxiattr = rzg2l_cru_read(cru, AMnAXIATTR) & ~AMnAXIATTR_AXILEN_MASK; in rzg2l_cru_initialize_axi()
192 rzg2l_cru_write(cru, AMnAXIATTR, amnaxiattr); in rzg2l_cru_initialize_axi()
195 static void rzg2l_cru_csi2_setup(struct rzg2l_cru_dev *cru, in rzg2l_cru_csi2_setup() argument
201 icnmc |= (rzg2l_cru_read(cru, ICnMC) & ~ICnMC_INF_MASK); in rzg2l_cru_csi2_setup()
206 rzg2l_cru_write(cru, ICnMC, icnmc); in rzg2l_cru_csi2_setup()
209 static int rzg2l_cru_initialize_image_conv(struct rzg2l_cru_dev *cru, in rzg2l_cru_initialize_image_conv() argument
217 rzg2l_cru_csi2_setup(cru, cru_ip_fmt, csi_vc); in rzg2l_cru_initialize_image_conv()
220 cru_video_fmt = rzg2l_cru_ip_format_to_fmt(cru->format.pixelformat); in rzg2l_cru_initialize_image_conv()
222 dev_err(cru->dev, "Invalid pixelformat (0x%x)\n", in rzg2l_cru_initialize_image_conv()
223 cru->format.pixelformat); in rzg2l_cru_initialize_image_conv()
229 rzg2l_cru_write(cru, ICnMC, in rzg2l_cru_initialize_image_conv()
230 rzg2l_cru_read(cru, ICnMC) | ICnMC_CSCTHR); in rzg2l_cru_initialize_image_conv()
232 rzg2l_cru_write(cru, ICnMC, in rzg2l_cru_initialize_image_conv()
233 rzg2l_cru_read(cru, ICnMC) & (~ICnMC_CSCTHR)); in rzg2l_cru_initialize_image_conv()
236 rzg2l_cru_write(cru, ICnDMR, cru_video_fmt->icndmr); in rzg2l_cru_initialize_image_conv()
241 void rzg2l_cru_stop_image_processing(struct rzg2l_cru_dev *cru) in rzg2l_cru_stop_image_processing() argument
248 spin_lock_irqsave(&cru->qlock, flags); in rzg2l_cru_stop_image_processing()
251 rzg2l_cru_write(cru, CRUnIE, 0); in rzg2l_cru_stop_image_processing()
252 rzg2l_cru_write(cru, CRUnINTS, 0x001F0F0F); in rzg2l_cru_stop_image_processing()
255 rzg2l_cru_write(cru, ICnEN, 0); in rzg2l_cru_stop_image_processing()
258 while ((rzg2l_cru_read(cru, ICnMS) & ICnMS_IA) && retries++ < RZG2L_RETRIES) { in rzg2l_cru_stop_image_processing()
259 spin_unlock_irqrestore(&cru->qlock, flags); in rzg2l_cru_stop_image_processing()
261 spin_lock_irqsave(&cru->qlock, flags); in rzg2l_cru_stop_image_processing()
264 icnms = rzg2l_cru_read(cru, ICnMS) & ICnMS_IA; in rzg2l_cru_stop_image_processing()
266 dev_err(cru->dev, "Failed stop HW, something is seriously broken\n"); in rzg2l_cru_stop_image_processing()
268 cru->state = RZG2L_CRU_DMA_STOPPED; in rzg2l_cru_stop_image_processing()
272 amnfifopntr = rzg2l_cru_read(cru, AMnFIFOPNTR); in rzg2l_cru_stop_image_processing()
285 dev_err(cru->dev, "Failed to empty FIFO\n"); in rzg2l_cru_stop_image_processing()
288 rzg2l_cru_write(cru, AMnAXISTP, AMnAXISTP_AXI_STOP); in rzg2l_cru_stop_image_processing()
292 if (rzg2l_cru_read(cru, AMnAXISTPACK) & in rzg2l_cru_stop_image_processing()
301 dev_err(cru->dev, "Failed to stop AXI bus\n"); in rzg2l_cru_stop_image_processing()
304 rzg2l_cru_write(cru, AMnAXISTP, 0); in rzg2l_cru_stop_image_processing()
306 /* Reset the CRU (AXI-master) */ in rzg2l_cru_stop_image_processing()
307 reset_control_assert(cru->aresetn); in rzg2l_cru_stop_image_processing()
310 rzg2l_cru_write(cru, CRUnRST, 0); in rzg2l_cru_stop_image_processing()
312 spin_unlock_irqrestore(&cru->qlock, flags); in rzg2l_cru_stop_image_processing()
315 static int rzg2l_cru_get_virtual_channel(struct rzg2l_cru_dev *cru) in rzg2l_cru_get_virtual_channel() argument
321 remote_pad = media_pad_remote_pad_unique(&cru->ip.pads[RZG2L_CRU_IP_SINK]); in rzg2l_cru_get_virtual_channel()
322 ret = v4l2_subdev_call(cru->ip.remote, pad, get_frame_desc, remote_pad->index, &fd); in rzg2l_cru_get_virtual_channel()
324 dev_err(cru->dev, "get_frame_desc failed on IP remote subdev\n"); in rzg2l_cru_get_virtual_channel()
332 dev_err(cru->dev, "get_frame_desc returned invalid bus type %d\n", fd.type); in rzg2l_cru_get_virtual_channel()
337 dev_err(cru->dev, "get_frame_desc returned zero entries\n"); in rzg2l_cru_get_virtual_channel()
344 int rzg2l_cru_start_image_processing(struct rzg2l_cru_dev *cru) in rzg2l_cru_start_image_processing() argument
346 struct v4l2_mbus_framefmt *fmt = rzg2l_cru_ip_get_src_fmt(cru); in rzg2l_cru_start_image_processing()
351 ret = rzg2l_cru_get_virtual_channel(cru); in rzg2l_cru_start_image_processing()
356 spin_lock_irqsave(&cru->qlock, flags); in rzg2l_cru_start_image_processing()
359 rzg2l_cru_write(cru, CRUnCTRL, CRUnCTRL_VINSEL(0)); in rzg2l_cru_start_image_processing()
362 rzg2l_cru_write(cru, CRUnRST, CRUnRST_VRESETN); in rzg2l_cru_start_image_processing()
365 rzg2l_cru_write(cru, CRUnIE, 0); in rzg2l_cru_start_image_processing()
366 rzg2l_cru_write(cru, CRUnINTS, 0x001f000f); in rzg2l_cru_start_image_processing()
369 rzg2l_cru_initialize_axi(cru); in rzg2l_cru_start_image_processing()
372 ret = rzg2l_cru_initialize_image_conv(cru, fmt, csi_vc); in rzg2l_cru_start_image_processing()
374 spin_unlock_irqrestore(&cru->qlock, flags); in rzg2l_cru_start_image_processing()
379 rzg2l_cru_write(cru, CRUnIE, CRUnIE_EFE); in rzg2l_cru_start_image_processing()
382 rzg2l_cru_write(cru, ICnEN, ICnEN_ICEN); in rzg2l_cru_start_image_processing()
384 spin_unlock_irqrestore(&cru->qlock, flags); in rzg2l_cru_start_image_processing()
389 static int rzg2l_cru_set_stream(struct rzg2l_cru_dev *cru, int on) in rzg2l_cru_set_stream() argument
396 pad = media_pad_remote_pad_first(&cru->pad); in rzg2l_cru_set_stream()
415 video_device_pipeline_stop(&cru->vdev); in rzg2l_cru_set_stream()
420 pipe = media_entity_pipeline(&sd->entity) ? : &cru->vdev.pipe; in rzg2l_cru_set_stream()
421 ret = video_device_pipeline_start(&cru->vdev, pipe); in rzg2l_cru_set_stream()
439 video_device_pipeline_stop(&cru->vdev); in rzg2l_cru_set_stream()
444 static void rzg2l_cru_stop_streaming(struct rzg2l_cru_dev *cru) in rzg2l_cru_stop_streaming() argument
446 cru->state = RZG2L_CRU_DMA_STOPPING; in rzg2l_cru_stop_streaming()
448 rzg2l_cru_set_stream(cru, 0); in rzg2l_cru_stop_streaming()
453 struct rzg2l_cru_dev *cru = data; in rzg2l_cru_irq() local
460 spin_lock_irqsave(&cru->qlock, flags); in rzg2l_cru_irq()
462 irq_status = rzg2l_cru_read(cru, CRUnINTS); in rzg2l_cru_irq()
468 rzg2l_cru_write(cru, CRUnINTS, rzg2l_cru_read(cru, CRUnINTS)); in rzg2l_cru_irq()
471 if (cru->state == RZG2L_CRU_DMA_STOPPED) { in rzg2l_cru_irq()
472 dev_dbg(cru->dev, "IRQ while state stopped\n"); in rzg2l_cru_irq()
477 if (cru->state == RZG2L_CRU_DMA_STOPPING) { in rzg2l_cru_irq()
479 dev_dbg(cru->dev, "IRQ while state stopping\n"); in rzg2l_cru_irq()
484 amnmbs = rzg2l_cru_read(cru, AMnMBS); in rzg2l_cru_irq()
492 slot = cru->num_buf - 1; in rzg2l_cru_irq()
500 if (cru->state == RZG2L_CRU_DMA_STARTING) { in rzg2l_cru_irq()
502 dev_dbg(cru->dev, "Starting sync slot: %d\n", slot); in rzg2l_cru_irq()
506 dev_dbg(cru->dev, "Capture start synced!\n"); in rzg2l_cru_irq()
507 cru->state = RZG2L_CRU_DMA_RUNNING; in rzg2l_cru_irq()
511 if (cru->queue_buf[slot]) { in rzg2l_cru_irq()
512 cru->queue_buf[slot]->field = cru->format.field; in rzg2l_cru_irq()
513 cru->queue_buf[slot]->sequence = cru->sequence; in rzg2l_cru_irq()
514 cru->queue_buf[slot]->vb2_buf.timestamp = ktime_get_ns(); in rzg2l_cru_irq()
515 vb2_buffer_done(&cru->queue_buf[slot]->vb2_buf, in rzg2l_cru_irq()
517 cru->queue_buf[slot] = NULL; in rzg2l_cru_irq()
520 dev_dbg(cru->dev, "Dropping frame %u\n", cru->sequence); in rzg2l_cru_irq()
523 cru->sequence++; in rzg2l_cru_irq()
526 rzg2l_cru_fill_hw_slot(cru, slot); in rzg2l_cru_irq()
529 spin_unlock_irqrestore(&cru->qlock, flags); in rzg2l_cru_irq()
536 struct rzg2l_cru_dev *cru = vb2_get_drv_priv(vq); in rzg2l_cru_start_streaming_vq() local
539 ret = pm_runtime_resume_and_get(cru->dev); in rzg2l_cru_start_streaming_vq()
543 ret = clk_prepare_enable(cru->vclk); in rzg2l_cru_start_streaming_vq()
548 ret = reset_control_deassert(cru->aresetn); in rzg2l_cru_start_streaming_vq()
550 dev_err(cru->dev, "failed to deassert aresetn\n"); in rzg2l_cru_start_streaming_vq()
554 ret = reset_control_deassert(cru->presetn); in rzg2l_cru_start_streaming_vq()
556 reset_control_assert(cru->aresetn); in rzg2l_cru_start_streaming_vq()
557 dev_err(cru->dev, "failed to deassert presetn\n"); in rzg2l_cru_start_streaming_vq()
562 cru->scratch = dma_alloc_coherent(cru->dev, cru->format.sizeimage, in rzg2l_cru_start_streaming_vq()
563 &cru->scratch_phys, GFP_KERNEL); in rzg2l_cru_start_streaming_vq()
564 if (!cru->scratch) { in rzg2l_cru_start_streaming_vq()
565 return_unused_buffers(cru, VB2_BUF_STATE_QUEUED); in rzg2l_cru_start_streaming_vq()
566 dev_err(cru->dev, "Failed to allocate scratch buffer\n"); in rzg2l_cru_start_streaming_vq()
571 cru->sequence = 0; in rzg2l_cru_start_streaming_vq()
573 ret = rzg2l_cru_set_stream(cru, 1); in rzg2l_cru_start_streaming_vq()
575 return_unused_buffers(cru, VB2_BUF_STATE_QUEUED); in rzg2l_cru_start_streaming_vq()
579 cru->state = RZG2L_CRU_DMA_STARTING; in rzg2l_cru_start_streaming_vq()
580 dev_dbg(cru->dev, "Starting to capture\n"); in rzg2l_cru_start_streaming_vq()
585 dma_free_coherent(cru->dev, cru->format.sizeimage, cru->scratch, in rzg2l_cru_start_streaming_vq()
586 cru->scratch_phys); in rzg2l_cru_start_streaming_vq()
588 reset_control_assert(cru->presetn); in rzg2l_cru_start_streaming_vq()
591 reset_control_assert(cru->aresetn); in rzg2l_cru_start_streaming_vq()
594 clk_disable_unprepare(cru->vclk); in rzg2l_cru_start_streaming_vq()
597 pm_runtime_put_sync(cru->dev); in rzg2l_cru_start_streaming_vq()
604 struct rzg2l_cru_dev *cru = vb2_get_drv_priv(vq); in rzg2l_cru_stop_streaming_vq() local
606 rzg2l_cru_stop_streaming(cru); in rzg2l_cru_stop_streaming_vq()
609 dma_free_coherent(cru->dev, cru->format.sizeimage, in rzg2l_cru_stop_streaming_vq()
610 cru->scratch, cru->scratch_phys); in rzg2l_cru_stop_streaming_vq()
612 return_unused_buffers(cru, VB2_BUF_STATE_ERROR); in rzg2l_cru_stop_streaming_vq()
614 reset_control_assert(cru->presetn); in rzg2l_cru_stop_streaming_vq()
615 clk_disable_unprepare(cru->vclk); in rzg2l_cru_stop_streaming_vq()
616 pm_runtime_put_sync(cru->dev); in rzg2l_cru_stop_streaming_vq()
627 void rzg2l_cru_dma_unregister(struct rzg2l_cru_dev *cru) in rzg2l_cru_dma_unregister() argument
629 mutex_destroy(&cru->lock); in rzg2l_cru_dma_unregister()
631 v4l2_device_unregister(&cru->v4l2_dev); in rzg2l_cru_dma_unregister()
632 vb2_queue_release(&cru->queue); in rzg2l_cru_dma_unregister()
635 int rzg2l_cru_dma_register(struct rzg2l_cru_dev *cru) in rzg2l_cru_dma_register() argument
637 struct vb2_queue *q = &cru->queue; in rzg2l_cru_dma_register()
642 ret = v4l2_device_register(cru->dev, &cru->v4l2_dev); in rzg2l_cru_dma_register()
646 mutex_init(&cru->lock); in rzg2l_cru_dma_register()
647 INIT_LIST_HEAD(&cru->buf_list); in rzg2l_cru_dma_register()
649 spin_lock_init(&cru->qlock); in rzg2l_cru_dma_register()
651 cru->state = RZG2L_CRU_DMA_STOPPED; in rzg2l_cru_dma_register()
654 cru->queue_buf[i] = NULL; in rzg2l_cru_dma_register()
659 q->lock = &cru->lock; in rzg2l_cru_dma_register()
660 q->drv_priv = cru; in rzg2l_cru_dma_register()
666 q->dev = cru->dev; in rzg2l_cru_dma_register()
670 dev_err(cru->dev, "failed to initialize VB2 queue\n"); in rzg2l_cru_dma_register()
677 mutex_destroy(&cru->lock); in rzg2l_cru_dma_register()
678 v4l2_device_unregister(&cru->v4l2_dev); in rzg2l_cru_dma_register()
686 static void rzg2l_cru_format_align(struct rzg2l_cru_dev *cru, in rzg2l_cru_format_align() argument
710 /* Limit to CRU capabilities */ in rzg2l_cru_format_align()
717 dev_dbg(cru->dev, "Format %ux%u bpl: %u size: %u\n", in rzg2l_cru_format_align()
721 static void rzg2l_cru_try_format(struct rzg2l_cru_dev *cru, in rzg2l_cru_try_format() argument
736 rzg2l_cru_format_align(cru, pix); in rzg2l_cru_try_format()
751 struct rzg2l_cru_dev *cru = video_drvdata(file); in rzg2l_cru_try_fmt_vid_cap() local
753 rzg2l_cru_try_format(cru, &f->fmt.pix); in rzg2l_cru_try_fmt_vid_cap()
761 struct rzg2l_cru_dev *cru = video_drvdata(file); in rzg2l_cru_s_fmt_vid_cap() local
763 if (vb2_is_busy(&cru->queue)) in rzg2l_cru_s_fmt_vid_cap()
766 rzg2l_cru_try_format(cru, &f->fmt.pix); in rzg2l_cru_s_fmt_vid_cap()
768 cru->format = f->fmt.pix; in rzg2l_cru_s_fmt_vid_cap()
776 struct rzg2l_cru_dev *cru = video_drvdata(file); in rzg2l_cru_g_fmt_vid_cap() local
778 f->fmt.pix = cru->format; in rzg2l_cru_g_fmt_vid_cap()
821 struct rzg2l_cru_dev *cru = video_drvdata(file); in rzg2l_cru_open() local
824 ret = mutex_lock_interruptible(&cru->lock); in rzg2l_cru_open()
828 file->private_data = cru; in rzg2l_cru_open()
833 mutex_unlock(&cru->lock); in rzg2l_cru_open()
838 mutex_unlock(&cru->lock); in rzg2l_cru_open()
845 struct rzg2l_cru_dev *cru = video_drvdata(file); in rzg2l_cru_release() local
848 mutex_lock(&cru->lock); in rzg2l_cru_release()
853 mutex_unlock(&cru->lock); in rzg2l_cru_release()
879 struct rzg2l_cru_dev *cru; in rzg2l_cru_video_link_validate() local
888 cru = container_of(media_entity_to_video_device(link->sink->entity), in rzg2l_cru_video_link_validate()
890 video_fmt = rzg2l_cru_ip_format_to_fmt(cru->format.pixelformat); in rzg2l_cru_video_link_validate()
892 if (fmt.format.width != cru->format.width || in rzg2l_cru_video_link_validate()
893 fmt.format.height != cru->format.height || in rzg2l_cru_video_link_validate()
894 fmt.format.field != cru->format.field || in rzg2l_cru_video_link_validate()
905 static void rzg2l_cru_v4l2_init(struct rzg2l_cru_dev *cru) in rzg2l_cru_v4l2_init() argument
907 struct video_device *vdev = &cru->vdev; in rzg2l_cru_v4l2_init()
909 vdev->v4l2_dev = &cru->v4l2_dev; in rzg2l_cru_v4l2_init()
910 vdev->queue = &cru->queue; in rzg2l_cru_v4l2_init()
911 snprintf(vdev->name, sizeof(vdev->name), "CRU output"); in rzg2l_cru_v4l2_init()
913 vdev->lock = &cru->lock; in rzg2l_cru_v4l2_init()
921 cru->format.pixelformat = RZG2L_CRU_DEFAULT_FORMAT; in rzg2l_cru_v4l2_init()
922 cru->format.width = RZG2L_CRU_DEFAULT_WIDTH; in rzg2l_cru_v4l2_init()
923 cru->format.height = RZG2L_CRU_DEFAULT_HEIGHT; in rzg2l_cru_v4l2_init()
924 cru->format.field = RZG2L_CRU_DEFAULT_FIELD; in rzg2l_cru_v4l2_init()
925 cru->format.colorspace = RZG2L_CRU_DEFAULT_COLORSPACE; in rzg2l_cru_v4l2_init()
926 rzg2l_cru_format_align(cru, &cru->format); in rzg2l_cru_v4l2_init()
929 void rzg2l_cru_video_unregister(struct rzg2l_cru_dev *cru) in rzg2l_cru_video_unregister() argument
931 media_device_unregister(&cru->mdev); in rzg2l_cru_video_unregister()
932 video_unregister_device(&cru->vdev); in rzg2l_cru_video_unregister()
935 int rzg2l_cru_video_register(struct rzg2l_cru_dev *cru) in rzg2l_cru_video_register() argument
937 struct video_device *vdev = &cru->vdev; in rzg2l_cru_video_register()
940 if (video_is_registered(&cru->vdev)) { in rzg2l_cru_video_register()
943 entity = &cru->vdev.entity; in rzg2l_cru_video_register()
945 entity->graph_obj.mdev = &cru->mdev; in rzg2l_cru_video_register()
949 rzg2l_cru_v4l2_init(cru); in rzg2l_cru_video_register()
950 video_set_drvdata(vdev, cru); in rzg2l_cru_video_register()
953 dev_err(cru->dev, "Failed to register video device\n"); in rzg2l_cru_video_register()
957 ret = media_device_register(&cru->mdev); in rzg2l_cru_video_register()
959 video_unregister_device(&cru->vdev); in rzg2l_cru_video_register()