static int hva_register_device(struct hva_dev *hva) { int ret; struct video_device *vdev; struct device *dev; if (!hva) return -ENODEV; dev = hva_to_dev(hva); hva->m2m_dev = v4l2_m2m_init(&hva_m2m_ops); if (IS_ERR(hva->m2m_dev)) { dev_err(dev, "%s failed to initialize v4l2-m2m device\n", HVA_PREFIX); ret = PTR_ERR(hva->m2m_dev); goto err; } vdev = video_device_alloc(); if (!vdev) { dev_err(dev, "%s failed to allocate video device\n", HVA_PREFIX); ret = -ENOMEM; goto err_m2m_release; } vdev->fops = &hva_fops; vdev->ioctl_ops = &hva_ioctl_ops; vdev->release = video_device_release; vdev->lock = &hva->lock; vdev->vfl_dir = VFL_DIR_M2M; vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M; vdev->v4l2_dev = &hva->v4l2_dev; snprintf(vdev->name, sizeof(vdev->name), "%s%lx", HVA_NAME, hva->ip_version); ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); if (ret) { dev_err(dev, "%s failed to register video device\n", HVA_PREFIX); goto err_vdev_release; } hva->vdev = vdev; video_set_drvdata(vdev, hva); return 0; err_vdev_release: video_device_release(vdev); err_m2m_release: v4l2_m2m_release(hva->m2m_dev); err: return ret; }
static int hva_remove(struct platform_device *pdev) { struct hva_dev *hva = platform_get_drvdata(pdev); struct device *dev = hva_to_dev(hva); hva_unregister_device(hva); destroy_workqueue(hva->work_queue); hva_hw_remove(hva); v4l2_device_unregister(&hva->v4l2_dev); dev_info(dev, "%s %s removed\n", HVA_PREFIX, pdev->name); return 0; }
static void register_encoders(struct hva_dev *hva) { struct device *dev = hva_to_dev(hva); unsigned int i; for (i = 0; i < ARRAY_SIZE(hva_encoders); i++) { if (hva->nb_of_encoders >= HVA_MAX_ENCODERS) { dev_dbg(dev, "%s failed to register %s encoder (%d maximum reached)\n", HVA_PREFIX, hva_encoders[i]->name, HVA_MAX_ENCODERS); return; } hva->encoders[hva->nb_of_encoders++] = hva_encoders[i]; dev_info(dev, "%s %s encoder registered\n", HVA_PREFIX, hva_encoders[i]->name); } }
static int hva_remove(struct platform_device *pdev) { struct hva_dev *hva = platform_get_drvdata(pdev); struct device *dev = hva_to_dev(hva); hva_unregister_device(hva); destroy_workqueue(hva->work_queue); hva_hw_remove(hva); #ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS hva_debugfs_remove(hva); #endif v4l2_device_unregister(&hva->v4l2_dev); dev_info(dev, "%s %s removed\n", HVA_PREFIX, pdev->name); return 0; }
static int hva_open(struct file *file) { struct hva_dev *hva = video_drvdata(file); struct device *dev = hva_to_dev(hva); struct hva_ctx *ctx; int ret; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) { ret = -ENOMEM; goto out; } ctx->hva_dev = hva; INIT_WORK(&ctx->run_work, hva_run_work); v4l2_fh_init(&ctx->fh, video_devdata(file)); file->private_data = &ctx->fh; v4l2_fh_add(&ctx->fh); ret = hva_ctrls_setup(ctx); if (ret) { dev_err(dev, "%s [x:x] failed to setup controls\n", HVA_PREFIX); goto err_fh; } ctx->fh.ctrl_handler = &ctx->ctrl_handler; mutex_init(&ctx->lock); ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(hva->m2m_dev, ctx, &hva_queue_init); if (IS_ERR(ctx->fh.m2m_ctx)) { ret = PTR_ERR(ctx->fh.m2m_ctx); dev_err(dev, "%s failed to initialize m2m context (%d)\n", HVA_PREFIX, ret); goto err_ctrls; } /* set the instance name */ mutex_lock(&hva->lock); hva->instance_id++; snprintf(ctx->name, sizeof(ctx->name), "[%3d:----]", hva->instance_id); mutex_unlock(&hva->lock); /* default parameters for frame and stream */ set_default_params(ctx); dev_info(dev, "%s encoder instance created\n", ctx->name); return 0; err_ctrls: v4l2_ctrl_handler_free(&ctx->ctrl_handler); err_fh: v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); kfree(ctx); out: return ret; }