| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd |
|---|
| 3 | 4 | * Author: Jacob Chen <jacob-chen@iotwrt.com> |
|---|
| 4 | | - * |
|---|
| 5 | | - * This software is licensed under the terms of the GNU General Public |
|---|
| 6 | | - * License version 2, as published by the Free Software Foundation, and |
|---|
| 7 | | - * may be copied, distributed, and modified under those terms. |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 10 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 11 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 12 | | - * GNU General Public License for more details. |
|---|
| 13 | 5 | */ |
|---|
| 14 | 6 | |
|---|
| 15 | 7 | #include <linux/clk.h> |
|---|
| .. | .. |
|---|
| 97 | 89 | return IRQ_HANDLED; |
|---|
| 98 | 90 | } |
|---|
| 99 | 91 | |
|---|
| 100 | | -static struct v4l2_m2m_ops rga_m2m_ops = { |
|---|
| 92 | +static const struct v4l2_m2m_ops rga_m2m_ops = { |
|---|
| 101 | 93 | .device_run = device_run, |
|---|
| 102 | 94 | }; |
|---|
| 103 | 95 | |
|---|
| .. | .. |
|---|
| 447 | 439 | static int |
|---|
| 448 | 440 | vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) |
|---|
| 449 | 441 | { |
|---|
| 450 | | - strlcpy(cap->driver, RGA_NAME, sizeof(cap->driver)); |
|---|
| 451 | | - strlcpy(cap->card, "rockchip-rga", sizeof(cap->card)); |
|---|
| 452 | | - strlcpy(cap->bus_info, "platform:rga", sizeof(cap->bus_info)); |
|---|
| 442 | + strscpy(cap->driver, RGA_NAME, sizeof(cap->driver)); |
|---|
| 443 | + strscpy(cap->card, "rockchip-rga", sizeof(cap->card)); |
|---|
| 444 | + strscpy(cap->bus_info, "platform:rga", sizeof(cap->bus_info)); |
|---|
| 453 | 445 | |
|---|
| 454 | 446 | return 0; |
|---|
| 455 | 447 | } |
|---|
| .. | .. |
|---|
| 700 | 692 | .vidioc_s_selection = vidioc_s_selection, |
|---|
| 701 | 693 | }; |
|---|
| 702 | 694 | |
|---|
| 703 | | -static struct video_device rga_videodev = { |
|---|
| 695 | +static const struct video_device rga_videodev = { |
|---|
| 704 | 696 | .name = "rockchip-rga", |
|---|
| 705 | 697 | .fops = &rga_fops, |
|---|
| 706 | 698 | .ioctl_ops = &rga_ioctl_ops, |
|---|
| .. | .. |
|---|
| 839 | 831 | |
|---|
| 840 | 832 | irq = platform_get_irq(pdev, 0); |
|---|
| 841 | 833 | if (irq < 0) { |
|---|
| 842 | | - dev_err(rga->dev, "failed to get irq\n"); |
|---|
| 843 | 834 | ret = irq; |
|---|
| 844 | 835 | goto err_put_clk; |
|---|
| 845 | 836 | } |
|---|
| .. | .. |
|---|
| 872 | 863 | if (IS_ERR(rga->m2m_dev)) { |
|---|
| 873 | 864 | v4l2_err(&rga->v4l2_dev, "Failed to init mem2mem device\n"); |
|---|
| 874 | 865 | ret = PTR_ERR(rga->m2m_dev); |
|---|
| 875 | | - goto unreg_video_dev; |
|---|
| 866 | + goto rel_vdev; |
|---|
| 876 | 867 | } |
|---|
| 877 | 868 | |
|---|
| 878 | | - pm_runtime_get_sync(rga->dev); |
|---|
| 869 | + ret = pm_runtime_resume_and_get(rga->dev); |
|---|
| 870 | + if (ret < 0) |
|---|
| 871 | + goto rel_m2m; |
|---|
| 879 | 872 | |
|---|
| 880 | 873 | rga->version.major = (rga_read(rga, RGA_VERSION_INFO) >> 24) & 0xFF; |
|---|
| 881 | 874 | rga->version.minor = (rga_read(rga, RGA_VERSION_INFO) >> 20) & 0x0F; |
|---|
| .. | .. |
|---|
| 889 | 882 | rga->cmdbuf_virt = dma_alloc_attrs(rga->dev, RGA_CMDBUF_SIZE, |
|---|
| 890 | 883 | &rga->cmdbuf_phy, GFP_KERNEL, |
|---|
| 891 | 884 | DMA_ATTR_WRITE_COMBINE); |
|---|
| 885 | + if (!rga->cmdbuf_virt) { |
|---|
| 886 | + ret = -ENOMEM; |
|---|
| 887 | + goto rel_m2m; |
|---|
| 888 | + } |
|---|
| 892 | 889 | |
|---|
| 893 | 890 | rga->src_mmu_pages = |
|---|
| 894 | 891 | (unsigned int *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3); |
|---|
| 892 | + if (!rga->src_mmu_pages) { |
|---|
| 893 | + ret = -ENOMEM; |
|---|
| 894 | + goto free_dma; |
|---|
| 895 | + } |
|---|
| 895 | 896 | rga->dst_mmu_pages = |
|---|
| 896 | 897 | (unsigned int *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3); |
|---|
| 898 | + if (!rga->dst_mmu_pages) { |
|---|
| 899 | + ret = -ENOMEM; |
|---|
| 900 | + goto free_src_pages; |
|---|
| 901 | + } |
|---|
| 897 | 902 | |
|---|
| 898 | 903 | def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3; |
|---|
| 899 | 904 | def_frame.size = def_frame.stride * def_frame.height; |
|---|
| 900 | 905 | |
|---|
| 901 | | - ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); |
|---|
| 906 | + ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1); |
|---|
| 902 | 907 | if (ret) { |
|---|
| 903 | 908 | v4l2_err(&rga->v4l2_dev, "Failed to register video device\n"); |
|---|
| 904 | | - goto rel_vdev; |
|---|
| 909 | + goto free_dst_pages; |
|---|
| 905 | 910 | } |
|---|
| 906 | 911 | |
|---|
| 907 | 912 | v4l2_info(&rga->v4l2_dev, "Registered %s as /dev/%s\n", |
|---|
| .. | .. |
|---|
| 909 | 914 | |
|---|
| 910 | 915 | return 0; |
|---|
| 911 | 916 | |
|---|
| 917 | +free_dst_pages: |
|---|
| 918 | + free_pages((unsigned long)rga->dst_mmu_pages, 3); |
|---|
| 919 | +free_src_pages: |
|---|
| 920 | + free_pages((unsigned long)rga->src_mmu_pages, 3); |
|---|
| 921 | +free_dma: |
|---|
| 922 | + dma_free_attrs(rga->dev, RGA_CMDBUF_SIZE, rga->cmdbuf_virt, |
|---|
| 923 | + rga->cmdbuf_phy, DMA_ATTR_WRITE_COMBINE); |
|---|
| 924 | +rel_m2m: |
|---|
| 925 | + v4l2_m2m_release(rga->m2m_dev); |
|---|
| 912 | 926 | rel_vdev: |
|---|
| 913 | 927 | video_device_release(vfd); |
|---|
| 914 | | -unreg_video_dev: |
|---|
| 915 | | - video_unregister_device(rga->vfd); |
|---|
| 916 | 928 | unreg_v4l2_dev: |
|---|
| 917 | 929 | v4l2_device_unregister(&rga->v4l2_dev); |
|---|
| 918 | 930 | err_put_clk: |
|---|