diff options
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-capture.c | 142 | ||||
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-core.c | 13 | ||||
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-core.h | 7 | ||||
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-m2m.c | 17 | ||||
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-mdevice.c | 89 | ||||
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-mdevice.h | 1 |
6 files changed, 138 insertions, 131 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 0051d8161c6c..b45da2780213 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c | |||
@@ -993,7 +993,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc) | |||
993 | if (!(pad->flags & MEDIA_PAD_FL_SINK)) | 993 | if (!(pad->flags & MEDIA_PAD_FL_SINK)) |
994 | break; | 994 | break; |
995 | /* Don't call FIMC subdev operation to avoid nested locking */ | 995 | /* Don't call FIMC subdev operation to avoid nested locking */ |
996 | if (sd == fimc->vid_cap.subdev) { | 996 | if (sd == &fimc->vid_cap.subdev) { |
997 | struct fimc_frame *ff = &vid_cap->ctx->s_frame; | 997 | struct fimc_frame *ff = &vid_cap->ctx->s_frame; |
998 | sink_fmt.format.width = ff->f_width; | 998 | sink_fmt.format.width = ff->f_width; |
999 | sink_fmt.format.height = ff->f_height; | 999 | sink_fmt.format.height = ff->f_height; |
@@ -1489,53 +1489,6 @@ static struct v4l2_subdev_ops fimc_subdev_ops = { | |||
1489 | .pad = &fimc_subdev_pad_ops, | 1489 | .pad = &fimc_subdev_pad_ops, |
1490 | }; | 1490 | }; |
1491 | 1491 | ||
1492 | static int fimc_create_capture_subdev(struct fimc_dev *fimc, | ||
1493 | struct v4l2_device *v4l2_dev) | ||
1494 | { | ||
1495 | struct v4l2_subdev *sd; | ||
1496 | int ret; | ||
1497 | |||
1498 | sd = kzalloc(sizeof(*sd), GFP_KERNEL); | ||
1499 | if (!sd) | ||
1500 | return -ENOMEM; | ||
1501 | |||
1502 | v4l2_subdev_init(sd, &fimc_subdev_ops); | ||
1503 | sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE; | ||
1504 | snprintf(sd->name, sizeof(sd->name), "FIMC.%d", fimc->pdev->id); | ||
1505 | |||
1506 | fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK; | ||
1507 | fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; | ||
1508 | ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM, | ||
1509 | fimc->vid_cap.sd_pads, 0); | ||
1510 | if (ret) | ||
1511 | goto me_err; | ||
1512 | ret = v4l2_device_register_subdev(v4l2_dev, sd); | ||
1513 | if (ret) | ||
1514 | goto sd_err; | ||
1515 | |||
1516 | fimc->vid_cap.subdev = sd; | ||
1517 | v4l2_set_subdevdata(sd, fimc); | ||
1518 | sd->entity.ops = &fimc_sd_media_ops; | ||
1519 | return 0; | ||
1520 | sd_err: | ||
1521 | media_entity_cleanup(&sd->entity); | ||
1522 | me_err: | ||
1523 | kfree(sd); | ||
1524 | return ret; | ||
1525 | } | ||
1526 | |||
1527 | static void fimc_destroy_capture_subdev(struct fimc_dev *fimc) | ||
1528 | { | ||
1529 | struct v4l2_subdev *sd = fimc->vid_cap.subdev; | ||
1530 | |||
1531 | if (!sd) | ||
1532 | return; | ||
1533 | media_entity_cleanup(&sd->entity); | ||
1534 | v4l2_device_unregister_subdev(sd); | ||
1535 | kfree(sd); | ||
1536 | fimc->vid_cap.subdev = NULL; | ||
1537 | } | ||
1538 | |||
1539 | /* Set default format at the sensor and host interface */ | 1492 | /* Set default format at the sensor and host interface */ |
1540 | static int fimc_capture_set_default_format(struct fimc_dev *fimc) | 1493 | static int fimc_capture_set_default_format(struct fimc_dev *fimc) |
1541 | { | 1494 | { |
@@ -1554,7 +1507,7 @@ static int fimc_capture_set_default_format(struct fimc_dev *fimc) | |||
1554 | } | 1507 | } |
1555 | 1508 | ||
1556 | /* fimc->lock must be already initialized */ | 1509 | /* fimc->lock must be already initialized */ |
1557 | int fimc_register_capture_device(struct fimc_dev *fimc, | 1510 | static int fimc_register_capture_device(struct fimc_dev *fimc, |
1558 | struct v4l2_device *v4l2_dev) | 1511 | struct v4l2_device *v4l2_dev) |
1559 | { | 1512 | { |
1560 | struct video_device *vfd; | 1513 | struct video_device *vfd; |
@@ -1572,7 +1525,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc, | |||
1572 | ctx->out_path = FIMC_DMA; | 1525 | ctx->out_path = FIMC_DMA; |
1573 | ctx->state = FIMC_CTX_CAP; | 1526 | ctx->state = FIMC_CTX_CAP; |
1574 | ctx->s_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0); | 1527 | ctx->s_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0); |
1575 | ctx->d_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0); | 1528 | ctx->d_frame.fmt = ctx->s_frame.fmt; |
1576 | 1529 | ||
1577 | vfd = video_device_alloc(); | 1530 | vfd = video_device_alloc(); |
1578 | if (!vfd) { | 1531 | if (!vfd) { |
@@ -1580,8 +1533,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc, | |||
1580 | goto err_vd_alloc; | 1533 | goto err_vd_alloc; |
1581 | } | 1534 | } |
1582 | 1535 | ||
1583 | snprintf(vfd->name, sizeof(vfd->name), "%s.capture", | 1536 | snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.capture", fimc->id); |
1584 | dev_name(&fimc->pdev->dev)); | ||
1585 | 1537 | ||
1586 | vfd->fops = &fimc_capture_fops; | 1538 | vfd->fops = &fimc_capture_fops; |
1587 | vfd->ioctl_ops = &fimc_capture_ioctl_ops; | 1539 | vfd->ioctl_ops = &fimc_capture_ioctl_ops; |
@@ -1616,18 +1568,22 @@ int fimc_register_capture_device(struct fimc_dev *fimc, | |||
1616 | 1568 | ||
1617 | vb2_queue_init(q); | 1569 | vb2_queue_init(q); |
1618 | 1570 | ||
1619 | fimc->vid_cap.vd_pad.flags = MEDIA_PAD_FL_SINK; | 1571 | vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK; |
1620 | ret = media_entity_init(&vfd->entity, 1, &fimc->vid_cap.vd_pad, 0); | 1572 | ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0); |
1621 | if (ret) | 1573 | if (ret) |
1622 | goto err_ent; | 1574 | goto err_ent; |
1623 | ret = fimc_create_capture_subdev(fimc, v4l2_dev); | 1575 | |
1576 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); | ||
1624 | if (ret) | 1577 | if (ret) |
1625 | goto err_sd_reg; | 1578 | goto err_vd; |
1579 | |||
1580 | v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n", | ||
1581 | vfd->name, video_device_node_name(vfd)); | ||
1626 | 1582 | ||
1627 | vfd->ctrl_handler = &ctx->ctrl_handler; | 1583 | vfd->ctrl_handler = &ctx->ctrl_handler; |
1628 | return 0; | 1584 | return 0; |
1629 | 1585 | ||
1630 | err_sd_reg: | 1586 | err_vd: |
1631 | media_entity_cleanup(&vfd->entity); | 1587 | media_entity_cleanup(&vfd->entity); |
1632 | err_ent: | 1588 | err_ent: |
1633 | video_device_release(vfd); | 1589 | video_device_release(vfd); |
@@ -1636,17 +1592,73 @@ err_vd_alloc: | |||
1636 | return ret; | 1592 | return ret; |
1637 | } | 1593 | } |
1638 | 1594 | ||
1639 | void fimc_unregister_capture_device(struct fimc_dev *fimc) | 1595 | static int fimc_capture_subdev_registered(struct v4l2_subdev *sd) |
1640 | { | 1596 | { |
1641 | struct video_device *vfd = fimc->vid_cap.vfd; | 1597 | struct fimc_dev *fimc = v4l2_get_subdevdata(sd); |
1598 | int ret; | ||
1642 | 1599 | ||
1643 | if (vfd) { | 1600 | ret = fimc_register_m2m_device(fimc, sd->v4l2_dev); |
1644 | media_entity_cleanup(&vfd->entity); | 1601 | if (ret) |
1645 | /* Can also be called if video device was | 1602 | return ret; |
1646 | not registered */ | 1603 | |
1647 | video_unregister_device(vfd); | 1604 | ret = fimc_register_capture_device(fimc, sd->v4l2_dev); |
1605 | if (ret) | ||
1606 | fimc_unregister_m2m_device(fimc); | ||
1607 | |||
1608 | return ret; | ||
1609 | } | ||
1610 | |||
1611 | static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd) | ||
1612 | { | ||
1613 | struct fimc_dev *fimc = v4l2_get_subdevdata(sd); | ||
1614 | |||
1615 | if (fimc == NULL) | ||
1616 | return; | ||
1617 | |||
1618 | fimc_unregister_m2m_device(fimc); | ||
1619 | |||
1620 | if (fimc->vid_cap.vfd) { | ||
1621 | media_entity_cleanup(&fimc->vid_cap.vfd->entity); | ||
1622 | video_unregister_device(fimc->vid_cap.vfd); | ||
1623 | fimc->vid_cap.vfd = NULL; | ||
1648 | } | 1624 | } |
1649 | fimc_destroy_capture_subdev(fimc); | 1625 | |
1650 | kfree(fimc->vid_cap.ctx); | 1626 | kfree(fimc->vid_cap.ctx); |
1651 | fimc->vid_cap.ctx = NULL; | 1627 | fimc->vid_cap.ctx = NULL; |
1652 | } | 1628 | } |
1629 | |||
1630 | static const struct v4l2_subdev_internal_ops fimc_capture_sd_internal_ops = { | ||
1631 | .registered = fimc_capture_subdev_registered, | ||
1632 | .unregistered = fimc_capture_subdev_unregistered, | ||
1633 | }; | ||
1634 | |||
1635 | int fimc_initialize_capture_subdev(struct fimc_dev *fimc) | ||
1636 | { | ||
1637 | struct v4l2_subdev *sd = &fimc->vid_cap.subdev; | ||
1638 | int ret; | ||
1639 | |||
1640 | v4l2_subdev_init(sd, &fimc_subdev_ops); | ||
1641 | sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE; | ||
1642 | snprintf(sd->name, sizeof(sd->name), "FIMC.%d", fimc->pdev->id); | ||
1643 | |||
1644 | fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK; | ||
1645 | fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; | ||
1646 | ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM, | ||
1647 | fimc->vid_cap.sd_pads, 0); | ||
1648 | if (ret) | ||
1649 | return ret; | ||
1650 | |||
1651 | sd->entity.ops = &fimc_sd_media_ops; | ||
1652 | sd->internal_ops = &fimc_capture_sd_internal_ops; | ||
1653 | v4l2_set_subdevdata(sd, fimc); | ||
1654 | return 0; | ||
1655 | } | ||
1656 | |||
1657 | void fimc_unregister_capture_subdev(struct fimc_dev *fimc) | ||
1658 | { | ||
1659 | struct v4l2_subdev *sd = &fimc->vid_cap.subdev; | ||
1660 | |||
1661 | v4l2_device_unregister_subdev(sd); | ||
1662 | media_entity_cleanup(&sd->entity); | ||
1663 | v4l2_set_subdevdata(sd, NULL); | ||
1664 | } | ||
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 749db4deefcb..add24cd373a5 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c | |||
@@ -842,8 +842,6 @@ static int fimc_probe(struct platform_device *pdev) | |||
842 | clk_set_rate(fimc->clock[CLK_BUS], drv_data->lclk_frequency); | 842 | clk_set_rate(fimc->clock[CLK_BUS], drv_data->lclk_frequency); |
843 | clk_enable(fimc->clock[CLK_BUS]); | 843 | clk_enable(fimc->clock[CLK_BUS]); |
844 | 844 | ||
845 | platform_set_drvdata(pdev, fimc); | ||
846 | |||
847 | ret = devm_request_irq(&pdev->dev, res->start, fimc_irq_handler, | 845 | ret = devm_request_irq(&pdev->dev, res->start, fimc_irq_handler, |
848 | 0, pdev->name, fimc); | 846 | 0, pdev->name, fimc); |
849 | if (ret) { | 847 | if (ret) { |
@@ -851,10 +849,15 @@ static int fimc_probe(struct platform_device *pdev) | |||
851 | goto err_clk; | 849 | goto err_clk; |
852 | } | 850 | } |
853 | 851 | ||
852 | ret = fimc_initialize_capture_subdev(fimc); | ||
853 | if (ret) | ||
854 | goto err_clk; | ||
855 | |||
856 | platform_set_drvdata(pdev, fimc); | ||
854 | pm_runtime_enable(&pdev->dev); | 857 | pm_runtime_enable(&pdev->dev); |
855 | ret = pm_runtime_get_sync(&pdev->dev); | 858 | ret = pm_runtime_get_sync(&pdev->dev); |
856 | if (ret < 0) | 859 | if (ret < 0) |
857 | goto err_clk; | 860 | goto err_sd; |
858 | /* Initialize contiguous memory allocator */ | 861 | /* Initialize contiguous memory allocator */ |
859 | fimc->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); | 862 | fimc->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); |
860 | if (IS_ERR(fimc->alloc_ctx)) { | 863 | if (IS_ERR(fimc->alloc_ctx)) { |
@@ -866,9 +869,10 @@ static int fimc_probe(struct platform_device *pdev) | |||
866 | 869 | ||
867 | pm_runtime_put(&pdev->dev); | 870 | pm_runtime_put(&pdev->dev); |
868 | return 0; | 871 | return 0; |
869 | |||
870 | err_pm: | 872 | err_pm: |
871 | pm_runtime_put(&pdev->dev); | 873 | pm_runtime_put(&pdev->dev); |
874 | err_sd: | ||
875 | fimc_unregister_capture_subdev(fimc); | ||
872 | err_clk: | 876 | err_clk: |
873 | fimc_clk_put(fimc); | 877 | fimc_clk_put(fimc); |
874 | return ret; | 878 | return ret; |
@@ -953,6 +957,7 @@ static int __devexit fimc_remove(struct platform_device *pdev) | |||
953 | pm_runtime_disable(&pdev->dev); | 957 | pm_runtime_disable(&pdev->dev); |
954 | pm_runtime_set_suspended(&pdev->dev); | 958 | pm_runtime_set_suspended(&pdev->dev); |
955 | 959 | ||
960 | fimc_unregister_capture_subdev(fimc); | ||
956 | vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx); | 961 | vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx); |
957 | 962 | ||
958 | clk_disable(fimc->clock[CLK_BUS]); | 963 | clk_disable(fimc->clock[CLK_BUS]); |
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h index 288631a86e53..ef7c6a23ca2a 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.h +++ b/drivers/media/video/s5p-fimc/fimc-core.h | |||
@@ -331,7 +331,7 @@ struct fimc_vid_cap { | |||
331 | struct fimc_ctx *ctx; | 331 | struct fimc_ctx *ctx; |
332 | struct vb2_alloc_ctx *alloc_ctx; | 332 | struct vb2_alloc_ctx *alloc_ctx; |
333 | struct video_device *vfd; | 333 | struct video_device *vfd; |
334 | struct v4l2_subdev *subdev; | 334 | struct v4l2_subdev subdev; |
335 | struct media_pad vd_pad; | 335 | struct media_pad vd_pad; |
336 | struct v4l2_mbus_framefmt mf; | 336 | struct v4l2_mbus_framefmt mf; |
337 | struct media_pad sd_pads[FIMC_SD_PADS_NUM]; | 337 | struct media_pad sd_pads[FIMC_SD_PADS_NUM]; |
@@ -737,9 +737,8 @@ void fimc_m2m_job_finish(struct fimc_ctx *ctx, int vb_state); | |||
737 | 737 | ||
738 | /* -----------------------------------------------------*/ | 738 | /* -----------------------------------------------------*/ |
739 | /* fimc-capture.c */ | 739 | /* fimc-capture.c */ |
740 | int fimc_register_capture_device(struct fimc_dev *fimc, | 740 | int fimc_initialize_capture_subdev(struct fimc_dev *fimc); |
741 | struct v4l2_device *v4l2_dev); | 741 | void fimc_unregister_capture_subdev(struct fimc_dev *fimc); |
742 | void fimc_unregister_capture_device(struct fimc_dev *fimc); | ||
743 | int fimc_capture_ctrls_create(struct fimc_dev *fimc); | 742 | int fimc_capture_ctrls_create(struct fimc_dev *fimc); |
744 | void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification, | 743 | void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification, |
745 | void *arg); | 744 | void *arg); |
diff --git a/drivers/media/video/s5p-fimc/fimc-m2m.c b/drivers/media/video/s5p-fimc/fimc-m2m.c index 9935cc4bd0cb..92b6059b25bf 100644 --- a/drivers/media/video/s5p-fimc/fimc-m2m.c +++ b/drivers/media/video/s5p-fimc/fimc-m2m.c | |||
@@ -776,7 +776,7 @@ int fimc_register_m2m_device(struct fimc_dev *fimc, | |||
776 | This driver needs auditing so that this flag can be removed. */ | 776 | This driver needs auditing so that this flag can be removed. */ |
777 | set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags); | 777 | set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags); |
778 | 778 | ||
779 | snprintf(vfd->name, sizeof(vfd->name), "%s.m2m", dev_name(&pdev->dev)); | 779 | snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.m2m", fimc->id); |
780 | video_set_drvdata(vfd, fimc); | 780 | video_set_drvdata(vfd, fimc); |
781 | 781 | ||
782 | fimc->m2m.vfd = vfd; | 782 | fimc->m2m.vfd = vfd; |
@@ -788,9 +788,20 @@ int fimc_register_m2m_device(struct fimc_dev *fimc, | |||
788 | } | 788 | } |
789 | 789 | ||
790 | ret = media_entity_init(&vfd->entity, 0, NULL, 0); | 790 | ret = media_entity_init(&vfd->entity, 0, NULL, 0); |
791 | if (!ret) | 791 | if (ret) |
792 | return 0; | 792 | goto err_me; |
793 | |||
794 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); | ||
795 | if (ret) | ||
796 | goto err_vd; | ||
797 | |||
798 | v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n", | ||
799 | vfd->name, video_device_node_name(vfd)); | ||
800 | return 0; | ||
793 | 801 | ||
802 | err_vd: | ||
803 | media_entity_cleanup(&vfd->entity); | ||
804 | err_me: | ||
794 | v4l2_m2m_release(fimc->m2m.m2m_dev); | 805 | v4l2_m2m_release(fimc->m2m.m2m_dev); |
795 | err_init: | 806 | err_init: |
796 | video_device_release(fimc->m2m.vfd); | 807 | video_device_release(fimc->m2m.vfd); |
diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c index f97ac02b8677..c319842c762d 100644 --- a/drivers/media/video/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/video/s5p-fimc/fimc-mdevice.c | |||
@@ -304,8 +304,9 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) | |||
304 | static int fimc_register_callback(struct device *dev, void *p) | 304 | static int fimc_register_callback(struct device *dev, void *p) |
305 | { | 305 | { |
306 | struct fimc_dev *fimc = dev_get_drvdata(dev); | 306 | struct fimc_dev *fimc = dev_get_drvdata(dev); |
307 | struct v4l2_subdev *sd = &fimc->vid_cap.subdev; | ||
307 | struct fimc_md *fmd = p; | 308 | struct fimc_md *fmd = p; |
308 | int ret; | 309 | int ret = 0; |
309 | 310 | ||
310 | if (!fimc || !fimc->pdev) | 311 | if (!fimc || !fimc->pdev) |
311 | return 0; | 312 | return 0; |
@@ -313,12 +314,14 @@ static int fimc_register_callback(struct device *dev, void *p) | |||
313 | return 0; | 314 | return 0; |
314 | 315 | ||
315 | fmd->fimc[fimc->pdev->id] = fimc; | 316 | fmd->fimc[fimc->pdev->id] = fimc; |
316 | ret = fimc_register_m2m_device(fimc, &fmd->v4l2_dev); | 317 | sd->grp_id = FIMC_GROUP_ID; |
317 | if (ret) | 318 | |
318 | return ret; | 319 | ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); |
319 | ret = fimc_register_capture_device(fimc, &fmd->v4l2_dev); | 320 | if (ret) { |
320 | if (!ret) | 321 | v4l2_err(&fmd->v4l2_dev, "Failed to register FIMC.%d (%d)\n", |
321 | fimc->vid_cap.user_subdev_api = fmd->user_subdev_api; | 322 | fimc->id, ret); |
323 | } | ||
324 | |||
322 | return ret; | 325 | return ret; |
323 | } | 326 | } |
324 | 327 | ||
@@ -401,8 +404,7 @@ static void fimc_md_unregister_entities(struct fimc_md *fmd) | |||
401 | for (i = 0; i < FIMC_MAX_DEVS; i++) { | 404 | for (i = 0; i < FIMC_MAX_DEVS; i++) { |
402 | if (fmd->fimc[i] == NULL) | 405 | if (fmd->fimc[i] == NULL) |
403 | continue; | 406 | continue; |
404 | fimc_unregister_m2m_device(fmd->fimc[i]); | 407 | v4l2_device_unregister_subdev(&fmd->fimc[i]->vid_cap.subdev); |
405 | fimc_unregister_capture_device(fmd->fimc[i]); | ||
406 | fmd->fimc[i] = NULL; | 408 | fmd->fimc[i] = NULL; |
407 | } | 409 | } |
408 | for (i = 0; i < CSIS_MAX_ENTITIES; i++) { | 410 | for (i = 0; i < CSIS_MAX_ENTITIES; i++) { |
@@ -420,35 +422,6 @@ static void fimc_md_unregister_entities(struct fimc_md *fmd) | |||
420 | } | 422 | } |
421 | } | 423 | } |
422 | 424 | ||
423 | static int fimc_md_register_video_nodes(struct fimc_md *fmd) | ||
424 | { | ||
425 | struct video_device *vdev; | ||
426 | int i, ret = 0; | ||
427 | |||
428 | for (i = 0; i < FIMC_MAX_DEVS && !ret; i++) { | ||
429 | if (!fmd->fimc[i]) | ||
430 | continue; | ||
431 | |||
432 | vdev = fmd->fimc[i]->m2m.vfd; | ||
433 | if (vdev) { | ||
434 | ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); | ||
435 | if (ret) | ||
436 | break; | ||
437 | v4l2_info(&fmd->v4l2_dev, "Registered %s as /dev/%s\n", | ||
438 | vdev->name, video_device_node_name(vdev)); | ||
439 | } | ||
440 | |||
441 | vdev = fmd->fimc[i]->vid_cap.vfd; | ||
442 | if (vdev == NULL) | ||
443 | continue; | ||
444 | ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); | ||
445 | v4l2_info(&fmd->v4l2_dev, "Registered %s as /dev/%s\n", | ||
446 | vdev->name, video_device_node_name(vdev)); | ||
447 | } | ||
448 | |||
449 | return ret; | ||
450 | } | ||
451 | |||
452 | /** | 425 | /** |
453 | * __fimc_md_create_fimc_links - create links to all FIMC entities | 426 | * __fimc_md_create_fimc_links - create links to all FIMC entities |
454 | * @fmd: fimc media device | 427 | * @fmd: fimc media device |
@@ -479,7 +452,7 @@ static int __fimc_md_create_fimc_links(struct fimc_md *fmd, | |||
479 | continue; | 452 | continue; |
480 | 453 | ||
481 | flags = (i == fimc_id) ? MEDIA_LNK_FL_ENABLED : 0; | 454 | flags = (i == fimc_id) ? MEDIA_LNK_FL_ENABLED : 0; |
482 | sink = &fmd->fimc[i]->vid_cap.subdev->entity; | 455 | sink = &fmd->fimc[i]->vid_cap.subdev.entity; |
483 | ret = media_entity_create_link(source, pad, sink, | 456 | ret = media_entity_create_link(source, pad, sink, |
484 | FIMC_SD_PAD_SINK, flags); | 457 | FIMC_SD_PAD_SINK, flags); |
485 | if (ret) | 458 | if (ret) |
@@ -588,7 +561,7 @@ static int fimc_md_create_links(struct fimc_md *fmd) | |||
588 | for (i = 0; i < FIMC_MAX_DEVS; i++) { | 561 | for (i = 0; i < FIMC_MAX_DEVS; i++) { |
589 | if (!fmd->fimc[i]) | 562 | if (!fmd->fimc[i]) |
590 | continue; | 563 | continue; |
591 | source = &fmd->fimc[i]->vid_cap.subdev->entity; | 564 | source = &fmd->fimc[i]->vid_cap.subdev.entity; |
592 | sink = &fmd->fimc[i]->vid_cap.vfd->entity; | 565 | sink = &fmd->fimc[i]->vid_cap.vfd->entity; |
593 | ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE, | 566 | ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE, |
594 | sink, 0, flags); | 567 | sink, 0, flags); |
@@ -817,42 +790,48 @@ static int fimc_md_probe(struct platform_device *pdev) | |||
817 | ret = media_device_register(&fmd->media_dev); | 790 | ret = media_device_register(&fmd->media_dev); |
818 | if (ret < 0) { | 791 | if (ret < 0) { |
819 | v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret); | 792 | v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret); |
820 | goto err2; | 793 | goto err_md; |
821 | } | 794 | } |
822 | ret = fimc_md_get_clocks(fmd); | 795 | ret = fimc_md_get_clocks(fmd); |
823 | if (ret) | 796 | if (ret) |
824 | goto err3; | 797 | goto err_clk; |
825 | 798 | ||
826 | fmd->user_subdev_api = false; | 799 | fmd->user_subdev_api = false; |
800 | |||
801 | /* Protect the media graph while we're registering entities */ | ||
802 | mutex_lock(&fmd->media_dev.graph_mutex); | ||
803 | |||
827 | ret = fimc_md_register_platform_entities(fmd); | 804 | ret = fimc_md_register_platform_entities(fmd); |
828 | if (ret) | 805 | if (ret) |
829 | goto err3; | 806 | goto err_unlock; |
830 | 807 | ||
831 | if (pdev->dev.platform_data) { | 808 | if (pdev->dev.platform_data) { |
832 | ret = fimc_md_register_sensor_entities(fmd); | 809 | ret = fimc_md_register_sensor_entities(fmd); |
833 | if (ret) | 810 | if (ret) |
834 | goto err3; | 811 | goto err_unlock; |
835 | } | 812 | } |
836 | ret = fimc_md_create_links(fmd); | 813 | ret = fimc_md_create_links(fmd); |
837 | if (ret) | 814 | if (ret) |
838 | goto err3; | 815 | goto err_unlock; |
839 | ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev); | 816 | ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev); |
840 | if (ret) | 817 | if (ret) |
841 | goto err3; | 818 | goto err_unlock; |
842 | ret = fimc_md_register_video_nodes(fmd); | ||
843 | if (ret) | ||
844 | goto err3; | ||
845 | 819 | ||
846 | ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode); | 820 | ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode); |
847 | if (!ret) { | 821 | if (ret) |
848 | platform_set_drvdata(pdev, fmd); | 822 | goto err_unlock; |
849 | return 0; | 823 | |
850 | } | 824 | platform_set_drvdata(pdev, fmd); |
851 | err3: | 825 | mutex_unlock(&fmd->media_dev.graph_mutex); |
826 | return 0; | ||
827 | |||
828 | err_unlock: | ||
829 | mutex_unlock(&fmd->media_dev.graph_mutex); | ||
830 | err_clk: | ||
852 | media_device_unregister(&fmd->media_dev); | 831 | media_device_unregister(&fmd->media_dev); |
853 | fimc_md_put_clocks(fmd); | 832 | fimc_md_put_clocks(fmd); |
854 | fimc_md_unregister_entities(fmd); | 833 | fimc_md_unregister_entities(fmd); |
855 | err2: | 834 | err_md: |
856 | v4l2_device_unregister(&fmd->v4l2_dev); | 835 | v4l2_device_unregister(&fmd->v4l2_dev); |
857 | return ret; | 836 | return ret; |
858 | } | 837 | } |
diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.h b/drivers/media/video/s5p-fimc/fimc-mdevice.h index da3780823e7d..4f3b69c682cb 100644 --- a/drivers/media/video/s5p-fimc/fimc-mdevice.h +++ b/drivers/media/video/s5p-fimc/fimc-mdevice.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #define SENSOR_GROUP_ID (1 << 8) | 24 | #define SENSOR_GROUP_ID (1 << 8) |
25 | #define CSIS_GROUP_ID (1 << 9) | 25 | #define CSIS_GROUP_ID (1 << 9) |
26 | #define WRITEBACK_GROUP_ID (1 << 10) | 26 | #define WRITEBACK_GROUP_ID (1 << 10) |
27 | #define FIMC_GROUP_ID (1 << 11) | ||
27 | 28 | ||
28 | #define FIMC_MAX_SENSORS 8 | 29 | #define FIMC_MAX_SENSORS 8 |
29 | #define FIMC_MAX_CAMCLKS 2 | 30 | #define FIMC_MAX_CAMCLKS 2 |