[PATCH 2/2] [ARM] samsung-rotator: Add Samsung S3C/S5P rotator driver
Alexey Klimov
klimov.linux at gmail.com
Wed Dec 23 17:29:17 EST 2009
Hello,
On Wed, Dec 23, 2009 at 1:08 PM, Pawel Osciak <p.osciak at samsung.com> wrote:
> The rotator device present on Samsung S3C and S5P series SoCs allows image
> rotation and flipping. It requires contiguous memory buffers to operate,
> as it does not have scatter-gather support. It is also an example of
> a memory-to-memory device, and so uses the mem-2-mem device V4L2 framework.
[...]
> +
> +static const struct v4l2_file_operations s3c_rotator_fops = {
> + .owner = THIS_MODULE,
> + .open = s3c_rotator_open,
> + .release = s3c_rotator_release,
> + .poll = s3c_rotator_poll,
> + .ioctl = video_ioctl2,
> + .mmap = s3c_rotator_mmap,
> +};
> +
> +static struct video_device m2mtest_videodev = {
> + .name = S3C_ROTATOR_NAME,
> + .fops = &s3c_rotator_fops,
> + .ioctl_ops = &s3c_rotator_ioctl_ops,
> + .minor = -1,
> + .release = video_device_release,
> +};
> +
> +static struct v4l2_m2m_ops m2m_ops = {
> + .device_run = device_run,
> + .job_abort = job_abort,
> +};
> +
> +static int s3c_rotator_probe(struct platform_device *pdev)
> +{
> + struct s3c_rotator_dev *dev;
> + struct video_device *vfd;
> + struct resource *res;
> + int ret = -ENOENT;
Here ^^^ (see below please for comments)
> +
> + dev = kzalloc(sizeof *dev, GFP_KERNEL);
> + if (!dev)
> + return -ENOMEM;
> +
> + spin_lock_init(&dev->irqlock);
> + ret = -ENOENT;
It's probably bad pedantic part of me speaking but looks like you set
ret equals to -ENOENT two times. Most likely you don't need
assignment second time.
> + dev->irq = platform_get_irq(pdev, 0);
> + if (dev->irq <= 0) {
> + dev_err(&pdev->dev, "Failed to acquire irq\n");
> + goto free_dev;
> + }
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (!res) {
> + dev_err(&pdev->dev,
> + "Failed to acquire memory region resource\n");
> + goto free_irq;
> + }
> +
> + dev->regs_res = request_mem_region(res->start, resource_size(res),
> + dev_name(&pdev->dev));
> + if (!dev->regs_res) {
> + dev_err(&pdev->dev, "Failed to reserve memory region\n");
> + goto free_irq;
> + }
> +
> + dev->regs_base = ioremap(res->start, resource_size(res));
> + if (!dev->regs_base) {
> + dev_err(&pdev->dev, "Ioremap failed\n");
> + ret = -ENXIO;
> + goto rel_res;
> + }
> +
> + ret = request_irq(dev->irq, s3c_rotator_isr, 0,
> + S3C_ROTATOR_NAME, dev);
> + if (ret) {
> + dev_err(&pdev->dev, "Requesting irq failed\n");
> + goto regs_unmap;
> + }
> +
> + ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
> + if (ret)
> + goto regs_unmap;
> +
> + atomic_set(&dev->num_inst, 0);
> +
> + vfd = video_device_alloc();
> + if (!vfd) {
> + v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
> + goto unreg_dev;
> + }
> +
> + *vfd = m2mtest_videodev;
> +
> + ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
> + if (ret) {
> + v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
> + goto rel_vdev;
> + }
> +
> + video_set_drvdata(vfd, dev);
> + snprintf(vfd->name, sizeof(vfd->name), "%s", m2mtest_videodev.name);
> + dev->vfd = vfd;
> + v4l2_info(&dev->v4l2_dev,
> + "Device registered as /dev/video%d\n", vfd->num);
> +
> + platform_set_drvdata(pdev, dev);
> +
> + dev->m2m_dev = v4l2_m2m_init(&m2m_ops);
> + if (IS_ERR(dev->m2m_dev)) {
> + v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
> + ret = PTR_ERR(dev->m2m_dev);
> + goto err_m2m;
> + }
> +
> + return 0;
> +
> +err_m2m:
> + video_unregister_device(dev->vfd);
> +rel_vdev:
> + video_device_release(vfd);
> +unreg_dev:
> + v4l2_device_unregister(&dev->v4l2_dev);
> +regs_unmap:
> + iounmap(dev->regs_base);
> +rel_res:
> + release_resource(dev->regs_res);
> + kfree(dev->regs_res);
> +free_irq:
> + free_irq(dev->irq, dev);
> +free_dev:
> + kfree(dev);
> +
> + return ret;
> +}
> +
> +static int s3c_rotator_remove(struct platform_device *pdev)
> +{
> + struct s3c_rotator_dev *dev =
> + (struct s3c_rotator_dev *)platform_get_drvdata(pdev);
> +
> + v4l2_info(&dev->v4l2_dev, "Removing %s\n", S3C_ROTATOR_NAME);
> +
> + v4l2_m2m_release(dev->m2m_dev);
> + video_unregister_device(dev->vfd);
> + v4l2_device_unregister(&dev->v4l2_dev);
> + iounmap(dev->regs_base);
> + release_resource(dev->regs_res);
> + kfree(dev->regs_res);
> + free_irq(dev->irq, dev);
> + kfree(dev);
> +
> + return 0;
> +}
> +
> +static int s3c_rotator_suspend(struct device *dev)
> +{
> + return 0;
> +}
> +
> +static int s3c_rotator_resume(struct device *dev)
> +{
> + return 0;
> +}
> +
> +static struct dev_pm_ops s3c_rotator_pm_ops = {
> + .suspend = s3c_rotator_suspend,
> + .resume = s3c_rotator_resume,
> +};
> +
> +static struct platform_driver s3c_rotator_pdrv = {
> + .probe = s3c_rotator_probe,
> + .remove = s3c_rotator_remove,
> + .driver = {
> + .name = S3C_ROTATOR_NAME,
> + .owner = THIS_MODULE,
> + .pm = &s3c_rotator_pm_ops
> + },
> +};
> +
> +static char banner[] __initdata =
> + KERN_INFO "S3C Rotator V4L2 Driver, (c) 2009 Samsung Electronics\n";
> +
> +static int __init s3c_rotator_init(void)
> +{
> + printk(banner);
> + return platform_driver_register(&s3c_rotator_pdrv);
> +}
> +
> +static void __devexit s3c_rotator_exit(void)
> +{
> + platform_driver_unregister(&s3c_rotator_pdrv);
> +}
> +
> +module_init(s3c_rotator_init);
> +module_exit(s3c_rotator_exit);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Pawel Osciak <p.osciak at samsung.com>");
> +MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki at samsung.com>");
--
Best regards, Klimov Alexey
More information about the linux-arm-kernel
mailing list