diff options
Diffstat (limited to 'drivers/media/platform/rockchip/rga/rga.c')
| -rw-r--r-- | drivers/media/platform/rockchip/rga/rga.c | 269 |
1 files changed, 129 insertions, 140 deletions
diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c index 5c653287185f..43f6a8d99381 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -1,15 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd + * Copyright (C) Rockchip Electronics Co., Ltd. * Author: Jacob Chen <jacob-chen@iotwrt.com> - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/clk.h> @@ -43,7 +35,7 @@ static void device_run(void *prv) { struct rga_ctx *ctx = prv; struct rockchip_rga *rga = ctx->rga; - struct vb2_buffer *src, *dst; + struct vb2_v4l2_buffer *src, *dst; unsigned long flags; spin_lock_irqsave(&rga->ctrl_lock, flags); @@ -51,12 +43,11 @@ static void device_run(void *prv) rga->curr = ctx; src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); - dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); + src->sequence = ctx->osequence++; - rga_buf_map(src); - rga_buf_map(dst); + dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); - rga_hw_start(rga); + rga_hw_start(rga, vb_to_rga(src), vb_to_rga(dst)); spin_unlock_irqrestore(&rga->ctrl_lock, flags); } @@ -84,10 +75,9 @@ static irqreturn_t rga_isr(int irq, void *prv) WARN_ON(!src); WARN_ON(!dst); - dst->timecode = src->timecode; - dst->vb2_buf.timestamp = src->vb2_buf.timestamp; - dst->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK; - dst->flags |= src->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK; + v4l2_m2m_buf_copy_metadata(src, dst); + + dst->sequence = ctx->csequence++; v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE); v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE); @@ -107,12 +97,13 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) struct rga_ctx *ctx = priv; int ret; - src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; src_vq->io_modes = VB2_MMAP | VB2_DMABUF; src_vq->drv_priv = ctx; src_vq->ops = &rga_qops; src_vq->mem_ops = &vb2_dma_sg_memops; - src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + src_vq->gfp_flags = __GFP_DMA32; + src_vq->buf_struct_size = sizeof(struct rga_vb_buffer); src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; src_vq->lock = &ctx->rga->mutex; src_vq->dev = ctx->rga->v4l2_dev.dev; @@ -121,12 +112,13 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) if (ret) return ret; - dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; dst_vq->drv_priv = ctx; dst_vq->ops = &rga_qops; dst_vq->mem_ops = &vb2_dma_sg_memops; - dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + dst_vq->gfp_flags = __GFP_DMA32; + dst_vq->buf_struct_size = sizeof(struct rga_vb_buffer); dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; dst_vq->lock = &ctx->rga->mutex; dst_vq->dev = ctx->rga->v4l2_dev.dev; @@ -195,7 +187,7 @@ static int rga_setup_ctrls(struct rga_ctx *ctx) static struct rga_fmt formats[] = { { .fourcc = V4L2_PIX_FMT_ARGB32, - .color_swap = RGA_COLOR_RB_SWAP, + .color_swap = RGA_COLOR_ALPHA_SWAP, .hw_format = RGA_COLOR_FMT_ABGR8888, .depth = 32, .uv_factor = 1, @@ -203,17 +195,8 @@ static struct rga_fmt formats[] = { .x_div = 1, }, { - .fourcc = V4L2_PIX_FMT_XRGB32, - .color_swap = RGA_COLOR_RB_SWAP, - .hw_format = RGA_COLOR_FMT_XBGR8888, - .depth = 32, - .uv_factor = 1, - .y_div = 1, - .x_div = 1, - }, - { .fourcc = V4L2_PIX_FMT_ABGR32, - .color_swap = RGA_COLOR_ALPHA_SWAP, + .color_swap = RGA_COLOR_RB_SWAP, .hw_format = RGA_COLOR_FMT_ABGR8888, .depth = 32, .uv_factor = 1, @@ -222,7 +205,7 @@ static struct rga_fmt formats[] = { }, { .fourcc = V4L2_PIX_FMT_XBGR32, - .color_swap = RGA_COLOR_ALPHA_SWAP, + .color_swap = RGA_COLOR_RB_SWAP, .hw_format = RGA_COLOR_FMT_XBGR8888, .depth = 32, .uv_factor = 1, @@ -302,6 +285,15 @@ static struct rga_fmt formats[] = { .x_div = 1, }, { + .fourcc = V4L2_PIX_FMT_NV12M, + .color_swap = RGA_COLOR_NONE_SWAP, + .hw_format = RGA_COLOR_FMT_YUV420SP, + .depth = 12, + .uv_factor = 4, + .y_div = 2, + .x_div = 1, + }, + { .fourcc = V4L2_PIX_FMT_NV16, .color_swap = RGA_COLOR_NONE_SWAP, .hw_format = RGA_COLOR_FMT_YUV422SP, @@ -341,12 +333,12 @@ static struct rga_fmt formats[] = { #define NUM_FORMATS ARRAY_SIZE(formats) -static struct rga_fmt *rga_fmt_find(struct v4l2_format *f) +static struct rga_fmt *rga_fmt_find(u32 pixelformat) { unsigned int i; for (i = 0; i < NUM_FORMATS; i++) { - if (formats[i].fourcc == f->fmt.pix.pixelformat) + if (formats[i].fourcc == pixelformat) return &formats[i]; } return NULL; @@ -365,14 +357,11 @@ static struct rga_frame def_frame = { struct rga_frame *rga_get_frame(struct rga_ctx *ctx, enum v4l2_buf_type type) { - switch (type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT: + if (V4L2_TYPE_IS_OUTPUT(type)) return &ctx->in; - case V4L2_BUF_TYPE_VIDEO_CAPTURE: + if (V4L2_TYPE_IS_CAPTURE(type)) return &ctx->out; - default: - return ERR_PTR(-EINVAL); - } + return ERR_PTR(-EINVAL); } static int rga_open(struct file *file) @@ -389,6 +378,11 @@ static int rga_open(struct file *file) ctx->in = def_frame; ctx->out = def_frame; + v4l2_fill_pixfmt_mp(&ctx->in.pix, + ctx->in.fmt->fourcc, ctx->out.width, ctx->out.height); + v4l2_fill_pixfmt_mp(&ctx->out.pix, + ctx->out.fmt->fourcc, ctx->out.width, ctx->out.height); + if (mutex_lock_interruptible(&rga->mutex)) { kfree(ctx); return -ERESTARTSYS; @@ -401,8 +395,7 @@ static int rga_open(struct file *file) return ret; } v4l2_fh_init(&ctx->fh, video_devdata(file)); - file->private_data = &ctx->fh; - v4l2_fh_add(&ctx->fh); + v4l2_fh_add(&ctx->fh, file); rga_setup_ctrls(ctx); @@ -417,8 +410,7 @@ static int rga_open(struct file *file) static int rga_release(struct file *file) { - struct rga_ctx *ctx = - container_of(file->private_data, struct rga_ctx, fh); + struct rga_ctx *ctx = file_to_rga_ctx(file); struct rockchip_rga *rga = ctx->rga; mutex_lock(&rga->mutex); @@ -426,7 +418,7 @@ static int rga_release(struct file *file) v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); v4l2_ctrl_handler_free(&ctx->ctrl_handler); - v4l2_fh_del(&ctx->fh); + v4l2_fh_del(&ctx->fh, file); v4l2_fh_exit(&ctx->fh); kfree(ctx); @@ -454,7 +446,7 @@ vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) return 0; } -static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f) +static int vidioc_enum_fmt(struct file *file, void *priv, struct v4l2_fmtdesc *f) { struct rga_fmt *fmt; @@ -467,76 +459,58 @@ static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f) return 0; } -static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f) +static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) { - struct rga_ctx *ctx = prv; - struct vb2_queue *vq; + struct v4l2_pix_format_mplane *pix_fmt = &f->fmt.pix_mp; + struct rga_ctx *ctx = file_to_rga_ctx(file); struct rga_frame *frm; - vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); - if (!vq) - return -EINVAL; frm = rga_get_frame(ctx, f->type); if (IS_ERR(frm)) return PTR_ERR(frm); - f->fmt.pix.width = frm->width; - f->fmt.pix.height = frm->height; - f->fmt.pix.field = V4L2_FIELD_NONE; - f->fmt.pix.pixelformat = frm->fmt->fourcc; - f->fmt.pix.bytesperline = frm->stride; - f->fmt.pix.sizeimage = frm->size; - f->fmt.pix.colorspace = frm->colorspace; + v4l2_fill_pixfmt_mp(pix_fmt, frm->fmt->fourcc, frm->width, frm->height); + + pix_fmt->field = V4L2_FIELD_NONE; + pix_fmt->colorspace = frm->colorspace; return 0; } -static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f) +static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) { + struct v4l2_pix_format_mplane *pix_fmt = &f->fmt.pix_mp; struct rga_fmt *fmt; - fmt = rga_fmt_find(f); - if (!fmt) { + fmt = rga_fmt_find(pix_fmt->pixelformat); + if (!fmt) fmt = &formats[0]; - f->fmt.pix.pixelformat = fmt->fourcc; - } - f->fmt.pix.field = V4L2_FIELD_NONE; + pix_fmt->width = clamp(pix_fmt->width, + (u32)MIN_WIDTH, (u32)MAX_WIDTH); + pix_fmt->height = clamp(pix_fmt->height, + (u32)MIN_HEIGHT, (u32)MAX_HEIGHT); - if (f->fmt.pix.width > MAX_WIDTH) - f->fmt.pix.width = MAX_WIDTH; - if (f->fmt.pix.height > MAX_HEIGHT) - f->fmt.pix.height = MAX_HEIGHT; - - if (f->fmt.pix.width < MIN_WIDTH) - f->fmt.pix.width = MIN_WIDTH; - if (f->fmt.pix.height < MIN_HEIGHT) - f->fmt.pix.height = MIN_HEIGHT; - - if (fmt->hw_format >= RGA_COLOR_FMT_YUV422SP) - f->fmt.pix.bytesperline = f->fmt.pix.width; - else - f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; - - f->fmt.pix.sizeimage = - f->fmt.pix.height * (f->fmt.pix.width * fmt->depth) >> 3; + v4l2_fill_pixfmt_mp(pix_fmt, fmt->fourcc, pix_fmt->width, pix_fmt->height); + pix_fmt->field = V4L2_FIELD_NONE; return 0; } -static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f) +static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) { - struct rga_ctx *ctx = prv; + struct v4l2_pix_format_mplane *pix_fmt = &f->fmt.pix_mp; + struct rga_ctx *ctx = file_to_rga_ctx(file); struct rockchip_rga *rga = ctx->rga; struct vb2_queue *vq; struct rga_frame *frm; - struct rga_fmt *fmt; int ret = 0; + int i; /* Adjust all values accordingly to the hardware capabilities * and chosen format. */ - ret = vidioc_try_fmt(file, prv, f); + ret = vidioc_try_fmt(file, priv, f); if (ret) return ret; vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); @@ -547,15 +521,14 @@ static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f) frm = rga_get_frame(ctx, f->type); if (IS_ERR(frm)) return PTR_ERR(frm); - fmt = rga_fmt_find(f); - if (!fmt) - return -EINVAL; - frm->width = f->fmt.pix.width; - frm->height = f->fmt.pix.height; - frm->size = f->fmt.pix.sizeimage; - frm->fmt = fmt; - frm->stride = f->fmt.pix.bytesperline; - frm->colorspace = f->fmt.pix.colorspace; + frm->width = pix_fmt->width; + frm->height = pix_fmt->height; + frm->size = 0; + for (i = 0; i < pix_fmt->num_planes; i++) + frm->size += pix_fmt->plane_fmt[i].sizeimage; + frm->fmt = rga_fmt_find(pix_fmt->pixelformat); + frm->stride = pix_fmt->plane_fmt[0].bytesperline; + frm->colorspace = pix_fmt->colorspace; /* Reset crop settings */ frm->crop.left = 0; @@ -563,13 +536,28 @@ static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f) frm->crop.width = frm->width; frm->crop.height = frm->height; + frm->pix = *pix_fmt; + + v4l2_dbg(debug, 1, &rga->v4l2_dev, + "[%s] fmt - %p4cc %dx%d (stride %d, sizeimage %d)\n", + V4L2_TYPE_IS_OUTPUT(f->type) ? "OUTPUT" : "CAPTURE", + &frm->fmt->fourcc, frm->width, frm->height, + frm->stride, frm->size); + + for (i = 0; i < pix_fmt->num_planes; i++) { + v4l2_dbg(debug, 1, &rga->v4l2_dev, + "plane[%d]: size %d, bytesperline %d\n", + i, pix_fmt->plane_fmt[i].sizeimage, + pix_fmt->plane_fmt[i].bytesperline); + } + return 0; } -static int vidioc_g_selection(struct file *file, void *prv, +static int vidioc_g_selection(struct file *file, void *priv, struct v4l2_selection *s) { - struct rga_ctx *ctx = prv; + struct rga_ctx *ctx = file_to_rga_ctx(file); struct rga_frame *f; bool use_frame = false; @@ -580,21 +568,21 @@ static int vidioc_g_selection(struct file *file, void *prv, switch (s->target) { case V4L2_SEL_TGT_COMPOSE_DEFAULT: case V4L2_SEL_TGT_COMPOSE_BOUNDS: - if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (!V4L2_TYPE_IS_CAPTURE(s->type)) return -EINVAL; break; case V4L2_SEL_TGT_CROP_DEFAULT: case V4L2_SEL_TGT_CROP_BOUNDS: - if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) + if (!V4L2_TYPE_IS_OUTPUT(s->type)) return -EINVAL; break; case V4L2_SEL_TGT_COMPOSE: - if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (!V4L2_TYPE_IS_CAPTURE(s->type)) return -EINVAL; use_frame = true; break; case V4L2_SEL_TGT_CROP: - if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) + if (!V4L2_TYPE_IS_OUTPUT(s->type)) return -EINVAL; use_frame = true; break; @@ -614,10 +602,10 @@ static int vidioc_g_selection(struct file *file, void *prv, return 0; } -static int vidioc_s_selection(struct file *file, void *prv, +static int vidioc_s_selection(struct file *file, void *priv, struct v4l2_selection *s) { - struct rga_ctx *ctx = prv; + struct rga_ctx *ctx = file_to_rga_ctx(file); struct rockchip_rga *rga = ctx->rga; struct rga_frame *f; int ret = 0; @@ -632,7 +620,7 @@ static int vidioc_s_selection(struct file *file, void *prv, * COMPOSE target is only valid for capture buffer type, return * error for output buffer type */ - if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (!V4L2_TYPE_IS_CAPTURE(s->type)) return -EINVAL; break; case V4L2_SEL_TGT_CROP: @@ -640,7 +628,7 @@ static int vidioc_s_selection(struct file *file, void *prv, * CROP target is only valid for output buffer type, return * error for capture buffer type */ - if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) + if (!V4L2_TYPE_IS_OUTPUT(s->type)) return -EINVAL; break; /* @@ -673,14 +661,14 @@ static const struct v4l2_ioctl_ops rga_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt, - .vidioc_g_fmt_vid_cap = vidioc_g_fmt, - .vidioc_try_fmt_vid_cap = vidioc_try_fmt, - .vidioc_s_fmt_vid_cap = vidioc_s_fmt, + .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt, + .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt, + .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt, .vidioc_enum_fmt_vid_out = vidioc_enum_fmt, - .vidioc_g_fmt_vid_out = vidioc_g_fmt, - .vidioc_try_fmt_vid_out = vidioc_try_fmt, - .vidioc_s_fmt_vid_out = vidioc_s_fmt, + .vidioc_g_fmt_vid_out_mplane = vidioc_g_fmt, + .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt, + .vidioc_s_fmt_vid_out_mplane = vidioc_s_fmt, .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, @@ -707,7 +695,7 @@ static const struct video_device rga_videodev = { .minor = -1, .release = video_device_release, .vfl_dir = VFL_DIR_M2M, - .device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING, + .device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING, }; static int rga_enable_clocks(struct rockchip_rga *rga) @@ -734,10 +722,10 @@ static int rga_enable_clocks(struct rockchip_rga *rga) return 0; -err_disable_sclk: - clk_disable_unprepare(rga->sclk); err_disable_aclk: clk_disable_unprepare(rga->aclk); +err_disable_sclk: + clk_disable_unprepare(rga->sclk); return ret; } @@ -808,7 +796,6 @@ static int rga_probe(struct platform_device *pdev) { struct rockchip_rga *rga; struct video_device *vfd; - struct resource *res; int ret = 0; int irq; @@ -825,13 +812,11 @@ static int rga_probe(struct platform_device *pdev) ret = rga_parse_dt(rga); if (ret) - dev_err(&pdev->dev, "Unable to parse OF data\n"); + return dev_err_probe(&pdev->dev, ret, "Unable to parse OF data\n"); pm_runtime_enable(rga->dev); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - rga->regs = devm_ioremap_resource(rga->dev, res); + rga->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(rga->regs)) { ret = PTR_ERR(rga->regs); goto err_put_clk; @@ -839,7 +824,6 @@ static int rga_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) { - dev_err(rga->dev, "failed to get irq\n"); ret = irq; goto err_put_clk; } @@ -851,6 +835,12 @@ static int rga_probe(struct platform_device *pdev) goto err_put_clk; } + ret = dma_set_mask_and_coherent(rga->dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(rga->dev, "32-bit DMA not supported"); + goto err_put_clk; + } + ret = v4l2_device_register(&pdev->dev, &rga->v4l2_dev); if (ret) goto err_put_clk; @@ -872,10 +862,12 @@ static int rga_probe(struct platform_device *pdev) if (IS_ERR(rga->m2m_dev)) { v4l2_err(&rga->v4l2_dev, "Failed to init mem2mem device\n"); ret = PTR_ERR(rga->m2m_dev); - goto unreg_video_dev; + goto rel_vdev; } - pm_runtime_get_sync(rga->dev); + ret = pm_runtime_resume_and_get(rga->dev); + if (ret < 0) + goto rel_m2m; rga->version.major = (rga_read(rga, RGA_VERSION_INFO) >> 24) & 0xFF; rga->version.minor = (rga_read(rga, RGA_VERSION_INFO) >> 20) & 0x0F; @@ -889,19 +881,18 @@ static int rga_probe(struct platform_device *pdev) rga->cmdbuf_virt = dma_alloc_attrs(rga->dev, RGA_CMDBUF_SIZE, &rga->cmdbuf_phy, GFP_KERNEL, DMA_ATTR_WRITE_COMBINE); - - rga->src_mmu_pages = - (unsigned int *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3); - rga->dst_mmu_pages = - (unsigned int *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 3); + if (!rga->cmdbuf_virt) { + ret = -ENOMEM; + goto rel_m2m; + } def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3; def_frame.size = def_frame.stride * def_frame.height; - ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); + ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1); if (ret) { v4l2_err(&rga->v4l2_dev, "Failed to register video device\n"); - goto rel_vdev; + goto free_dma; } v4l2_info(&rga->v4l2_dev, "Registered %s as /dev/%s\n", @@ -909,10 +900,13 @@ static int rga_probe(struct platform_device *pdev) return 0; +free_dma: + dma_free_attrs(rga->dev, RGA_CMDBUF_SIZE, rga->cmdbuf_virt, + rga->cmdbuf_phy, DMA_ATTR_WRITE_COMBINE); +rel_m2m: + v4l2_m2m_release(rga->m2m_dev); rel_vdev: video_device_release(vfd); -unreg_video_dev: - video_unregister_device(rga->vfd); unreg_v4l2_dev: v4l2_device_unregister(&rga->v4l2_dev); err_put_clk: @@ -921,16 +915,13 @@ err_put_clk: return ret; } -static int rga_remove(struct platform_device *pdev) +static void rga_remove(struct platform_device *pdev) { struct rockchip_rga *rga = platform_get_drvdata(pdev); dma_free_attrs(rga->dev, RGA_CMDBUF_SIZE, rga->cmdbuf_virt, rga->cmdbuf_phy, DMA_ATTR_WRITE_COMBINE); - free_pages((unsigned long)rga->src_mmu_pages, 3); - free_pages((unsigned long)rga->dst_mmu_pages, 3); - v4l2_info(&rga->v4l2_dev, "Removing\n"); v4l2_m2m_release(rga->m2m_dev); @@ -938,8 +929,6 @@ static int rga_remove(struct platform_device *pdev) v4l2_device_unregister(&rga->v4l2_dev); pm_runtime_disable(rga->dev); - - return 0; } static int __maybe_unused rga_runtime_suspend(struct device *dev) |
