/* * Media device */ static int camif_media_dev_init(struct camif_dev *camif) { struct media_device *md = &camif->media_dev; struct v4l2_device *v4l2_dev = &camif->v4l2_dev; unsigned int ip_rev = camif->variant->ip_revision; int ret; memset(md, 0, sizeof(*md)); snprintf(md->model, sizeof(md->model), "SAMSUNG S3C%s CAMIF", ip_rev == S3C6410_CAMIF_IP_REV ? "6410" : "244X"); strlcpy(md->bus_info, "platform", sizeof(md->bus_info)); md->hw_revision = ip_rev; md->driver_version = KERNEL_VERSION(1, 0, 0); md->dev = camif->dev; strlcpy(v4l2_dev->name, "s3c-camif", sizeof(v4l2_dev->name)); v4l2_dev->mdev = md; media_device_init(md); ret = v4l2_device_register(camif->dev, v4l2_dev); if (ret < 0) return ret; return ret; }
static int rockchip_vpu_probe(struct platform_device *pdev) { const struct of_device_id *match; struct rockchip_vpu_dev *vpu; struct resource *res; int i, ret; vpu = devm_kzalloc(&pdev->dev, sizeof(*vpu), GFP_KERNEL); if (!vpu) return -ENOMEM; vpu->dev = &pdev->dev; vpu->pdev = pdev; mutex_init(&vpu->vpu_mutex); spin_lock_init(&vpu->irqlock); match = of_match_node(of_rockchip_vpu_match, pdev->dev.of_node); vpu->variant = match->data; INIT_DELAYED_WORK(&vpu->watchdog_work, rockchip_vpu_watchdog); for (i = 0; i < vpu->variant->num_clocks; i++) vpu->clocks[i].id = vpu->variant->clk_names[i]; ret = devm_clk_bulk_get(&pdev->dev, vpu->variant->num_clocks, vpu->clocks); if (ret) return ret; res = platform_get_resource(vpu->pdev, IORESOURCE_MEM, 0); vpu->base = devm_ioremap_resource(vpu->dev, res); if (IS_ERR(vpu->base)) return PTR_ERR(vpu->base); vpu->enc_base = vpu->base + vpu->variant->enc_offset; ret = dma_set_coherent_mask(vpu->dev, DMA_BIT_MASK(32)); if (ret) { dev_err(vpu->dev, "Could not set DMA coherent mask.\n"); return ret; } if (vpu->variant->vepu_irq) { int irq; irq = platform_get_irq_byname(vpu->pdev, "vepu"); if (irq <= 0) { dev_err(vpu->dev, "Could not get vepu IRQ.\n"); return -ENXIO; } ret = devm_request_irq(vpu->dev, irq, vpu->variant->vepu_irq, 0, dev_name(vpu->dev), vpu); if (ret) { dev_err(vpu->dev, "Could not request vepu IRQ.\n"); return ret; } } ret = vpu->variant->init(vpu); if (ret) { dev_err(&pdev->dev, "Failed to init VPU hardware\n"); return ret; } pm_runtime_set_autosuspend_delay(vpu->dev, 100); pm_runtime_use_autosuspend(vpu->dev); pm_runtime_enable(vpu->dev); ret = clk_bulk_prepare(vpu->variant->num_clocks, vpu->clocks); if (ret) { dev_err(&pdev->dev, "Failed to prepare clocks\n"); return ret; } ret = v4l2_device_register(&pdev->dev, &vpu->v4l2_dev); if (ret) { dev_err(&pdev->dev, "Failed to register v4l2 device\n"); goto err_clk_unprepare; } platform_set_drvdata(pdev, vpu); vpu->m2m_dev = v4l2_m2m_init(&vpu_m2m_ops); if (IS_ERR(vpu->m2m_dev)) { v4l2_err(&vpu->v4l2_dev, "Failed to init mem2mem device\n"); ret = PTR_ERR(vpu->m2m_dev); goto err_v4l2_unreg; } vpu->mdev.dev = vpu->dev; strlcpy(vpu->mdev.model, DRIVER_NAME, sizeof(vpu->mdev.model)); media_device_init(&vpu->mdev); vpu->v4l2_dev.mdev = &vpu->mdev; ret = rockchip_vpu_video_device_register(vpu); if (ret) { dev_err(&pdev->dev, "Failed to register encoder\n"); goto err_m2m_rel; } ret = media_device_register(&vpu->mdev); if (ret) { v4l2_err(&vpu->v4l2_dev, "Failed to register mem2mem media device\n"); goto err_video_dev_unreg; } return 0; err_video_dev_unreg: if (vpu->vfd_enc) { video_unregister_device(vpu->vfd_enc); video_device_release(vpu->vfd_enc); } err_m2m_rel: v4l2_m2m_release(vpu->m2m_dev); err_v4l2_unreg: v4l2_device_unregister(&vpu->v4l2_dev); err_clk_unprepare: clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks); pm_runtime_disable(vpu->dev); return ret; }