hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/media/platform/stm32/stm32-dcmi.c
....@@ -97,11 +97,13 @@
9797
9898 #define TIMEOUT_MS 1000
9999
100
-struct dcmi_graph_entity {
101
- struct device_node *node;
100
+#define OVERRUN_ERROR_THRESHOLD 3
102101
102
+struct dcmi_graph_entity {
103103 struct v4l2_async_subdev asd;
104
- struct v4l2_subdev *subdev;
104
+
105
+ struct device_node *remote_node;
106
+ struct v4l2_subdev *source;
105107 };
106108
107109 struct dcmi_format {
....@@ -133,6 +135,7 @@
133135 int sequence;
134136 struct list_head buffers;
135137 struct dcmi_buf *active;
138
+ int irq;
136139
137140 struct v4l2_device v4l2_dev;
138141 struct video_device *vdev;
....@@ -167,6 +170,10 @@
167170
168171 /* Ensure DMA operations atomicity */
169172 struct mutex dma_lock;
173
+
174
+ struct media_device mdev;
175
+ struct media_pad vid_cap_pad;
176
+ struct media_pipeline pipeline;
170177 };
171178
172179 static inline struct stm32_dcmi *notifier_to_dcmi(struct v4l2_async_notifier *n)
....@@ -446,11 +453,13 @@
446453
447454 spin_lock_irq(&dcmi->irqlock);
448455
449
- if ((dcmi->misr & IT_OVR) || (dcmi->misr & IT_ERR)) {
450
- dcmi->errors_count++;
451
- if (dcmi->misr & IT_OVR)
452
- dcmi->overrun_count++;
456
+ if (dcmi->misr & IT_OVR) {
457
+ dcmi->overrun_count++;
458
+ if (dcmi->overrun_count > OVERRUN_ERROR_THRESHOLD)
459
+ dcmi->errors_count++;
453460 }
461
+ if (dcmi->misr & IT_ERR)
462
+ dcmi->errors_count++;
454463
455464 if (dcmi->sd_format->fourcc == V4L2_PIX_FMT_JPEG &&
456465 dcmi->misr & IT_FRAME) {
....@@ -576,6 +585,144 @@
576585 spin_unlock_irq(&dcmi->irqlock);
577586 }
578587
588
+static struct media_entity *dcmi_find_source(struct stm32_dcmi *dcmi)
589
+{
590
+ struct media_entity *entity = &dcmi->vdev->entity;
591
+ struct media_pad *pad;
592
+
593
+ /* Walk searching for entity having no sink */
594
+ while (1) {
595
+ pad = &entity->pads[0];
596
+ if (!(pad->flags & MEDIA_PAD_FL_SINK))
597
+ break;
598
+
599
+ pad = media_entity_remote_pad(pad);
600
+ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
601
+ break;
602
+
603
+ entity = pad->entity;
604
+ }
605
+
606
+ return entity;
607
+}
608
+
609
+static int dcmi_pipeline_s_fmt(struct stm32_dcmi *dcmi,
610
+ struct v4l2_subdev_pad_config *pad_cfg,
611
+ struct v4l2_subdev_format *format)
612
+{
613
+ struct media_entity *entity = &dcmi->entity.source->entity;
614
+ struct v4l2_subdev *subdev;
615
+ struct media_pad *sink_pad = NULL;
616
+ struct media_pad *src_pad = NULL;
617
+ struct media_pad *pad = NULL;
618
+ struct v4l2_subdev_format fmt = *format;
619
+ bool found = false;
620
+ int ret;
621
+
622
+ /*
623
+ * Starting from sensor subdevice, walk within
624
+ * pipeline and set format on each subdevice
625
+ */
626
+ while (1) {
627
+ unsigned int i;
628
+
629
+ /* Search if current entity has a source pad */
630
+ for (i = 0; i < entity->num_pads; i++) {
631
+ pad = &entity->pads[i];
632
+ if (pad->flags & MEDIA_PAD_FL_SOURCE) {
633
+ src_pad = pad;
634
+ found = true;
635
+ break;
636
+ }
637
+ }
638
+ if (!found)
639
+ break;
640
+
641
+ subdev = media_entity_to_v4l2_subdev(entity);
642
+
643
+ /* Propagate format on sink pad if any, otherwise source pad */
644
+ if (sink_pad)
645
+ pad = sink_pad;
646
+
647
+ dev_dbg(dcmi->dev, "\"%s\":%d pad format set to 0x%x %ux%u\n",
648
+ subdev->name, pad->index, format->format.code,
649
+ format->format.width, format->format.height);
650
+
651
+ fmt.pad = pad->index;
652
+ ret = v4l2_subdev_call(subdev, pad, set_fmt, pad_cfg, &fmt);
653
+ if (ret < 0) {
654
+ dev_err(dcmi->dev, "%s: Failed to set format 0x%x %ux%u on \"%s\":%d pad (%d)\n",
655
+ __func__, format->format.code,
656
+ format->format.width, format->format.height,
657
+ subdev->name, pad->index, ret);
658
+ return ret;
659
+ }
660
+
661
+ if (fmt.format.code != format->format.code ||
662
+ fmt.format.width != format->format.width ||
663
+ fmt.format.height != format->format.height) {
664
+ dev_dbg(dcmi->dev, "\"%s\":%d pad format has been changed to 0x%x %ux%u\n",
665
+ subdev->name, pad->index, fmt.format.code,
666
+ fmt.format.width, fmt.format.height);
667
+ }
668
+
669
+ /* Walk to next entity */
670
+ sink_pad = media_entity_remote_pad(src_pad);
671
+ if (!sink_pad || !is_media_entity_v4l2_subdev(sink_pad->entity))
672
+ break;
673
+
674
+ entity = sink_pad->entity;
675
+ }
676
+ *format = fmt;
677
+
678
+ return 0;
679
+}
680
+
681
+static int dcmi_pipeline_s_stream(struct stm32_dcmi *dcmi, int state)
682
+{
683
+ struct media_entity *entity = &dcmi->vdev->entity;
684
+ struct v4l2_subdev *subdev;
685
+ struct media_pad *pad;
686
+ int ret;
687
+
688
+ /* Start/stop all entities within pipeline */
689
+ while (1) {
690
+ pad = &entity->pads[0];
691
+ if (!(pad->flags & MEDIA_PAD_FL_SINK))
692
+ break;
693
+
694
+ pad = media_entity_remote_pad(pad);
695
+ if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
696
+ break;
697
+
698
+ entity = pad->entity;
699
+ subdev = media_entity_to_v4l2_subdev(entity);
700
+
701
+ ret = v4l2_subdev_call(subdev, video, s_stream, state);
702
+ if (ret < 0 && ret != -ENOIOCTLCMD) {
703
+ dev_err(dcmi->dev, "%s: \"%s\" failed to %s streaming (%d)\n",
704
+ __func__, subdev->name,
705
+ state ? "start" : "stop", ret);
706
+ return ret;
707
+ }
708
+
709
+ dev_dbg(dcmi->dev, "\"%s\" is %s\n",
710
+ subdev->name, state ? "started" : "stopped");
711
+ }
712
+
713
+ return 0;
714
+}
715
+
716
+static int dcmi_pipeline_start(struct stm32_dcmi *dcmi)
717
+{
718
+ return dcmi_pipeline_s_stream(dcmi, 1);
719
+}
720
+
721
+static void dcmi_pipeline_stop(struct stm32_dcmi *dcmi)
722
+{
723
+ dcmi_pipeline_s_stream(dcmi, 0);
724
+}
725
+
579726 static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count)
580727 {
581728 struct stm32_dcmi *dcmi = vb2_get_drv_priv(vq);
....@@ -590,13 +737,16 @@
590737 goto err_pm_put;
591738 }
592739
593
- /* Enable stream on the sub device */
594
- ret = v4l2_subdev_call(dcmi->entity.subdev, video, s_stream, 1);
595
- if (ret && ret != -ENOIOCTLCMD) {
596
- dev_err(dcmi->dev, "%s: Failed to start streaming, subdev streamon error",
597
- __func__);
740
+ ret = media_pipeline_start(&dcmi->vdev->entity, &dcmi->pipeline);
741
+ if (ret < 0) {
742
+ dev_err(dcmi->dev, "%s: Failed to start streaming, media pipeline start error (%d)\n",
743
+ __func__, ret);
598744 goto err_pm_put;
599745 }
746
+
747
+ ret = dcmi_pipeline_start(dcmi);
748
+ if (ret)
749
+ goto err_media_pipeline_stop;
600750
601751 spin_lock_irq(&dcmi->irqlock);
602752
....@@ -669,16 +819,22 @@
669819 if (ret) {
670820 dev_err(dcmi->dev, "%s: Start streaming failed, cannot start capture\n",
671821 __func__);
672
- goto err_subdev_streamoff;
822
+ goto err_pipeline_stop;
673823 }
674824
675825 /* Enable interruptions */
676
- reg_set(dcmi->regs, DCMI_IER, IT_FRAME | IT_OVR | IT_ERR);
826
+ if (dcmi->sd_format->fourcc == V4L2_PIX_FMT_JPEG)
827
+ reg_set(dcmi->regs, DCMI_IER, IT_FRAME | IT_OVR | IT_ERR);
828
+ else
829
+ reg_set(dcmi->regs, DCMI_IER, IT_OVR | IT_ERR);
677830
678831 return 0;
679832
680
-err_subdev_streamoff:
681
- v4l2_subdev_call(dcmi->entity.subdev, video, s_stream, 0);
833
+err_pipeline_stop:
834
+ dcmi_pipeline_stop(dcmi);
835
+
836
+err_media_pipeline_stop:
837
+ media_pipeline_stop(&dcmi->vdev->entity);
682838
683839 err_pm_put:
684840 pm_runtime_put(dcmi->dev);
....@@ -701,13 +857,10 @@
701857 {
702858 struct stm32_dcmi *dcmi = vb2_get_drv_priv(vq);
703859 struct dcmi_buf *buf, *node;
704
- int ret;
705860
706
- /* Disable stream on the sub device */
707
- ret = v4l2_subdev_call(dcmi->entity.subdev, video, s_stream, 0);
708
- if (ret && ret != -ENOIOCTLCMD)
709
- dev_err(dcmi->dev, "%s: Failed to stop streaming, subdev streamoff error (%d)\n",
710
- __func__, ret);
861
+ dcmi_pipeline_stop(dcmi);
862
+
863
+ media_pipeline_stop(&dcmi->vdev->entity);
711864
712865 spin_lock_irq(&dcmi->irqlock);
713866
....@@ -848,7 +1001,7 @@
8481001 }
8491002
8501003 v4l2_fill_mbus_format(&format.format, pix, sd_fmt->mbus_code);
851
- ret = v4l2_subdev_call(dcmi->entity.subdev, pad, set_fmt,
1004
+ ret = v4l2_subdev_call(dcmi->entity.source, pad, set_fmt,
8521005 &pad_cfg, &format);
8531006 if (ret < 0)
8541007 return ret;
....@@ -925,8 +1078,7 @@
9251078 mf->width = sd_framesize.width;
9261079 mf->height = sd_framesize.height;
9271080
928
- ret = v4l2_subdev_call(dcmi->entity.subdev, pad,
929
- set_fmt, NULL, &format);
1081
+ ret = dcmi_pipeline_s_fmt(dcmi, NULL, &format);
9301082 if (ret < 0)
9311083 return ret;
9321084
....@@ -982,7 +1134,7 @@
9821134 };
9831135 int ret;
9841136
985
- ret = v4l2_subdev_call(dcmi->entity.subdev, pad, get_fmt, NULL, &fmt);
1137
+ ret = v4l2_subdev_call(dcmi->entity.source, pad, get_fmt, NULL, &fmt);
9861138 if (ret)
9871139 return ret;
9881140
....@@ -1011,7 +1163,7 @@
10111163 }
10121164
10131165 v4l2_fill_mbus_format(&format.format, pix, sd_fmt->mbus_code);
1014
- ret = v4l2_subdev_call(dcmi->entity.subdev, pad, set_fmt,
1166
+ ret = v4l2_subdev_call(dcmi->entity.source, pad, set_fmt,
10151167 &pad_cfg, &format);
10161168 if (ret < 0)
10171169 return ret;
....@@ -1034,7 +1186,7 @@
10341186 /*
10351187 * Get sensor bounds first
10361188 */
1037
- ret = v4l2_subdev_call(dcmi->entity.subdev, pad, get_selection,
1189
+ ret = v4l2_subdev_call(dcmi->entity.source, pad, get_selection,
10381190 NULL, &bounds);
10391191 if (!ret)
10401192 *r = bounds.r;
....@@ -1167,10 +1319,10 @@
11671319 static int dcmi_querycap(struct file *file, void *priv,
11681320 struct v4l2_capability *cap)
11691321 {
1170
- strlcpy(cap->driver, DRV_NAME, sizeof(cap->driver));
1171
- strlcpy(cap->card, "STM32 Camera Memory Interface",
1322
+ strscpy(cap->driver, DRV_NAME, sizeof(cap->driver));
1323
+ strscpy(cap->card, "STM32 Camera Memory Interface",
11721324 sizeof(cap->card));
1173
- strlcpy(cap->bus_info, "platform:dcmi", sizeof(cap->bus_info));
1325
+ strscpy(cap->bus_info, "platform:dcmi", sizeof(cap->bus_info));
11741326 return 0;
11751327 }
11761328
....@@ -1181,7 +1333,7 @@
11811333 return -EINVAL;
11821334
11831335 i->type = V4L2_INPUT_TYPE_CAMERA;
1184
- strlcpy(i->name, "Camera", sizeof(i->name));
1336
+ strscpy(i->name, "Camera", sizeof(i->name));
11851337 return 0;
11861338 }
11871339
....@@ -1215,7 +1367,7 @@
12151367
12161368 fse.code = sd_fmt->mbus_code;
12171369
1218
- ret = v4l2_subdev_call(dcmi->entity.subdev, pad, enum_frame_size,
1370
+ ret = v4l2_subdev_call(dcmi->entity.source, pad, enum_frame_size,
12191371 NULL, &fse);
12201372 if (ret)
12211373 return ret;
....@@ -1232,7 +1384,7 @@
12321384 {
12331385 struct stm32_dcmi *dcmi = video_drvdata(file);
12341386
1235
- return v4l2_g_parm_cap(video_devdata(file), dcmi->entity.subdev, p);
1387
+ return v4l2_g_parm_cap(video_devdata(file), dcmi->entity.source, p);
12361388 }
12371389
12381390 static int dcmi_s_parm(struct file *file, void *priv,
....@@ -1240,7 +1392,7 @@
12401392 {
12411393 struct stm32_dcmi *dcmi = video_drvdata(file);
12421394
1243
- return v4l2_s_parm_cap(video_devdata(file), dcmi->entity.subdev, p);
1395
+ return v4l2_s_parm_cap(video_devdata(file), dcmi->entity.source, p);
12441396 }
12451397
12461398 static int dcmi_enum_frameintervals(struct file *file, void *fh,
....@@ -1262,7 +1414,7 @@
12621414
12631415 fie.code = sd_fmt->mbus_code;
12641416
1265
- ret = v4l2_subdev_call(dcmi->entity.subdev, pad,
1417
+ ret = v4l2_subdev_call(dcmi->entity.source, pad,
12661418 enum_frame_interval, NULL, &fie);
12671419 if (ret)
12681420 return ret;
....@@ -1282,7 +1434,7 @@
12821434 static int dcmi_open(struct file *file)
12831435 {
12841436 struct stm32_dcmi *dcmi = video_drvdata(file);
1285
- struct v4l2_subdev *sd = dcmi->entity.subdev;
1437
+ struct v4l2_subdev *sd = dcmi->entity.source;
12861438 int ret;
12871439
12881440 if (mutex_lock_interruptible(&dcmi->lock))
....@@ -1313,7 +1465,7 @@
13131465 static int dcmi_release(struct file *file)
13141466 {
13151467 struct stm32_dcmi *dcmi = video_drvdata(file);
1316
- struct v4l2_subdev *sd = dcmi->entity.subdev;
1468
+ struct v4l2_subdev *sd = dcmi->entity.source;
13171469 bool fh_singular;
13181470 int ret;
13191471
....@@ -1400,6 +1552,12 @@
14001552 return 0;
14011553 }
14021554
1555
+/*
1556
+ * FIXME: For the time being we only support subdevices
1557
+ * which expose RGB & YUV "parallel form" mbus code (_2X8).
1558
+ * Nevertheless, this allows to support serial source subdevices
1559
+ * and serial to parallel bridges which conform to this.
1560
+ */
14031561 static const struct dcmi_format dcmi_formats[] = {
14041562 {
14051563 .fourcc = V4L2_PIX_FMT_RGB565,
....@@ -1424,7 +1582,7 @@
14241582 {
14251583 const struct dcmi_format *sd_fmts[ARRAY_SIZE(dcmi_formats)];
14261584 unsigned int num_fmts = 0, i, j;
1427
- struct v4l2_subdev *subdev = dcmi->entity.subdev;
1585
+ struct v4l2_subdev *subdev = dcmi->entity.source;
14281586 struct v4l2_subdev_mbus_code_enum mbus_code = {
14291587 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
14301588 };
....@@ -1438,12 +1596,20 @@
14381596 /* Code supported, have we got this fourcc yet? */
14391597 for (j = 0; j < num_fmts; j++)
14401598 if (sd_fmts[j]->fourcc ==
1441
- dcmi_formats[i].fourcc)
1599
+ dcmi_formats[i].fourcc) {
14421600 /* Already available */
1601
+ dev_dbg(dcmi->dev, "Skipping fourcc/code: %4.4s/0x%x\n",
1602
+ (char *)&sd_fmts[j]->fourcc,
1603
+ mbus_code.code);
14431604 break;
1444
- if (j == num_fmts)
1605
+ }
1606
+ if (j == num_fmts) {
14451607 /* New */
14461608 sd_fmts[num_fmts++] = dcmi_formats + i;
1609
+ dev_dbg(dcmi->dev, "Supported fourcc/code: %4.4s/0x%x\n",
1610
+ (char *)&sd_fmts[num_fmts - 1]->fourcc,
1611
+ sd_fmts[num_fmts - 1]->mbus_code);
1612
+ }
14471613 }
14481614 mbus_code.index++;
14491615 }
....@@ -1470,7 +1636,7 @@
14701636 static int dcmi_framesizes_init(struct stm32_dcmi *dcmi)
14711637 {
14721638 unsigned int num_fsize = 0;
1473
- struct v4l2_subdev *subdev = dcmi->entity.subdev;
1639
+ struct v4l2_subdev *subdev = dcmi->entity.source;
14741640 struct v4l2_subdev_frame_size_enum fse = {
14751641 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
14761642 .code = dcmi->sd_format->mbus_code,
....@@ -1517,7 +1683,20 @@
15171683 struct stm32_dcmi *dcmi = notifier_to_dcmi(notifier);
15181684 int ret;
15191685
1520
- dcmi->vdev->ctrl_handler = dcmi->entity.subdev->ctrl_handler;
1686
+ /*
1687
+ * Now that the graph is complete,
1688
+ * we search for the source subdevice
1689
+ * in order to expose it through V4L2 interface
1690
+ */
1691
+ dcmi->entity.source =
1692
+ media_entity_to_v4l2_subdev(dcmi_find_source(dcmi));
1693
+ if (!dcmi->entity.source) {
1694
+ dev_err(dcmi->dev, "Source subdevice not found\n");
1695
+ return -ENODEV;
1696
+ }
1697
+
1698
+ dcmi->vdev->ctrl_handler = dcmi->entity.source->ctrl_handler;
1699
+
15211700 ret = dcmi_formats_init(dcmi);
15221701 if (ret) {
15231702 dev_err(dcmi->dev, "No supported mediabus format found\n");
....@@ -1542,14 +1721,14 @@
15421721 return ret;
15431722 }
15441723
1545
- ret = video_register_device(dcmi->vdev, VFL_TYPE_GRABBER, -1);
1724
+ ret = devm_request_threaded_irq(dcmi->dev, dcmi->irq, dcmi_irq_callback,
1725
+ dcmi_irq_thread, IRQF_ONESHOT,
1726
+ dev_name(dcmi->dev), dcmi);
15461727 if (ret) {
1547
- dev_err(dcmi->dev, "Failed to register video device\n");
1728
+ dev_err(dcmi->dev, "Unable to request irq %d\n", dcmi->irq);
15481729 return ret;
15491730 }
15501731
1551
- dev_dbg(dcmi->dev, "Device registered as %s\n",
1552
- video_device_node_name(dcmi->vdev));
15531732 return 0;
15541733 }
15551734
....@@ -1561,7 +1740,7 @@
15611740
15621741 dev_dbg(dcmi->dev, "Removing %s\n", video_device_node_name(dcmi->vdev));
15631742
1564
- /* Checks internaly if vdev has been init or not */
1743
+ /* Checks internally if vdev has been init or not */
15651744 video_unregister_device(dcmi->vdev);
15661745 }
15671746
....@@ -1570,12 +1749,31 @@
15701749 struct v4l2_async_subdev *asd)
15711750 {
15721751 struct stm32_dcmi *dcmi = notifier_to_dcmi(notifier);
1752
+ unsigned int ret;
1753
+ int src_pad;
15731754
1574
- dev_dbg(dcmi->dev, "Subdev %s bound\n", subdev->name);
1755
+ dev_dbg(dcmi->dev, "Subdev \"%s\" bound\n", subdev->name);
15751756
1576
- dcmi->entity.subdev = subdev;
1757
+ /*
1758
+ * Link this sub-device to DCMI, it could be
1759
+ * a parallel camera sensor or a bridge
1760
+ */
1761
+ src_pad = media_entity_get_fwnode_pad(&subdev->entity,
1762
+ subdev->fwnode,
1763
+ MEDIA_PAD_FL_SOURCE);
15771764
1578
- return 0;
1765
+ ret = media_create_pad_link(&subdev->entity, src_pad,
1766
+ &dcmi->vdev->entity, 0,
1767
+ MEDIA_LNK_FL_IMMUTABLE |
1768
+ MEDIA_LNK_FL_ENABLED);
1769
+ if (ret)
1770
+ dev_err(dcmi->dev, "Failed to create media pad link with subdev \"%s\"\n",
1771
+ subdev->name);
1772
+ else
1773
+ dev_dbg(dcmi->dev, "DCMI is now linked to \"%s\"\n",
1774
+ subdev->name);
1775
+
1776
+ return ret;
15791777 }
15801778
15811779 static const struct v4l2_async_notifier_operations dcmi_graph_notify_ops = {
....@@ -1599,7 +1797,7 @@
15991797 return -EINVAL;
16001798
16011799 /* Remote node to connect */
1602
- dcmi->entity.node = remote;
1800
+ dcmi->entity.remote_node = remote;
16031801 dcmi->entity.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
16041802 dcmi->entity.asd.match.fwnode = of_fwnode_handle(remote);
16051803 return 0;
....@@ -1607,33 +1805,31 @@
16071805
16081806 static int dcmi_graph_init(struct stm32_dcmi *dcmi)
16091807 {
1610
- struct v4l2_async_subdev **subdevs = NULL;
16111808 int ret;
16121809
16131810 /* Parse the graph to extract a list of subdevice DT nodes. */
16141811 ret = dcmi_graph_parse(dcmi, dcmi->dev->of_node);
16151812 if (ret < 0) {
1616
- dev_err(dcmi->dev, "Graph parsing failed\n");
1813
+ dev_err(dcmi->dev, "Failed to parse graph\n");
16171814 return ret;
16181815 }
16191816
1620
- /* Register the subdevices notifier. */
1621
- subdevs = devm_kzalloc(dcmi->dev, sizeof(*subdevs), GFP_KERNEL);
1622
- if (!subdevs) {
1623
- of_node_put(dcmi->entity.node);
1624
- return -ENOMEM;
1817
+ v4l2_async_notifier_init(&dcmi->notifier);
1818
+
1819
+ ret = v4l2_async_notifier_add_subdev(&dcmi->notifier,
1820
+ &dcmi->entity.asd);
1821
+ if (ret) {
1822
+ dev_err(dcmi->dev, "Failed to add subdev notifier\n");
1823
+ of_node_put(dcmi->entity.remote_node);
1824
+ return ret;
16251825 }
16261826
1627
- subdevs[0] = &dcmi->entity.asd;
1628
-
1629
- dcmi->notifier.subdevs = subdevs;
1630
- dcmi->notifier.num_subdevs = 1;
16311827 dcmi->notifier.ops = &dcmi_graph_notify_ops;
16321828
16331829 ret = v4l2_async_notifier_register(&dcmi->v4l2_dev, &dcmi->notifier);
16341830 if (ret < 0) {
1635
- dev_err(dcmi->dev, "Notifier registration failed\n");
1636
- of_node_put(dcmi->entity.node);
1831
+ dev_err(dcmi->dev, "Failed to register notifier\n");
1832
+ v4l2_async_notifier_cleanup(&dcmi->notifier);
16371833 return ret;
16381834 }
16391835
....@@ -1644,7 +1840,7 @@
16441840 {
16451841 struct device_node *np = pdev->dev.of_node;
16461842 const struct of_device_id *match = NULL;
1647
- struct v4l2_fwnode_endpoint ep;
1843
+ struct v4l2_fwnode_endpoint ep = { .bus_type = 0 };
16481844 struct stm32_dcmi *dcmi;
16491845 struct vb2_queue *q;
16501846 struct dma_chan *chan;
....@@ -1672,7 +1868,6 @@
16721868 np = of_graph_get_next_endpoint(np, NULL);
16731869 if (!np) {
16741870 dev_err(&pdev->dev, "Could not find the endpoint\n");
1675
- of_node_put(np);
16761871 return -ENODEV;
16771872 }
16781873
....@@ -1683,7 +1878,7 @@
16831878 return ret;
16841879 }
16851880
1686
- if (ep.bus_type == V4L2_MBUS_CSI2) {
1881
+ if (ep.bus_type == V4L2_MBUS_CSI2_DPHY) {
16871882 dev_err(&pdev->dev, "CSI bus not supported\n");
16881883 return -ENODEV;
16891884 }
....@@ -1692,11 +1887,10 @@
16921887 dcmi->bus.data_shift = ep.bus.parallel.data_shift;
16931888
16941889 irq = platform_get_irq(pdev, 0);
1695
- if (irq <= 0) {
1696
- if (irq != -EPROBE_DEFER)
1697
- dev_err(&pdev->dev, "Could not get irq\n");
1890
+ if (irq <= 0)
16981891 return irq ? irq : -ENXIO;
1699
- }
1892
+
1893
+ dcmi->irq = irq;
17001894
17011895 dcmi->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
17021896 if (!dcmi->res) {
....@@ -1710,14 +1904,6 @@
17101904 return PTR_ERR(dcmi->regs);
17111905 }
17121906
1713
- ret = devm_request_threaded_irq(&pdev->dev, irq, dcmi_irq_callback,
1714
- dcmi_irq_thread, IRQF_ONESHOT,
1715
- dev_name(&pdev->dev), dcmi);
1716
- if (ret) {
1717
- dev_err(&pdev->dev, "Unable to request irq %d\n", irq);
1718
- return ret;
1719
- }
1720
-
17211907 mclk = devm_clk_get(&pdev->dev, "mclk");
17221908 if (IS_ERR(mclk)) {
17231909 if (PTR_ERR(mclk) != -EPROBE_DEFER)
....@@ -1725,10 +1911,13 @@
17251911 return PTR_ERR(mclk);
17261912 }
17271913
1728
- chan = dma_request_slave_channel(&pdev->dev, "tx");
1729
- if (!chan) {
1730
- dev_info(&pdev->dev, "Unable to request DMA channel, defer probing\n");
1731
- return -EPROBE_DEFER;
1914
+ chan = dma_request_chan(&pdev->dev, "tx");
1915
+ if (IS_ERR(chan)) {
1916
+ ret = PTR_ERR(chan);
1917
+ if (ret != -EPROBE_DEFER)
1918
+ dev_err(&pdev->dev,
1919
+ "Failed to request DMA channel: %d\n", ret);
1920
+ return ret;
17321921 }
17331922
17341923 spin_lock_init(&dcmi->irqlock);
....@@ -1744,10 +1933,19 @@
17441933
17451934 q = &dcmi->queue;
17461935
1936
+ dcmi->v4l2_dev.mdev = &dcmi->mdev;
1937
+
1938
+ /* Initialize media device */
1939
+ strscpy(dcmi->mdev.model, DRV_NAME, sizeof(dcmi->mdev.model));
1940
+ snprintf(dcmi->mdev.bus_info, sizeof(dcmi->mdev.bus_info),
1941
+ "platform:%s", DRV_NAME);
1942
+ dcmi->mdev.dev = &pdev->dev;
1943
+ media_device_init(&dcmi->mdev);
1944
+
17471945 /* Initialize the top-level structure */
17481946 ret = v4l2_device_register(&pdev->dev, &dcmi->v4l2_dev);
17491947 if (ret)
1750
- goto err_dma_release;
1948
+ goto err_media_device_cleanup;
17511949
17521950 dcmi->vdev = video_device_alloc();
17531951 if (!dcmi->vdev) {
....@@ -1759,13 +1957,32 @@
17591957 dcmi->vdev->fops = &dcmi_fops;
17601958 dcmi->vdev->v4l2_dev = &dcmi->v4l2_dev;
17611959 dcmi->vdev->queue = &dcmi->queue;
1762
- strlcpy(dcmi->vdev->name, KBUILD_MODNAME, sizeof(dcmi->vdev->name));
1960
+ strscpy(dcmi->vdev->name, KBUILD_MODNAME, sizeof(dcmi->vdev->name));
17631961 dcmi->vdev->release = video_device_release;
17641962 dcmi->vdev->ioctl_ops = &dcmi_ioctl_ops;
17651963 dcmi->vdev->lock = &dcmi->lock;
17661964 dcmi->vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
17671965 V4L2_CAP_READWRITE;
17681966 video_set_drvdata(dcmi->vdev, dcmi);
1967
+
1968
+ /* Media entity pads */
1969
+ dcmi->vid_cap_pad.flags = MEDIA_PAD_FL_SINK;
1970
+ ret = media_entity_pads_init(&dcmi->vdev->entity,
1971
+ 1, &dcmi->vid_cap_pad);
1972
+ if (ret) {
1973
+ dev_err(dcmi->dev, "Failed to init media entity pad\n");
1974
+ goto err_device_release;
1975
+ }
1976
+ dcmi->vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT;
1977
+
1978
+ ret = video_register_device(dcmi->vdev, VFL_TYPE_VIDEO, -1);
1979
+ if (ret) {
1980
+ dev_err(dcmi->dev, "Failed to register video device\n");
1981
+ goto err_media_entity_cleanup;
1982
+ }
1983
+
1984
+ dev_dbg(dcmi->dev, "Device registered as %s\n",
1985
+ video_device_node_name(dcmi->vdev));
17691986
17701987 /* Buffer queue */
17711988 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
....@@ -1782,18 +1999,18 @@
17821999 ret = vb2_queue_init(q);
17832000 if (ret < 0) {
17842001 dev_err(&pdev->dev, "Failed to initialize vb2 queue\n");
1785
- goto err_device_release;
2002
+ goto err_media_entity_cleanup;
17862003 }
17872004
17882005 ret = dcmi_graph_init(dcmi);
17892006 if (ret < 0)
1790
- goto err_device_release;
2007
+ goto err_media_entity_cleanup;
17912008
17922009 /* Reset device */
17932010 ret = reset_control_assert(dcmi->rstc);
17942011 if (ret) {
17952012 dev_err(&pdev->dev, "Failed to assert the reset line\n");
1796
- goto err_device_release;
2013
+ goto err_cleanup;
17972014 }
17982015
17992016 usleep_range(3000, 5000);
....@@ -1801,7 +2018,7 @@
18012018 ret = reset_control_deassert(dcmi->rstc);
18022019 if (ret) {
18032020 dev_err(&pdev->dev, "Failed to deassert the reset line\n");
1804
- goto err_device_release;
2021
+ goto err_cleanup;
18052022 }
18062023
18072024 dev_info(&pdev->dev, "Probe done\n");
....@@ -1812,11 +2029,16 @@
18122029
18132030 return 0;
18142031
2032
+err_cleanup:
2033
+ v4l2_async_notifier_cleanup(&dcmi->notifier);
2034
+err_media_entity_cleanup:
2035
+ media_entity_cleanup(&dcmi->vdev->entity);
18152036 err_device_release:
18162037 video_device_release(dcmi->vdev);
18172038 err_device_unregister:
18182039 v4l2_device_unregister(&dcmi->v4l2_dev);
1819
-err_dma_release:
2040
+err_media_device_cleanup:
2041
+ media_device_cleanup(&dcmi->mdev);
18202042 dma_release_channel(dcmi->dma_chan);
18212043
18222044 return ret;
....@@ -1829,7 +2051,10 @@
18292051 pm_runtime_disable(&pdev->dev);
18302052
18312053 v4l2_async_notifier_unregister(&dcmi->notifier);
2054
+ v4l2_async_notifier_cleanup(&dcmi->notifier);
2055
+ media_entity_cleanup(&dcmi->vdev->entity);
18322056 v4l2_device_unregister(&dcmi->v4l2_dev);
2057
+ media_device_cleanup(&dcmi->mdev);
18332058
18342059 dma_release_channel(dcmi->dma_chan);
18352060